/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hadoop.registry.server.dns;

import org.apache.commons.net.util.Base64;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.registry.client.api.RegistryConstants;
import org.apache.hadoop.registry.client.binding.RegistryUtils;
import org.apache.hadoop.registry.client.types.ServiceRecord;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.xbill.DNS.AAAARecord;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.CNAMERecord;
import org.xbill.DNS.DClass;
import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.Flags;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.OPTRecord;
import org.xbill.DNS.PTRRecord;
import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Rcode;
import org.xbill.DNS.Record;
import org.xbill.DNS.SRVRecord;
import org.xbill.DNS.Section;
import org.xbill.DNS.Type;

import java.io.IOException;
import java.math.BigInteger;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.RSAPrivateKeySpec;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import static org.apache.hadoop.registry.client.api.RegistryConstants.*;

/**
 *
 */
public class TestRegistryDNS extends Assert {

  private RegistryDNS registryDNS;
  private RegistryUtils.ServiceRecordMarshal marshal;

  private static final String APPLICATION_RECORD = "{\n"
      + "  \"type\" : \"JSONServiceRecord\",\n"
      + "  \"description\" : \"Slider Application Master\",\n"
      + "  \"external\" : [ {\n"
      + "    \"api\" : \"classpath:org.apache.hadoop.yarn.service.appmaster.ipc"
      + "\",\n"
      + "    \"addressType\" : \"host/port\",\n"
      + "    \"protocolType\" : \"hadoop/IPC\",\n"
      + "    \"addresses\" : [ {\n"
      + "      \"host\" : \"192.168.1.5\",\n"
      + "      \"port\" : \"1026\"\n"
      + "    } ]\n"
      + "  }, {\n"
      + "    \"api\" : \"http://\",\n"
      + "    \"addressType\" : \"uri\",\n"
      + "    \"protocolType\" : \"webui\",\n"
      + "    \"addresses\" : [ {\n"
      + "      \"uri\" : \"http://192.168.1.5:1027\"\n"
      + "    } ]\n"
      + "  }, {\n"
      + "    \"api\" : \"classpath:org.apache.hadoop.yarn.service.management\""
      + ",\n"
      + "    \"addressType\" : \"uri\",\n"
      + "    \"protocolType\" : \"REST\",\n"
      + "    \"addresses\" : [ {\n"
      + "      \"uri\" : \"http://192.168.1.5:1027/ws/v1/slider/mgmt\"\n"
      + "    } ]\n"
      + "  } ],\n"
      + "  \"internal\" : [ {\n"
      + "    \"api\" : \"classpath:org.apache.hadoop.yarn.service.agents.secure"
      + "\",\n"
      + "    \"addressType\" : \"uri\",\n"
      + "    \"protocolType\" : \"REST\",\n"
      + "    \"addresses\" : [ {\n"
      + "      \"uri\" : \"https://192.168.1.5:47700/ws/v1/slider/agents\"\n"
      + "    } ]\n"
      + "  }, {\n"
      + "    \"api\" : \"classpath:org.apache.hadoop.yarn.service.agents.oneway"
      + "\",\n"
      + "    \"addressType\" : \"uri\",\n"
      + "    \"protocolType\" : \"REST\",\n"
      + "    \"addresses\" : [ {\n"
      + "      \"uri\" : \"https://192.168.1.5:35531/ws/v1/slider/agents\"\n"
      + "    } ]\n"
      + "  } ],\n"
      + "  \"yarn:id\" : \"application_1451931954322_0016\",\n"
      + "  \"yarn:persistence\" : \"application\"\n"
      + "}\n";
  static final String CONTAINER_RECORD = "{\n"
      + "  \"type\" : \"JSONServiceRecord\",\n"
      + "  \"description\" : \"httpd-1\",\n"
      + "  \"external\" : [ ],\n"
      + "  \"internal\" : [ ],\n"
      + "  \"yarn:id\" : \"container_e50_1451931954322_0016_01_000002\",\n"
      + "  \"yarn:persistence\" : \"container\",\n"
      + "  \"yarn:ip\" : \"172.17.0.19\",\n"
      + "  \"yarn:hostname\" : \"host1\",\n"
      + "  \"yarn:component\" : \"httpd\"\n"
      + "}\n";

  static final String CONTAINER_RECORD2 = "{\n"
      + "  \"type\" : \"JSONServiceRecord\",\n"
      + "  \"description\" : \"httpd-2\",\n"
      + "  \"external\" : [ ],\n"
      + "  \"internal\" : [ ],\n"
      + "  \"yarn:id\" : \"container_e50_1451931954322_0016_01_000003\",\n"
      + "  \"yarn:persistence\" : \"container\",\n"
      + "  \"yarn:ip\" : \"172.17.0.20\",\n"
      + "  \"yarn:hostname\" : \"host2\",\n"
      + "  \"yarn:component\" : \"httpd\"\n"
      + "}\n";

  private static final String CONTAINER_RECORD_NO_IP = "{\n"
      + "  \"type\" : \"JSONServiceRecord\",\n"
      + "  \"description\" : \"httpd-1\",\n"
      + "  \"external\" : [ ],\n"
      + "  \"internal\" : [ ],\n"
      + "  \"yarn:id\" : \"container_e50_1451931954322_0016_01_000002\",\n"
      + "  \"yarn:persistence\" : \"container\",\n"
      + "  \"yarn:component\" : \"httpd\"\n"
      + "}\n";

  private static final String CONTAINER_RECORD_YARN_PERSISTANCE_ABSENT = "{\n"
      + "  \"type\" : \"JSONServiceRecord\",\n"
      + "  \"description\" : \"httpd-1\",\n"
      + "  \"external\" : [ ],\n"
      + "  \"internal\" : [ ],\n"
      + "  \"yarn:id\" : \"container_e50_1451931954322_0016_01_000003\",\n"
      + "  \"yarn:ip\" : \"172.17.0.19\",\n"
      + "  \"yarn:hostname\" : \"0a134d6329bb\",\n"
      + "  \"yarn:component\" : \"httpd\""
      + "}\n";

  @Before
  public void initialize() throws Exception {
    setRegistryDNS(new RegistryDNS("TestRegistry"));
    Configuration conf = createConfiguration();

    getRegistryDNS().setDomainName(conf);
    getRegistryDNS().initializeZones(conf);

    setMarshal(new RegistryUtils.ServiceRecordMarshal());
  }

  protected Configuration createConfiguration() {
    Configuration conf = new Configuration();
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "dev.test");
    conf.set(RegistryConstants.KEY_DNS_ZONE_SUBNET, "172.17.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);
    return conf;
  }

  protected boolean isSecure() {
    return false;
  }

  @After
  public void closeRegistry() throws Exception {
    getRegistryDNS().stopExecutor();
  }

  @Test
  public void testAppRegistration() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        APPLICATION_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/", record);

    // start assessing whether correct records are available
    Record[] recs = assertDNSQuery("test1.root.dev.test.");
    assertEquals("wrong result", "192.168.1.5",
        ((ARecord) recs[0]).getAddress().getHostAddress());

    recs = assertDNSQuery("management-api.test1.root.dev.test.", 2);
    assertEquals("wrong target name", "test1.root.dev.test.",
        ((CNAMERecord) recs[0]).getTarget().toString());
    assertTrue("not an ARecord", recs[isSecure() ? 2 : 1] instanceof ARecord);

    recs = assertDNSQuery("appmaster-ipc-api.test1.root.dev.test.",
        Type.SRV, 1);
    assertTrue("not an SRV record", recs[0] instanceof SRVRecord);
    assertEquals("wrong port", 1026, ((SRVRecord) recs[0]).getPort());

    recs = assertDNSQuery("appmaster-ipc-api.test1.root.dev.test.", 2);
    assertEquals("wrong target name", "test1.root.dev.test.",
        ((CNAMERecord) recs[0]).getTarget().toString());
    assertTrue("not an ARecord", recs[isSecure() ? 2 : 1] instanceof ARecord);

    recs = assertDNSQuery("http-api.test1.root.dev.test.", 2);
    assertEquals("wrong target name", "test1.root.dev.test.",
        ((CNAMERecord) recs[0]).getTarget().toString());
    assertTrue("not an ARecord", recs[isSecure() ? 2 : 1] instanceof ARecord);

    recs = assertDNSQuery("http-api.test1.root.dev.test.", Type.SRV,
        1);
    assertTrue("not an SRV record", recs[0] instanceof SRVRecord);
    assertEquals("wrong port", 1027, ((SRVRecord) recs[0]).getPort());

    assertDNSQuery("test1.root.dev.test.", Type.TXT, 3);
    assertDNSQuery("appmaster-ipc-api.test1.root.dev.test.", Type.TXT, 1);
    assertDNSQuery("http-api.test1.root.dev.test.", Type.TXT, 1);
    assertDNSQuery("management-api.test1.root.dev.test.", Type.TXT, 1);
  }

  @Test
  public void testContainerRegistration() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs =
        assertDNSQuery("ctr-e50-1451931954322-0016-01-000002.dev.test.");
    assertEquals("wrong result", "172.17.0.19",
        ((ARecord) recs[0]).getAddress().getHostAddress());

    recs = assertDNSQuery("httpd-1.test1.root.dev.test.", 1);
    assertTrue("not an ARecord", recs[0] instanceof ARecord);
  }

  @Test
  public void testContainerRegistrationPersistanceAbsent() throws Exception {
    ServiceRecord record = marshal.fromBytes("somepath",
        CONTAINER_RECORD_YARN_PERSISTANCE_ABSENT.getBytes());
    registryDNS.register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000003",
         record);

    Name name =
        Name.fromString("ctr-e50-1451931954322-0016-01-000002.dev.test.");
    Record question = Record.newRecord(name, Type.A, DClass.IN);
    Message query = Message.newQuery(question);
    byte[] responseBytes = registryDNS.generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("Excepting NXDOMAIN as Record must not have regsisterd wrong",
        Rcode.NXDOMAIN, response.getRcode());
  }

  @Test
  public void testRecordTTL() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs = assertDNSQuery(
        "ctr-e50-1451931954322-0016-01-000002.dev.test.");
    assertEquals("wrong result", "172.17.0.19",
        ((ARecord) recs[0]).getAddress().getHostAddress());
    assertEquals("wrong ttl", 30L, recs[0].getTTL());

    recs = assertDNSQuery("httpd-1.test1.root.dev.test.", 1);
    assertTrue("not an ARecord", recs[0] instanceof ARecord);

    assertEquals("wrong ttl", 30L, recs[0].getTTL());
  }

  @Test
  public void testReverseLookup() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs = assertDNSQuery("19.0.17.172.in-addr.arpa.", Type.PTR, 1);
    assertEquals("wrong result",
        "httpd-1.test1.root.dev.test.",
        ((PTRRecord) recs[0]).getTarget().toString());
  }

  @Test
  public void testReverseLookupInLargeNetwork() throws Exception {
    setRegistryDNS(new RegistryDNS("TestRegistry"));
    Configuration conf = createConfiguration();
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "dev.test");
    conf.set(KEY_DNS_ZONE_SUBNET, "172.17.0.0");
    conf.set(KEY_DNS_ZONE_MASK, "255.255.224.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);

    getRegistryDNS().setDomainName(conf);
    getRegistryDNS().initializeZones(conf);

    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs = assertDNSQuery("19.0.17.172.in-addr.arpa.", Type.PTR, 1);
    assertEquals("wrong result",
        "httpd-1.test1.root.dev.test.",
        ((PTRRecord) recs[0]).getTarget().toString());
  }

  @Test
  public void testMissingReverseLookup() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Name name = Name.fromString("19.1.17.172.in-addr.arpa.");
    Record question = Record.newRecord(name, Type.PTR, DClass.IN);
    Message query = Message.newQuery(question);
    OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null);
    query.addRecord(optRecord, Section.ADDITIONAL);
    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("Missing record should be: ", Rcode.NXDOMAIN,
        response.getRcode());
  }

  @Test
  public void testNoContainerIP() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD_NO_IP.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Name name =
        Name.fromString("ctr-e50-1451931954322-0016-01-000002.dev.test.");
    Record question = Record.newRecord(name, Type.A, DClass.IN);
    Message query = Message.newQuery(question);

    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("wrong status", Rcode.NXDOMAIN, response.getRcode());
  }

  private Record[] assertDNSQuery(String lookup) throws IOException {
    return assertDNSQuery(lookup, Type.A, 1);
  }

  private Record[] assertDNSQuery(String lookup, int numRecs)
      throws IOException {
    return assertDNSQuery(lookup, Type.A, numRecs);
  }

  Record[] assertDNSQuery(String lookup, int type, int numRecs)
      throws IOException {
    Name name = Name.fromString(lookup);
    Record question = Record.newRecord(name, type, DClass.IN);
    Message query = Message.newQuery(question);
    OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null);
    query.addRecord(optRecord, Section.ADDITIONAL);
    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("not successful", Rcode.NOERROR, response.getRcode());
    assertNotNull("Null response", response);
    assertEquals("Questions do not match", query.getQuestion(),
        response.getQuestion());
    Record[] recs = response.getSectionArray(Section.ANSWER);
    assertEquals("wrong number of answer records",
        isSecure() ? numRecs * 2 : numRecs, recs.length);
    if (isSecure()) {
      boolean signed = false;
      for (Record record : recs) {
        signed = record.getType() == Type.RRSIG;
        if (signed) {
          break;
        }
      }
      assertTrue("No signatures found", signed);
    }
    return recs;
  }

  Record[] assertDNSQueryNotNull(String lookup, int type, int answerCount)
      throws IOException {
    Name name = Name.fromString(lookup);
    Record question = Record.newRecord(name, type, DClass.IN);
    Message query = Message.newQuery(question);
    OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null);
    query.addRecord(optRecord, Section.ADDITIONAL);
    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("not successful", Rcode.NOERROR, response.getRcode());
    assertNotNull("Null response", response);
    assertEquals("Questions do not match", query.getQuestion(),
        response.getQuestion());
    Record[] recs = response.getSectionArray(Section.ANSWER);
    assertEquals(answerCount, recs.length);
    assertEquals(recs[0].getType(), type);
    return recs;
  }

  @Test
  public void testDNSKEYRecord() throws Exception {
    String publicK =
        "AwEAAe1Jev0Az1khlQCvf0nud1/CNHQwwPEu8BNchZthdDxKPVn29yrD "
            + "CHoAWjwiGsOSw3SzIPrawSbHzyJsjn0oLBhGrH6QedFGnydoxjNsw3m/ "
            + "SCmOjR/a7LGBAMDFKqFioi4gOyuN66svBeY+/5uw72+0ei9AQ20gqf6q "
            + "l9Ozs5bV";
    //    byte[] publicBytes = Base64.decodeBase64(publicK);
    //    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
    //    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    //    PublicKey pubKey = keyFactory.generatePublic(keySpec);
    DNSKEYRecord dnskeyRecord =
        new DNSKEYRecord(Name.fromString("dev.test."), DClass.IN, 0,
            DNSKEYRecord.Flags.ZONE_KEY,
            DNSKEYRecord.Protocol.DNSSEC,
            DNSSEC.Algorithm.RSASHA256,
            Base64.decodeBase64(publicK.getBytes()));
    assertNotNull(dnskeyRecord);
    RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(new BigInteger(1,
        Base64.decodeBase64(
            "7Ul6/QDPWSGVAK9/Se53X8I0dDDA8S7wE1yFm2F0PEo9Wfb3KsMIegBaPCIaw5LDd"
                + "LMg+trBJsfPImyOfSgsGEasfpB50UafJ2jGM2zDeb9IKY6NH9rssYEAwMUq"
                + "oWKiLiA7K43rqy8F5j7/m7Dvb7R6L0BDbSCp/qqX07OzltU=")),
        new BigInteger(1, Base64.decodeBase64(
            "MgbQ6DBYhskeufNGGdct0cGG/4wb0X183ggenwCv2dopDyOTPq+5xMb4Pz9Ndzgk/"
                + "yCY7mpaWIu9rttGOzrR+LBRR30VobPpMK1bMnzu2C0x08oYAguVwZB79DLC"
                + "705qmZpiaaFB+LnhG7VtpPiOBm3UzZxdrBfeq/qaKrXid60=")));
    KeyFactory factory = KeyFactory.getInstance("RSA");
    PrivateKey priv = factory.generatePrivate(privateSpec);

    ARecord aRecord = new ARecord(Name.fromString("some.test."), DClass.IN, 0,
        InetAddress.getByName("192.168.0.1"));
    Calendar cal = Calendar.getInstance();
    Date inception = cal.getTime();
    cal.add(Calendar.YEAR, 1);
    Date expiration = cal.getTime();
    RRset rrset = new RRset(aRecord);
    RRSIGRecord rrsigRecord = DNSSEC.sign(rrset,
        dnskeyRecord,
        priv,
        inception,
        expiration);
    DNSSEC.verify(rrset, rrsigRecord, dnskeyRecord);

  }

  @Test
  public void testIpv4toIpv6() throws Exception {
    InetAddress address =
        BaseServiceRecordProcessor
            .getIpv6Address(InetAddress.getByName("172.17.0.19"));
    assertTrue("not an ipv6 address", address instanceof Inet6Address);
    assertEquals("wrong IP", "172.17.0.19",
        InetAddress.getByAddress(address.getAddress()).getHostAddress());
  }

  @Test
  public void testAAAALookup() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs = assertDNSQuery(
        "ctr-e50-1451931954322-0016-01-000002.dev.test.", Type.AAAA, 1);
    assertEquals("wrong result", "172.17.0.19",
        ((AAAARecord) recs[0]).getAddress().getHostAddress());

    recs = assertDNSQuery("httpd-1.test1.root.dev.test.", Type.AAAA, 1);
    assertTrue("not an ARecord", recs[0] instanceof AAAARecord);
  }

  @Test
  public void testNegativeLookup() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Name name = Name.fromString("missing.dev.test.");
    Record question = Record.newRecord(name, Type.A, DClass.IN);
    Message query = Message.newQuery(question);

    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    assertEquals("not successful", Rcode.NXDOMAIN, response.getRcode());
    assertNotNull("Null response", response);
    assertEquals("Questions do not match", query.getQuestion(),
        response.getQuestion());
    Record[] sectionArray = response.getSectionArray(Section.AUTHORITY);
    assertEquals("Wrong number of recs in AUTHORITY", isSecure() ? 2 : 1,
        sectionArray.length);
    boolean soaFound = false;
    for (Record rec : sectionArray) {
      soaFound = rec.getType() == Type.SOA;
      if (soaFound) {
        break;
      }
    }
    assertTrue("wrong record type",
        soaFound);

  }

  @Test
  public void testReadMasterFile() throws Exception {
    setRegistryDNS(new RegistryDNS("TestRegistry"));
    Configuration conf = new Configuration();
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "dev.test");
    conf.set(RegistryConstants.KEY_DNS_ZONE_SUBNET, "172.17.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);
    conf.set(RegistryConstants.KEY_DNS_ZONES_DIR,
        getClass().getResource("/").getFile());
    if (isSecure()) {
      conf.setBoolean(RegistryConstants.KEY_DNSSEC_ENABLED, true);
      conf.set(RegistryConstants.KEY_DNSSEC_PUBLIC_KEY,
          "AwEAAe1Jev0Az1khlQCvf0nud1/CNHQwwPEu8BNchZthdDxKPVn29yrD "
              + "CHoAWjwiGsOSw3SzIPrawSbHzyJsjn0oLBhGrH6QedFGnydoxjNsw3m/ "
              + "SCmOjR/a7LGBAMDFKqFioi4gOyuN66svBeY+/5uw72+0ei9AQ20gqf6q "
              + "l9Ozs5bV");
      conf.set(RegistryConstants.KEY_DNSSEC_PRIVATE_KEY_FILE,
          getClass().getResource("/test.private").getFile());
    }

    getRegistryDNS().setDomainName(conf);
    getRegistryDNS().initializeZones(conf);

    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);

    // start assessing whether correct records are available
    Record[] recs =
        assertDNSQuery("ctr-e50-1451931954322-0016-01-000002.dev.test.");
    assertEquals("wrong result", "172.17.0.19",
        ((ARecord) recs[0]).getAddress().getHostAddress());

    recs = assertDNSQuery("httpd-1.test1.root.dev.test.", 1);
    assertTrue("not an ARecord", recs[0] instanceof ARecord);

    // lookup dyanmic reverse records
    recs = assertDNSQuery("19.0.17.172.in-addr.arpa.", Type.PTR, 1);
    assertEquals("wrong result",
        "httpd-1.test1.root.dev.test.",
        ((PTRRecord) recs[0]).getTarget().toString());

    // now lookup static reverse records
    Name name = Name.fromString("5.0.17.172.in-addr.arpa.");
    Record question = Record.newRecord(name, Type.PTR, DClass.IN);
    Message query = Message.newQuery(question);
    OPTRecord optRecord = new OPTRecord(4096, 0, 0, Flags.DO, null);
    query.addRecord(optRecord, Section.ADDITIONAL);
    byte[] responseBytes = getRegistryDNS().generateReply(query, null);
    Message response = new Message(responseBytes);
    recs = response.getSectionArray(Section.ANSWER);
    assertEquals("wrong result", "cn005.dev.test.",
        ((PTRRecord) recs[0]).getTarget().toString());
  }

  @Test
  public void testReverseZoneNames() throws Exception {
    Configuration conf = new Configuration();
    conf.set(KEY_DNS_ZONE_SUBNET, "172.26.32.0");
    conf.set(KEY_DNS_ZONE_MASK, "255.255.224.0");

    Name name = getRegistryDNS().getReverseZoneName(conf);
    assertEquals("wrong name", "26.172.in-addr.arpa.", name.toString());
  }

  @Test
  public void testSplitReverseZoneNames() throws Exception {
    Configuration conf = new Configuration();
    registryDNS = new RegistryDNS("TestRegistry");
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "example.com");
    conf.set(KEY_DNS_SPLIT_REVERSE_ZONE, "true");
    conf.set(KEY_DNS_SPLIT_REVERSE_ZONE_RANGE, "256");
    conf.set(KEY_DNS_ZONE_SUBNET, "172.26.32.0");
    conf.set(KEY_DNS_ZONE_MASK, "255.255.224.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);
    conf.set(RegistryConstants.KEY_DNS_ZONES_DIR,
        getClass().getResource("/").getFile());
    if (isSecure()) {
      conf.setBoolean(RegistryConstants.KEY_DNSSEC_ENABLED, true);
      conf.set(RegistryConstants.KEY_DNSSEC_PUBLIC_KEY,
          "AwEAAe1Jev0Az1khlQCvf0nud1/CNHQwwPEu8BNchZthdDxKPVn29yrD "
              + "CHoAWjwiGsOSw3SzIPrawSbHzyJsjn0oLBhGrH6QedFGnydoxjNsw3m/ "
              + "SCmOjR/a7LGBAMDFKqFioi4gOyuN66svBeY+/5uw72+0ei9AQ20gqf6q "
              + "l9Ozs5bV");
      conf.set(RegistryConstants.KEY_DNSSEC_PRIVATE_KEY_FILE,
          getClass().getResource("/test.private").getFile());
    }
    registryDNS.setDomainName(conf);
    registryDNS.setDNSSECEnabled(conf);
    registryDNS.addSplitReverseZones(conf, 4);
    assertEquals(4, registryDNS.getZoneCount());
  }

  @Test
  public void testExampleDotCom() throws Exception {
    Name name = Name.fromString("example.com.");
    Record[] records = getRegistryDNS().getRecords(name, Type.SOA);
    assertNotNull("example.com exists:", records);
  }

  @Test
  public void testExternalCNAMERecord() throws Exception {
    setRegistryDNS(new RegistryDNS("TestRegistry"));
    Configuration conf = new Configuration();
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "dev.test");
    conf.set(RegistryConstants.KEY_DNS_ZONE_SUBNET, "172.17.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);
    conf.set(RegistryConstants.KEY_DNS_ZONES_DIR,
        getClass().getResource("/").getFile());
    getRegistryDNS().setDomainName(conf);
    getRegistryDNS().initializeZones(conf);

    // start assessing whether correct records are available
    Record[] recs =
        assertDNSQueryNotNull("mail.yahoo.com.", Type.CNAME, 1);
  }

  @Test
  public void testRootLookup() throws Exception {
    setRegistryDNS(new RegistryDNS("TestRegistry"));
    Configuration conf = new Configuration();
    conf.set(RegistryConstants.KEY_DNS_DOMAIN, "dev.test");
    conf.set(RegistryConstants.KEY_DNS_ZONE_SUBNET, "172.17.0");
    conf.setTimeDuration(RegistryConstants.KEY_DNS_TTL, 30L, TimeUnit.SECONDS);
    conf.set(RegistryConstants.KEY_DNS_ZONES_DIR,
        getClass().getResource("/").getFile());
    getRegistryDNS().setDomainName(conf);
    getRegistryDNS().initializeZones(conf);

    // start assessing whether correct records are available
    Record[] recs =
        assertDNSQueryNotNull(".", Type.NS, 13);
  }

  @Test
  public void testMultiARecord() throws Exception {
    ServiceRecord record = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD.getBytes());
    ServiceRecord record2 = getMarshal().fromBytes("somepath",
        CONTAINER_RECORD2.getBytes());
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000002",
        record);
    getRegistryDNS().register(
        "/registry/users/root/services/org-apache-slider/test1/components/"
            + "ctr-e50-1451931954322-0016-01-000003",
        record2);

    // start assessing whether correct records are available
    Record[] recs =
        assertDNSQuery("httpd.test1.root.dev.test.", 2);
    assertTrue("not an ARecord", recs[0] instanceof ARecord);
    assertTrue("not an ARecord", recs[1] instanceof ARecord);
  }

  @Test(timeout=5000)
  public void testUpstreamFault() throws Exception {
    Name name = Name.fromString("19.0.17.172.in-addr.arpa.");
    Record[] recs = getRegistryDNS().getRecords(name, Type.CNAME);
    assertNull("Record is not null", recs);
  }

  public RegistryDNS getRegistryDNS() {
    return registryDNS;
  }

  public void setRegistryDNS(
      RegistryDNS registryDNS) {
    this.registryDNS = registryDNS;
  }

  public RegistryUtils.ServiceRecordMarshal getMarshal() {
    return marshal;
  }

  public void setMarshal(
      RegistryUtils.ServiceRecordMarshal marshal) {
    this.marshal = marshal;
  }
}
