http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/ZookeeperConfigOptions.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/ZookeeperConfigOptions.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/ZookeeperConfigOptions.java new file mode 100644 index 0000000..edcf085 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/ZookeeperConfigOptions.java @@ -0,0 +1,118 @@ +/* + * 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.client.impl.zk; + +import org.apache.zookeeper.client.ZooKeeperSaslClient; +import org.apache.zookeeper.server.ZooKeeperSaslServer; + +/** + * Configuration options which are internal to Zookeeper, + * as well as some other ZK constants + * <p> + * Zookeeper options are passed via system properties prior to the ZK + * Methods/classes being invoked. This implies that: + * <ol> + * <li>There can only be one instance of a ZK client or service class + * in a single JVM âelse their configuration options will conflict.</li> + * <li>It is safest to set these properties immediately before + * invoking ZK operations.</li> + * </ol> + * + */ +public interface ZookeeperConfigOptions { + /** + * Enable SASL secure clients: {@value}. + * This is usually set to true, with ZK set to fall back to + * non-SASL authentication if the SASL auth fails + * by the property + * {@link #PROP_ZK_SERVER_MAINTAIN_CONNECTION_DESPITE_SASL_FAILURE}. + * <p> + * As a result, clients will default to attempting SASL-authentication, + * but revert to classic authentication/anonymous access on failure. + */ + String PROP_ZK_ENABLE_SASL_CLIENT = + "zookeeper.sasl.client"; + + /** + * Default flag for the ZK client: {@value}. + */ + String DEFAULT_ZK_ENABLE_SASL_CLIENT = "true"; + + /** + * System property for the JAAS client context : {@value}. + * + * For SASL authentication to work, this must point to a + * context within the + * + * <p> + * Default value is derived from + * {@link ZooKeeperSaslClient#LOGIN_CONTEXT_NAME_KEY} + */ + String PROP_ZK_SASL_CLIENT_CONTEXT = + ZooKeeperSaslClient.LOGIN_CONTEXT_NAME_KEY; + + /** + * The SASL client username: {@value}. + * <p> + * Set this to the <i>short</i> name of the client, e.g, "user", + * not {@code user/host}, or {@code user/host@REALM} + */ + String PROP_ZK_SASL_CLIENT_USERNAME = "zookeeper.sasl.client.username"; + + /** + * The SASL Server context, referring to a context in the JVM's + * JAAS context file: {@value} + */ + String PROP_ZK_SERVER_SASL_CONTEXT = + ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY; + + /** + * Should ZK Server allow failed SASL clients to downgrade to classic + * authentication on a SASL auth failure: {@value}. + */ + String PROP_ZK_SERVER_MAINTAIN_CONNECTION_DESPITE_SASL_FAILURE = + "zookeeper.maintain_connection_despite_sasl_failure"; + + /** + * should the ZK Server Allow failed SASL clients: {@value}. + */ + String PROP_ZK_ALLOW_FAILED_SASL_CLIENTS = + "zookeeper.allowSaslFailedClients"; + + /** + * Kerberos realm of the server: {@value}. + */ + String PROP_ZK_SERVER_REALM = "zookeeper.server.realm"; + + /** + * Path to a kinit binary: {@value}. + * Defaults to <code>"/usr/bin/kinit"</code> + */ + String PROP_ZK_KINIT_PATH = "zookeeper.kinit"; + + /** + * ID scheme for SASL: {@value}. + */ + String SCHEME_SASL = "sasl"; + + /** + * ID scheme for digest auth: {@value}. + */ + String SCHEME_DIGEST = "digest"; +}
http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/package-info.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/package-info.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/package-info.java new file mode 100644 index 0000000..f7ae983 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/impl/zk/package-info.java @@ -0,0 +1,39 @@ +/* + * 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. + */ + +/** + * Core Zookeeper support. + * <p> + * This package contains the low-level bindings to Curator and Zookeeper, + * including everything related to registry security. + * <p> + * The class {@link org.apache.hadoop.registry.client.impl.zk.CuratorService} + * is a YARN service which offers access to a Zookeeper instance via + * Apache Curator. + * <p> + * The {@link org.apache.hadoop.registry.client.impl.zk.RegistrySecurity} + * implements the security support in the registry, though a set of + * static methods and as a YARN service. + * <p> + * To work with ZK, system properties need to be set before invoking + * some operations/instantiating some objects. The definitions of these + * are kept in {@link org.apache.hadoop.registry.client.impl.zk.ZookeeperConfigOptions}. + * + * + */ +package org.apache.hadoop.registry.client.impl.zk; http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/AddressTypes.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/AddressTypes.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/AddressTypes.java new file mode 100644 index 0000000..61298e6 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/AddressTypes.java @@ -0,0 +1,94 @@ +/* + * 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.client.types; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * Enum of address types -as integers. + * Why integers and not enums? Cross platform serialization as JSON + */ [email protected] [email protected] +public interface AddressTypes { + + /** + * hostname/FQDN and port pair: {@value}. + * The host/domain name and port are set as separate strings in the address + * list, e.g. + * <pre> + * ["namenode.example.org", "9870"] + * </pre> + */ + public static final String ADDRESS_HOSTNAME_AND_PORT = "host/port"; + public static final String ADDRESS_HOSTNAME_FIELD = "host"; + public static final String ADDRESS_PORT_FIELD = "port"; + + + /** + * Path <code>/a/b/c</code> style: {@value}. + * The entire path is encoded in a single entry + * + * <pre> + * ["/users/example/dataset"] + * </pre> + */ + public static final String ADDRESS_PATH = "path"; + + + + /** + * URI entries: {@value}. + * <pre> + * ["http://example.org"] + * </pre> + */ + public static final String ADDRESS_URI = "uri"; + + /** + * Zookeeper addresses as a triple : {@value}. + * <p> + * These are provide as a 3 element tuple of: hostname, port + * and optionally path (depending on the application) + * <p> + * A single element would be + * <pre> + * ["zk1","2181","/registry"] + * </pre> + * An endpoint with multiple elements would list them as + * <pre> + * [ + * ["zk1","2181","/registry"] + * ["zk2","1600","/registry"] + * ] + * </pre> + * + * the third element in each entry , the path, MUST be the same in each entry. + * A client reading the addresses of an endpoint is free to pick any + * of the set, so they must be the same. + * + */ + public static final String ADDRESS_ZOOKEEPER = "zktriple"; + + /** + * Any other address: {@value}. + */ + public static final String ADDRESS_OTHER = ""; +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/Endpoint.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/Endpoint.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/Endpoint.java new file mode 100644 index 0000000..392884f --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/Endpoint.java @@ -0,0 +1,247 @@ +/* + * 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.client.types; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.google.common.base.Preconditions; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.hadoop.registry.client.binding.JsonSerDeser; +import org.apache.hadoop.registry.client.binding.RegistryTypeUtils; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Description of a single service/component endpoint. + * It is designed to be marshalled as JSON. + * <p> + * Every endpoint can have more than one address entry, such as + * a list of URLs to a replicated service, or a (hostname, port) + * pair. Each of these address entries is represented as a string list, + * as that is the only reliably marshallable form of a tuple JSON can represent. + * + * + */ [email protected] [email protected] +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public final class Endpoint implements Cloneable { + + /** + * API implemented at the end of the binding + */ + public String api; + + /** + * Type of address. The standard types are defined in + * {@link AddressTypes} + */ + public String addressType; + + /** + * Protocol type. Some standard types are defined in + * {@link ProtocolTypes} + */ + public String protocolType; + + /** + * a list of address tuples âtuples whose format depends on the address type + */ + public List<Map<String, String>> addresses; + + /** + * Create an empty instance. + */ + public Endpoint() { + } + + /** + * Create an endpoint from another endpoint. + * This is a deep clone with a new list of addresses. + * @param that the endpoint to copy from + */ + public Endpoint(Endpoint that) { + this.api = that.api; + this.addressType = that.addressType; + this.protocolType = that.protocolType; + this.addresses = newAddresses(that.addresses.size()); + for (Map<String, String> address : that.addresses) { + Map<String, String> addr2 = new HashMap<String, String>(address.size()); + addr2.putAll(address); + addresses.add(addr2); + } + } + + /** + * Build an endpoint with a list of addresses + * @param api API name + * @param addressType address type + * @param protocolType protocol type + * @param addrs addresses + */ + public Endpoint(String api, + String addressType, + String protocolType, + List<Map<String, String>> addrs) { + this.api = api; + this.addressType = addressType; + this.protocolType = protocolType; + this.addresses = newAddresses(0); + if (addrs != null) { + addresses.addAll(addrs); + } + } + + /** + * Build an endpoint with an empty address list + * @param api API name + * @param addressType address type + * @param protocolType protocol type + */ + public Endpoint(String api, + String addressType, + String protocolType) { + this.api = api; + this.addressType = addressType; + this.protocolType = protocolType; + this.addresses = newAddresses(0); + } + + /** + * Build an endpoint with a single address entry. + * <p> + * This constructor is superfluous given the varags constructor is equivalent + * for a single element argument. However, type-erasure in java generics + * causes javac to warn about unchecked generic array creation. This + * constructor, which represents the common "one address" case, does + * not generate compile-time warnings. + * @param api API name + * @param addressType address type + * @param protocolType protocol type + * @param addr address. May be null âin which case it is not added + */ + public Endpoint(String api, + String addressType, + String protocolType, + Map<String, String> addr) { + this(api, addressType, protocolType); + if (addr != null) { + addresses.add(addr); + } + } + + /** + * Build an endpoint with a list of addresses + * @param api API name + * @param addressType address type + * @param protocolType protocol type + * @param addrs addresses. Null elements will be skipped + */ + public Endpoint(String api, + String addressType, + String protocolType, + Map<String, String>...addrs) { + this(api, addressType, protocolType); + for (Map<String, String> addr : addrs) { + if (addr!=null) { + addresses.add(addr); + } + } + } + + /** + * Create a new address structure of the requested size + * @param size size to create + * @return the new list + */ + private List<Map<String, String>> newAddresses(int size) { + return new ArrayList<Map<String, String>>(size); + } + + /** + * Build an endpoint from a list of URIs; each URI + * is ASCII-encoded and added to the list of addresses. + * @param api API name + * @param protocolType protocol type + * @param uris URIs to convert to a list of tup;les + */ + public Endpoint(String api, + String protocolType, + URI... uris) { + this.api = api; + this.addressType = AddressTypes.ADDRESS_URI; + + this.protocolType = protocolType; + List<Map<String, String>> addrs = newAddresses(uris.length); + for (URI uri : uris) { + addrs.add(RegistryTypeUtils.uri(uri.toString())); + } + this.addresses = addrs; + } + + @Override + public String toString() { + return marshalToString.toString(this); + } + + /** + * Validate the record by checking for null fields and other invalid + * conditions + * @throws NullPointerException if a field is null when it + * MUST be set. + * @throws RuntimeException on invalid entries + */ + public void validate() { + Preconditions.checkNotNull(api, "null API field"); + Preconditions.checkNotNull(addressType, "null addressType field"); + Preconditions.checkNotNull(protocolType, "null protocolType field"); + Preconditions.checkNotNull(addresses, "null addresses field"); + for (Map<String, String> address : addresses) { + Preconditions.checkNotNull(address, "null element in address"); + } + } + + /** + * Shallow clone: the lists of addresses are shared + * @return a cloned instance + * @throws CloneNotSupportedException + */ + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + + /** + * Static instance of service record marshalling + */ + private static class Marshal extends JsonSerDeser<Endpoint> { + private Marshal() { + super(Endpoint.class); + } + } + + private static final Marshal marshalToString = new Marshal(); +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ProtocolTypes.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ProtocolTypes.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ProtocolTypes.java new file mode 100644 index 0000000..b836b00 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ProtocolTypes.java @@ -0,0 +1,99 @@ +/* + * 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.client.types; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * some common protocol types + */ [email protected] [email protected] +public interface ProtocolTypes { + + /** + * Addresses are URIs of Hadoop Filesystem paths: {@value}. + */ + String PROTOCOL_FILESYSTEM = "hadoop/filesystem"; + + /** + * Hadoop IPC, "classic" or protobuf : {@value}. + */ + String PROTOCOL_HADOOP_IPC = "hadoop/IPC"; + + /** + * Corba IIOP: {@value}. + */ + String PROTOCOL_IIOP = "IIOP"; + + /** + * REST: {@value}. + */ + String PROTOCOL_REST = "REST"; + + /** + * Java RMI: {@value}. + */ + String PROTOCOL_RMI = "RMI"; + + /** + * SunOS RPC, as used by NFS and similar: {@value}. + */ + String PROTOCOL_SUN_RPC = "sunrpc"; + + /** + * Thrift-based protocols: {@value}. + */ + String PROTOCOL_THRIFT = "thrift"; + + /** + * Custom TCP protocol: {@value}. + */ + String PROTOCOL_TCP = "tcp"; + + /** + * Custom UPC-based protocol : {@value}. + */ + String PROTOCOL_UDP = "udp"; + + /** + * Default value âthe protocol is unknown : "{@value}" + */ + String PROTOCOL_UNKNOWN = ""; + + /** + * Web page: {@value}. + * + * This protocol implies that the URLs are designed for + * people to view via web browsers. + */ + String PROTOCOL_WEBUI = "webui"; + + /** + * Web Services: {@value}. + */ + String PROTOCOL_WSAPI = "WS-*"; + + /** + * A zookeeper binding: {@value}. + */ + String PROTOCOL_ZOOKEEPER_BINDING = "zookeeper"; + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/RegistryPathStatus.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/RegistryPathStatus.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/RegistryPathStatus.java new file mode 100644 index 0000000..acd2b21 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/RegistryPathStatus.java @@ -0,0 +1,123 @@ +/* + * 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.client.types; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * Output of a <code>RegistryOperations.stat()</code> call + */ [email protected] [email protected] +@JsonIgnoreProperties(ignoreUnknown = true) +public final class RegistryPathStatus { + + /** + * Short path in the registry to this entry + */ + public final String path; + + /** + * Timestamp + */ + public final long time; + + /** + * Entry size in bytes, as returned by the storage infrastructure. + * In zookeeper, even "empty" nodes have a non-zero size. + */ + public final long size; + + /** + * Number of child nodes + */ + public final int children; + + /** + * Construct an instance + * @param path full path + * @param time time + * @param size entry size + * @param children number of children + */ + public RegistryPathStatus( + @JsonProperty("path") String path, + @JsonProperty("time") long time, + @JsonProperty("size") long size, + @JsonProperty("children") int children) { + this.path = path; + this.time = time; + this.size = size; + this.children = children; + } + + /** + * Equality operator checks size, time and path of the entries. + * It does <i>not</i> check {@link #children}. + * @param other the other entry + * @return true if the entries are considered equal. + */ + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + + RegistryPathStatus status = (RegistryPathStatus) other; + + if (size != status.size) { + return false; + } + if (time != status.time) { + return false; + } + if (path != null ? !path.equals(status.path) : status.path != null) { + return false; + } + return true; + } + + /** + * The hash code is derived from the path. + * @return hash code for storing the path in maps. + */ + @Override + public int hashCode() { + return path != null ? path.hashCode() : 0; + } + + @Override + public String toString() { + final StringBuilder sb = + new StringBuilder("RegistryPathStatus{"); + sb.append("path='").append(path).append('\''); + sb.append(", time=").append(time); + sb.append(", size=").append(size); + sb.append(", children=").append(children); + sb.append('}'); + return sb.toString(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ServiceRecord.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ServiceRecord.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ServiceRecord.java new file mode 100644 index 0000000..9bb02c3 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/ServiceRecord.java @@ -0,0 +1,312 @@ +/* + * 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.client.types; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.google.common.base.Preconditions; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * JSON-marshallable description of a single component. + * It supports the deserialization of unknown attributes, but does + * not support their creation. + */ [email protected] [email protected] +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ServiceRecord implements Cloneable { + + /** + * A type string which MUST be in the serialized json. This permits + * fast discarding of invalid entries + */ + public static final String RECORD_TYPE = "JSONServiceRecord"; + + /** + * The type field. This must be the string {@link #RECORD_TYPE} + */ + public String type = RECORD_TYPE; + + /** + * Description string + */ + public String description; + + /** + * map to handle unknown attributes. + */ + private Map<String, String> attributes = new HashMap<String, String>(4); + + /** + * List of endpoints intended for use to external callers + */ + public List<Endpoint> external = new ArrayList<Endpoint>(); + + /** + * List of endpoints for use <i>within</i> an application. + */ + public List<Endpoint> internal = new ArrayList<Endpoint>(); + + /** + * Create a service record with no ID, description or registration time. + * Endpoint lists are set to empty lists. + */ + public ServiceRecord() { + } + + /** + * Deep cloning constructor + * @param that service record source + */ + public ServiceRecord(ServiceRecord that) { + this.description = that.description; + // others + Map<String, String> thatAttrs = that.attributes; + for (Map.Entry<String, String> entry : thatAttrs.entrySet()) { + attributes.put(entry.getKey(), entry.getValue()); + } + // endpoints + List<Endpoint> src = that.internal; + if (src != null) { + internal = new ArrayList<Endpoint>(src.size()); + for (Endpoint endpoint : src) { + internal.add(new Endpoint(endpoint)); + } + } + src = that.external; + if (src != null) { + external = new ArrayList<Endpoint>(src.size()); + for (Endpoint endpoint : src) { + external.add(new Endpoint(endpoint)); + } + } + } + + /** + * Add an external endpoint + * @param endpoint endpoint to set + */ + public void addExternalEndpoint(Endpoint endpoint) { + Preconditions.checkArgument(endpoint != null); + endpoint.validate(); + external.add(endpoint); + } + + /** + * Add an internal endpoint + * @param endpoint endpoint to set + */ + public void addInternalEndpoint(Endpoint endpoint) { + Preconditions.checkArgument(endpoint != null); + endpoint.validate(); + internal.add(endpoint); + } + + /** + * Look up an internal endpoint + * @param api API + * @return the endpoint or null if there was no match + */ + public Endpoint getInternalEndpoint(String api) { + return findByAPI(internal, api); + } + + /** + * Look up an external endpoint + * @param api API + * @return the endpoint or null if there was no match + */ + public Endpoint getExternalEndpoint(String api) { + return findByAPI(external, api); + } + + /** + * Handle unknown attributes by storing them in the + * {@link #attributes} map + * @param key attribute name + * @param value attribute value. + */ + @JsonAnySetter + public void set(String key, Object value) { + attributes.put(key, value.toString()); + } + + /** + * The map of "other" attributes set when parsing. These + * are not included in the JSON value of this record when it + * is generated. + * @return a map of any unknown attributes in the deserialized JSON. + */ + @JsonAnyGetter + public Map<String, String> attributes() { + return attributes; + } + + /** + * Get the "other" attribute with a specific key + * @param key key to look up + * @return the value or null + */ + public String get(String key) { + return attributes.get(key); + } + + /** + * Get the "other" attribute with a specific key. + * @param key key to look up + * @param defVal default value + * @return the value as a string, + * or <code>defval</code> if the value was not present + */ + public String get(String key, String defVal) { + String val = attributes.get(key); + return val != null ? val: defVal; + } + + /** + * Find an endpoint by its API + * @param list list + * @param api api name + * @return the endpoint or null if there was no match + */ + private Endpoint findByAPI(List<Endpoint> list, String api) { + for (Endpoint endpoint : list) { + if (endpoint.api.equals(api)) { + return endpoint; + } + } + return null; + } + + @Override + public String toString() { + final StringBuilder sb = + new StringBuilder("ServiceRecord{"); + sb.append("description='").append(description).append('\''); + sb.append("; external endpoints: {"); + for (Endpoint endpoint : external) { + sb.append(endpoint).append("; "); + } + sb.append("}; internal endpoints: {"); + for (Endpoint endpoint : internal) { + sb.append(endpoint != null ? endpoint.toString() : "NULL ENDPOINT"); + sb.append("; "); + } + sb.append('}'); + + if (!attributes.isEmpty()) { + sb.append(", attributes: {"); + for (Map.Entry<String, String> attr : attributes.entrySet()) { + sb.append("\"").append(attr.getKey()).append("\"=\"") + .append(attr.getValue()).append("\" "); + } + } else { + + sb.append(", attributes: {"); + } + sb.append('}'); + + sb.append('}'); + return sb.toString(); + } + + /** + * Shallow clone: all endpoints will be shared across instances + * @return a clone of the instance + * @throws CloneNotSupportedException + */ + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public int hashCode() { + // Generated by eclipse + final int prime = 31; + int result = 1; + result = + prime * result + ((attributes == null) ? 0 : attributes.hashCode()); + result = + prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((external == null) ? 0 : external.hashCode()); + result = prime * result + ((internal == null) ? 0 : internal.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ServiceRecord other = (ServiceRecord) obj; + if (attributes == null) { + if (other.attributes != null) { + return false; + } + } else if (!attributes.equals(other.attributes)) { + return false; + } + if (description == null) { + if (other.description != null) { + return false; + } + } else if (!description.equals(other.description)) { + return false; + } + if (external == null) { + if (other.external != null) { + return false; + } + } else if (!external.equals(other.external)) { + return false; + } + if (internal == null) { + if (other.internal != null) { + return false; + } + } else if (!internal.equals(other.internal)) { + return false; + } + if (type == null) { + if (other.type != null) { + return false; + } + } else if (!type.equals(other.type)) { + return false; + } + return true; + } + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/package-info.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/package-info.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/package-info.java new file mode 100644 index 0000000..1c926be --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/package-info.java @@ -0,0 +1,41 @@ +/* + * 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. + */ + +/** + * This package contains all the data types which can be saved to the registry + * and/or marshalled to and from JSON. + * <p> + * The core datatypes, {@link org.apache.hadoop.registry.client.types.ServiceRecord}, + * and {@link org.apache.hadoop.registry.client.types.Endpoint} are + * what is used to describe services and their protocol endpoints in the registry. + * <p> + * Some adjacent interfaces exist to list attributes of the fields: + * <ul> + * <li>{@link org.apache.hadoop.registry.client.types.AddressTypes}</li> + * <li>{@link org.apache.hadoop.registry.client.types.yarn.PersistencePolicies}</li> + * <li>{@link org.apache.hadoop.registry.client.types.ProtocolTypes}</li> + * </ul> + * + * The {@link org.apache.hadoop.registry.client.types.RegistryPathStatus} + * class is not saved to the registry âit is the status of a registry + * entry that can be retrieved from the API call. It is still + * designed to be marshalled to and from JSON, as it can be served up + * from REST front ends to the registry. + * + */ +package org.apache.hadoop.registry.client.types; http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/PersistencePolicies.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/PersistencePolicies.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/PersistencePolicies.java new file mode 100644 index 0000000..e4c7272 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/PersistencePolicies.java @@ -0,0 +1,50 @@ +/* + * 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.client.types.yarn; + +import org.apache.hadoop.registry.client.types.ServiceRecord; + +/** + * Persistence policies for {@link ServiceRecord} + */ + +public interface PersistencePolicies { + + /** + * The record persists until removed manually: {@value}. + */ + String PERMANENT = "permanent"; + + /** + * Remove when the YARN application defined in the id field + * terminates: {@value}. + */ + String APPLICATION = "application"; + + /** + * Remove when the current YARN application attempt ID finishes: {@value}. + */ + String APPLICATION_ATTEMPT = "application-attempt"; + + /** + * Remove when the YARN container in the ID field finishes: {@value} + */ + String CONTAINER = "container"; + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/YarnRegistryAttributes.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/YarnRegistryAttributes.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/YarnRegistryAttributes.java new file mode 100644 index 0000000..b6e7a20 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/client/types/yarn/YarnRegistryAttributes.java @@ -0,0 +1,42 @@ +/* + * 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.client.types.yarn; + +/** + * YARN specific attributes in the registry. + */ +public final class YarnRegistryAttributes { + + /** + * Hidden constructor. + */ + private YarnRegistryAttributes() { + } + + /** + * ID. For containers: container ID. For application instances, + * application ID. + */ + public static final String YARN_ID = "yarn:id"; + public static final String YARN_PERSISTENCE = "yarn:persistence"; + public static final String YARN_PATH = "yarn:path"; + public static final String YARN_HOSTNAME = "yarn:hostname"; + public static final String YARN_IP = "yarn:ip"; + public static final String YARN_COMPONENT = "yarn:component"; +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/RegistryConfiguration.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/RegistryConfiguration.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/RegistryConfiguration.java new file mode 100644 index 0000000..ab06399 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/RegistryConfiguration.java @@ -0,0 +1,41 @@ +/* + * 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.conf; + +import org.apache.hadoop.conf.Configuration; + +/** + * Intermediate configuration class to import the keys from YarnConfiguration + * in yarn-default.xml and yarn-site.xml. Once hadoop-yarn-registry is totally + * deprecated, this should be deprecated. + */ +public class RegistryConfiguration extends Configuration { + + static { + Configuration.addDefaultResource("yarn-default.xml"); + Configuration.addDefaultResource("yarn-site.xml"); + } + + /** + * Default constructor which relies on the static method to import the YARN + * settings. + */ + public RegistryConfiguration() { + super(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/package-info.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/package-info.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/package-info.java new file mode 100644 index 0000000..50d03eb --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/conf/package-info.java @@ -0,0 +1,22 @@ +/* + * 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. + */ + +/** + * Configuration for the Hadoop Service Registry. + */ +package org.apache.hadoop.registry.conf; http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ApplicationServiceRecordProcessor.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ApplicationServiceRecordProcessor.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ApplicationServiceRecordProcessor.java new file mode 100644 index 0000000..0b5f724 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ApplicationServiceRecordProcessor.java @@ -0,0 +1,366 @@ +/* + * 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.hadoop.registry.client.types.Endpoint; +import org.apache.hadoop.registry.client.types.ServiceRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xbill.DNS.Name; +import org.xbill.DNS.Type; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +/** + * A processor for generating application DNS records from registry service + * records. + */ +public class ApplicationServiceRecordProcessor extends + BaseServiceRecordProcessor { + private static final Logger LOG = + LoggerFactory.getLogger(ApplicationServiceRecordProcessor.class); + /** + * Create an application service record processor. + * + * @param record the service record + * @param path the service record registry node path + * @param domain the DNS zone/domain name + * @param zoneSelector returns the zone associated with the provided name. + * @throws Exception if an issue is generated during instantiation. + */ + public ApplicationServiceRecordProcessor( + ServiceRecord record, String path, String domain, + ZoneSelector zoneSelector) throws Exception { + super(record, path, domain, zoneSelector); + } + + /** + * Initializes the DNS record type to descriptor mapping based on the + * provided service record. + * + * @param serviceRecord the registry service record. + * @throws Exception if an issue is encountered. + */ + @Override public void initTypeToInfoMapping(ServiceRecord serviceRecord) + throws Exception { + if (serviceRecord.external.isEmpty()) { + LOG.info(serviceRecord.description + ": No external endpoints defined."); + return; + } + for (int type : getRecordTypes()) { + switch (type) { + case Type.A: + createAInfo(serviceRecord); + break; + case Type.AAAA: + createAAAAInfo(serviceRecord); + break; + case Type.TXT: + createTXTInfo(serviceRecord); + break; + case Type.CNAME: + createCNAMEInfo(serviceRecord); + break; + case Type.SRV: + createSRVInfo(serviceRecord); + break; + default: + throw new IllegalArgumentException("Unknown type " + type); + + } + } + } + + /** + * Create an application TXT record descriptor. + * + * @param serviceRecord the service record. + * @throws Exception if there is an issue during descriptor creation. + */ + protected void createTXTInfo(ServiceRecord serviceRecord) throws Exception { + List<Endpoint> endpoints = serviceRecord.external; + List<RecordDescriptor> recordDescriptors = new ArrayList<>(); + TXTApplicationRecordDescriptor txtInfo; + for (Endpoint endpoint : endpoints) { + txtInfo = new TXTApplicationRecordDescriptor( + serviceRecord, endpoint); + recordDescriptors.add(txtInfo); + } + registerRecordDescriptor(Type.TXT, recordDescriptors); + } + + /** + * Create an application SRV record descriptor. + * + * @param serviceRecord the service record. + * @throws Exception if there is an issue during descriptor creation. + */ + protected void createSRVInfo(ServiceRecord serviceRecord) throws Exception { + List<Endpoint> endpoints = serviceRecord.external; + List<RecordDescriptor> recordDescriptors = new ArrayList<>(); + SRVApplicationRecordDescriptor srvInfo; + for (Endpoint endpoint : endpoints) { + srvInfo = new SRVApplicationRecordDescriptor( + serviceRecord, endpoint); + recordDescriptors.add(srvInfo); + } + registerRecordDescriptor(Type.SRV, recordDescriptors); + } + + /** + * Create an application CNAME record descriptor. + * + * @param serviceRecord the service record. + * @throws Exception if there is an issue during descriptor creation. + */ + protected void createCNAMEInfo(ServiceRecord serviceRecord) throws Exception { + List<Endpoint> endpoints = serviceRecord.external; + List<RecordDescriptor> recordDescriptors = new ArrayList<>(); + CNAMEApplicationRecordDescriptor cnameInfo; + for (Endpoint endpoint : endpoints) { + cnameInfo = new CNAMEApplicationRecordDescriptor( + serviceRecord, endpoint); + recordDescriptors.add(cnameInfo); + } + registerRecordDescriptor(Type.CNAME, recordDescriptors); + } + + /** + * Create an application AAAA record descriptor. + * + * @param record the service record. + * @throws Exception if there is an issue during descriptor creation. + */ + protected void createAAAAInfo(ServiceRecord record) + throws Exception { + AAAAApplicationRecordDescriptor + recordInfo = new AAAAApplicationRecordDescriptor( + getPath(), record); + registerRecordDescriptor(Type.AAAA, recordInfo); + } + + /** + * Create an application A record descriptor. + * + * @param record the service record. + * @throws Exception if there is an issue during descriptor creation. + */ + protected void createAInfo(ServiceRecord record) throws Exception { + AApplicationRecordDescriptor recordInfo = new AApplicationRecordDescriptor( + getPath(), record); + registerRecordDescriptor(Type.A, recordInfo); + } + + /** + * Returns the record types associated with a container service record. + * + * @return the record type array + */ + @Override public int[] getRecordTypes() { + return new int[] {Type.A, Type.AAAA, Type.CNAME, Type.SRV, Type.TXT}; + } + + /** + * An application TXT record descriptor. + */ + class TXTApplicationRecordDescriptor + extends ApplicationRecordDescriptor<List<String>> { + + /** + * Creates an application TXT record descriptor. + * + * @param record service record + * @throws Exception + */ + public TXTApplicationRecordDescriptor(ServiceRecord record, + Endpoint endpoint) throws Exception { + super(record, endpoint); + } + + /** + * Initializes the descriptor parameters. + * + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) + throws Exception { + if (getEndpoint() != null) { + this.setNames(new Name[] {getServiceName(), getEndpointName()}); + this.setTarget(getTextRecords(getEndpoint())); + } + } + + } + + /** + * An application SRV record descriptor. + */ + class SRVApplicationRecordDescriptor extends + ApplicationRecordDescriptor<RecordCreatorFactory.HostPortInfo> { + + /** + * Creates an application SRV record descriptor. + * + * @param record service record + * @throws Exception + */ + public SRVApplicationRecordDescriptor(ServiceRecord record, + Endpoint endpoint) throws Exception { + super(record, endpoint); + } + + /** + * Initializes the descriptor parameters. + * + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) + throws Exception { + if (getEndpoint() != null) { + this.setNames(new Name[] {getServiceName(), getEndpointName()}); + this.setTarget(new RecordCreatorFactory.HostPortInfo( + Name.fromString(getHost(getEndpoint()) + "."), getPort( + getEndpoint()))); + } + } + + } + + /** + * An application CNAME record descriptor. + */ + class CNAMEApplicationRecordDescriptor extends + ApplicationRecordDescriptor<Name> { + + /** + * Creates an application CNAME record descriptor. + * + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public CNAMEApplicationRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(record); + } + + /** + * Creates an application CNAME record descriptor. This descriptor is the + * source for API related CNAME records. + * + * @param record service record + * @param endpoint the API endpoint + * @throws Exception + */ + public CNAMEApplicationRecordDescriptor(ServiceRecord record, + Endpoint endpoint) throws Exception { + super(record, endpoint); + } + + /** + * Initializes the descriptor parameters. + * + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) + throws Exception { + if (getEndpoint() != null) { + this.setNames(new Name[] {getEndpointName()}); + this.setTarget(getServiceName()); + } + } + + } + + /** + * An application A record descriptor. + */ + class AApplicationRecordDescriptor + extends ApplicationRecordDescriptor<InetAddress> { + + /** + * Creates an application A record descriptor. + * + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public AApplicationRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(record); + } + + /** + * Initializes the descriptor parameters. + * + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) + throws Exception { + this.setNames(new Name[] {getServiceName()}); + List<Endpoint> endpoints = serviceRecord.external; + if (endpoints.isEmpty()) { + return; + } + // TODO: do we need a "hostname" attribute for an application record or + // can we rely on the first endpoint record. + this.setTarget(InetAddress.getByName( + getHost(endpoints.get(0)))); + } + + } + + /** + * An application AAAA record descriptor. + */ + class AAAAApplicationRecordDescriptor extends AApplicationRecordDescriptor { + + /** + * Creates an application AAAA record descriptor. + * + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public AAAAApplicationRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(path, record); + } + + /** + * Initializes the descriptor parameters. + * + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) + throws Exception { + super.init(serviceRecord); + if (getTarget() == null) { + return; + } + try { + this.setTarget(getIpv6Address(getTarget())); + } catch (UnknownHostException e) { + throw new IllegalStateException(e); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/BaseServiceRecordProcessor.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/BaseServiceRecordProcessor.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/BaseServiceRecordProcessor.java new file mode 100644 index 0000000..f30c0c2 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/BaseServiceRecordProcessor.java @@ -0,0 +1,470 @@ +/* + * 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.hadoop.fs.PathNotFoundException; +import org.apache.hadoop.registry.client.binding.RegistryPathUtils; +import org.apache.hadoop.registry.client.types.AddressTypes; +import org.apache.hadoop.registry.client.types.Endpoint; +import org.apache.hadoop.registry.client.types.ServiceRecord; +import org.xbill.DNS.Name; +import org.xbill.DNS.ReverseMap; +import org.xbill.DNS.TextParseException; + +import java.io.IOException; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.URI; +import java.net.UnknownHostException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Provides common service record processing logic. + */ +public abstract class BaseServiceRecordProcessor + implements ServiceRecordProcessor { + + private final ZoneSelector zoneSelctor; + private Map<Integer, List<RecordDescriptor>> typeToDescriptorMap = + new HashMap<>(); + private String path; + private String domain; + + private static final String YARN_SERVICE_API_PREFIX = + "classpath:org.apache.hadoop.yarn.service."; + private static final String HTTP_API_TYPE = "http://"; + + /** + * Creates a service record processor. + * + * @param record the service record. + * @param path the node path for the record in the registry. + * @param domain the target DNS domain for the service record + * associated DNS records. + * @param zoneSelector A selector of the best zone for a given DNS name. + * @throws Exception if an issue is generated during instantiation. + */ + public BaseServiceRecordProcessor(ServiceRecord record, String path, + String domain, ZoneSelector zoneSelector) + throws Exception { + this.setPath(path); + this.domain = domain; + this.zoneSelctor = zoneSelector; + initTypeToInfoMapping(record); + } + + /** + * Return the IPv6 mapped address for the provided IPv4 address. Utilized + * to create corresponding AAAA records. + * + * @param address the IPv4 address. + * @return the mapped IPv6 address. + * @throws UnknownHostException + */ + static InetAddress getIpv6Address(InetAddress address) + throws UnknownHostException { + String[] octets = address.getHostAddress().split("\\."); + byte[] octetBytes = new byte[4]; + for (int i = 0; i < 4; ++i) { + octetBytes[i] = (byte) Integer.parseInt(octets[i]); + } + + byte[] ipv4asIpV6addr = new byte[16]; + ipv4asIpV6addr[10] = (byte) 0xff; + ipv4asIpV6addr[11] = (byte) 0xff; + ipv4asIpV6addr[12] = octetBytes[0]; + ipv4asIpV6addr[13] = octetBytes[1]; + ipv4asIpV6addr[14] = octetBytes[2]; + ipv4asIpV6addr[15] = octetBytes[3]; + + return Inet6Address.getByAddress(null, ipv4asIpV6addr, 0); + } + + /** + * Reverse the string representation of the input IP address. + * + * @param ip the string representation of the IP address. + * @return the reversed IP address. + * @throws UnknownHostException if the ip is unknown. + */ + protected Name reverseIP(String ip) throws UnknownHostException { + return ReverseMap.fromAddress(ip); + } + + /** + * Manages the creation and registration of service record generated DNS + * records. + * + * @param command the DNS registration command object (e.g. add_record, + * remove record) + * @throws IOException if the creation or registration generates an issue. + */ + @SuppressWarnings({"unchecked"}) + public void manageDNSRecords(RegistryDNS.RegistryCommand command) + throws IOException { + for (Map.Entry<Integer, List<RecordDescriptor>> entry : + typeToDescriptorMap.entrySet()) { + for (RecordDescriptor recordDescriptor : entry.getValue()) { + for (Name name : recordDescriptor.getNames()) { + RecordCreatorFactory.RecordCreator recordCreator = + RecordCreatorFactory.getRecordCreator(entry.getKey()); + command.exec(zoneSelctor.findBestZone(name), + recordCreator.create(name, recordDescriptor.getTarget())); + } + } + } + } + + /** + * Add the DNS record descriptor object to the record type to descriptor + * mapping. + * + * @param type the DNS record type. + * @param recordDescriptor the DNS record descriptor + */ + protected void registerRecordDescriptor(int type, + RecordDescriptor recordDescriptor) { + List<RecordDescriptor> infos = new ArrayList<>(); + infos.add(recordDescriptor); + typeToDescriptorMap.put(type, infos); + } + + /** + * Add the DNS record descriptor objects to the record type to descriptor + * mapping. + * + * @param type the DNS record type. + * @param recordDescriptors the DNS record descriptors + */ + protected void registerRecordDescriptor(int type, + List<RecordDescriptor> recordDescriptors) { + typeToDescriptorMap.put(type, recordDescriptors); + } + + /** + * Return the path associated with the record. + * @return the path. + */ + protected String getPath() { + return path; + } + + /** + * Set the path associated with the record. + * @param path the path. + */ + protected void setPath(String path) { + this.path = path; + } + + /** + * A descriptor container the information to be populated into a DNS record. + * + * @param <T> the DNS record type/class. + */ + abstract class RecordDescriptor<T> { + private final ServiceRecord record; + private Name[] names; + private T target; + + /** + * Creates a DNS record descriptor. + * + * @param record the associated service record. + */ + public RecordDescriptor(ServiceRecord record) { + this.record = record; + } + + /** + * Returns the DNS names associated with the record type and information. + * + * @return the array of names. + */ + public Name[] getNames() { + return names; + } + + /** + * Return the target object for the DNS record. + * + * @return the DNS record target. + */ + public T getTarget() { + return target; + } + + /** + * Initializes the names and information for this DNS record descriptor. + * + * @param serviceRecord the service record. + * @throws Exception + */ + protected abstract void init(ServiceRecord serviceRecord) throws Exception; + + /** + * Returns the service record. + * @return the service record. + */ + public ServiceRecord getRecord() { + return record; + } + + /** + * Sets the names associated with the record type and information. + * @param names the names. + */ + public void setNames(Name[] names) { + this.names = names; + } + + /** + * Sets the target object associated with the record. + * @param target the target. + */ + public void setTarget(T target) { + this.target = target; + } + } + + /** + * A container-based DNS record descriptor. + * + * @param <T> the DNS record type/class. + */ + abstract class ContainerRecordDescriptor<T> extends RecordDescriptor<T> { + + public ContainerRecordDescriptor(String path, ServiceRecord record) + throws Exception { + super(record); + init(record); + } + + /** + * Returns the DNS name constructed from the YARN container ID. + * + * @return the container ID name. + * @throws TextParseException + */ + protected Name getContainerIDName() throws TextParseException { + String containerID = RegistryPathUtils.lastPathEntry(getPath()); + return Name.fromString(String.format("%s.%s", containerID, domain)); + } + + /** + * Returns the DNS name constructed from the container role/component name. + * + * @return the DNS naem. + * @throws PathNotFoundException + * @throws TextParseException + */ + protected Name getContainerName() + throws PathNotFoundException, TextParseException { + String service = RegistryPathUtils.lastPathEntry( + RegistryPathUtils.parentOf(RegistryPathUtils.parentOf(getPath()))); + String description = getRecord().description.toLowerCase(); + String user = RegistryPathUtils.getUsername(getPath()); + return Name.fromString(MessageFormat.format("{0}.{1}.{2}.{3}", + description, + service, + user, + domain)); + } + + /** + * Return the DNS name constructed from the component name. + * + * @return the DNS naem. + * @throws PathNotFoundException + * @throws TextParseException + */ + protected Name getComponentName() + throws PathNotFoundException, TextParseException { + String service = RegistryPathUtils.lastPathEntry( + RegistryPathUtils.parentOf(RegistryPathUtils.parentOf(getPath()))); + String component = getRecord().get("yarn:component").toLowerCase(); + String user = RegistryPathUtils.getUsername(getPath()); + return Name.fromString(MessageFormat.format("{0}.{1}.{2}.{3}", + component, + service, + user, + domain)); + } + + } + + /** + * An application-based DNS record descriptor. + * + * @param <T> the DNS record type/class. + */ + abstract class ApplicationRecordDescriptor<T> extends RecordDescriptor<T> { + + private Endpoint srEndpoint; + + /** + * Creates an application associated DNS record descriptor. + * + * @param record the service record. + * @throws Exception + */ + public ApplicationRecordDescriptor(ServiceRecord record) + throws Exception { + this(record, null); + } + + /** + * Creates an application associated DNS record descriptor. The endpoint + * is leverated to create an associated application API record. + * + * @param record the service record. + * @param endpoint an API endpoint. + * @throws Exception + */ + public ApplicationRecordDescriptor(ServiceRecord record, + Endpoint endpoint) throws Exception { + super(record); + this.setEndpoint(endpoint); + init(record); + } + + /** + * Get the service's DNS name for registration. + * + * @return the service DNS name. + * @throws TextParseException + */ + protected Name getServiceName() throws TextParseException { + String user = RegistryPathUtils.getUsername(getPath()); + String service = + String.format("%s.%s.%s", + RegistryPathUtils.lastPathEntry(getPath()), + user, + domain); + return Name.fromString(service); + } + + /** + * Get the host from the provided endpoint record. + * + * @param endpoint the endpoint info. + * @return the host name. + */ + protected String getHost(Endpoint endpoint) { + String host = null; + // assume one address for now + Map<String, String> address = endpoint.addresses.get(0); + if (endpoint.addressType.equals(AddressTypes.ADDRESS_HOSTNAME_AND_PORT)) { + host = address.get(AddressTypes.ADDRESS_HOSTNAME_FIELD); + } else if (endpoint.addressType.equals(AddressTypes.ADDRESS_URI)) { + URI uri = URI.create(address.get("uri")); + host = uri.getHost(); + } + return host; + } + + /** + * Get the post from the provided endpoint record. + * + * @param endpoint the endpoint info. + * @return the port. + */ + protected int getPort(Endpoint endpoint) { + int port = -1; + // assume one address for now + Map<String, String> address = endpoint.addresses.get(0); + if (endpoint.addressType.equals(AddressTypes.ADDRESS_HOSTNAME_AND_PORT)) { + port = Integer.parseInt(address.get(AddressTypes.ADDRESS_PORT_FIELD)); + } else if (endpoint.addressType.equals(AddressTypes.ADDRESS_URI)) { + URI uri = URI.create(address.get("uri")); + port = uri.getPort(); + } + return port; + } + + /** + * Get the list of strings that can be related in a TXT record for the given + * endpoint. + * + * @param endpoint the endpoint information. + * @return the list of strings relating endpoint info. + */ + protected List<String> getTextRecords(Endpoint endpoint) { + Map<String, String> address = endpoint.addresses.get(0); + List<String> txtRecs = new ArrayList<String>(); + txtRecs.add("api=" + getDNSApiFragment(endpoint.api)); + if (endpoint.addressType.equals(AddressTypes.ADDRESS_URI)) { + URI uri = URI.create(address.get("uri")); + txtRecs.add("path=" + uri.getPath()); + } + return txtRecs; + } + + /** + * Get an API name that is compatible with DNS standards (and shortened). + * + * @param api the api indicator. + * @return the shortened and compatible api name. + */ + protected String getDNSApiFragment(String api) { + String dnsApi = null; + if (api.startsWith(YARN_SERVICE_API_PREFIX)) { + dnsApi = api.substring(YARN_SERVICE_API_PREFIX.length()); + } else if (api.startsWith(HTTP_API_TYPE)) { + dnsApi = "http"; + } + assert dnsApi != null; + dnsApi = dnsApi.replace('.', '-'); + return dnsApi; + } + + /** + * Return the DNS name associated with the API endpoint. + * + * @return the name. + * @throws TextParseException + */ + protected Name getEndpointName() throws TextParseException { + return Name.fromString(String.format("%s-api.%s", + getDNSApiFragment( + getEndpoint().api), + getServiceName())); + } + + /** + * Returns the endpoint. + * @return the endpoint. + */ + public Endpoint getEndpoint() { + return srEndpoint; + } + + /** + * Sets the endpoint. + * @param endpoint the endpoint. + */ + public void setEndpoint( + Endpoint endpoint) { + this.srEndpoint = endpoint; + } + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ContainerServiceRecordProcessor.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ContainerServiceRecordProcessor.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ContainerServiceRecordProcessor.java new file mode 100644 index 0000000..e40a177 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/ContainerServiceRecordProcessor.java @@ -0,0 +1,284 @@ +/* + * 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.hadoop.fs.PathNotFoundException; +import org.apache.hadoop.registry.client.types.ServiceRecord; +import org.apache.hadoop.registry.client.types.yarn.YarnRegistryAttributes; +import org.xbill.DNS.Name; +import org.xbill.DNS.TextParseException; +import org.xbill.DNS.Type; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; + +/** + * A processor for generating container DNS records from registry service + * records. + */ +public class ContainerServiceRecordProcessor extends + BaseServiceRecordProcessor { + + /** + * Create a container service record processor. + * @param record the service record + * @param path the service record registry node path + * @param domain the DNS zone/domain name + * @param zoneSelector returns the zone associated with the provided name. + * @throws Exception if an issue is generated during instantiation. + */ + public ContainerServiceRecordProcessor( + ServiceRecord record, String path, String domain, + ZoneSelector zoneSelector) throws Exception { + super(record, path, domain, zoneSelector); + } + + /** + * Initializes the DNS record type to descriptor mapping based on the + * provided service record. + * @param serviceRecord the registry service record. + * @throws Exception if an issue arises. + */ + @Override public void initTypeToInfoMapping(ServiceRecord serviceRecord) + throws Exception { + if (serviceRecord.get(YarnRegistryAttributes.YARN_IP) != null) { + for (int type : getRecordTypes()) { + switch (type) { + case Type.A: + createAInfo(serviceRecord); + break; + case Type.AAAA: + createAAAAInfo(serviceRecord); + break; + case Type.PTR: + createPTRInfo(serviceRecord); + break; + case Type.TXT: + createTXTInfo(serviceRecord); + break; + default: + throw new IllegalArgumentException("Unknown type " + type); + + } + } + } + } + + /** + * Create a container TXT record descriptor. + * @param serviceRecord the service record. + * @throws Exception if the descriptor creation yields an issue. + */ + protected void createTXTInfo(ServiceRecord serviceRecord) throws Exception { + TXTContainerRecordDescriptor txtInfo = + new TXTContainerRecordDescriptor(getPath(), serviceRecord); + registerRecordDescriptor(Type.TXT, txtInfo); + } + + /** + * Creates a container PTR record descriptor. + * @param record the service record. + * @throws Exception if the descriptor creation yields an issue. + */ + protected void createPTRInfo(ServiceRecord record) throws Exception { + PTRContainerRecordDescriptor + ptrInfo = new PTRContainerRecordDescriptor(getPath(), record); + registerRecordDescriptor(Type.PTR, ptrInfo); + } + + /** + * Creates a container AAAA (IPv6) record descriptor. + * @param record the service record + * @throws Exception if the descriptor creation yields an issue. + */ + protected void createAAAAInfo(ServiceRecord record) + throws Exception { + AAAAContainerRecordDescriptor + recordInfo = new AAAAContainerRecordDescriptor( + getPath(), record); + registerRecordDescriptor(Type.AAAA, recordInfo); + } + + /** + * Creates a container A (IPv4) record descriptor. + * @param record service record. + * @throws Exception if the descriptor creation yields an issue. + */ + protected void createAInfo(ServiceRecord record) throws Exception { + AContainerRecordDescriptor recordInfo = new AContainerRecordDescriptor( + getPath(), record); + registerRecordDescriptor(Type.A, recordInfo); + } + + /** + * Returns the record types associated with a container service record. + * @return the record type array + */ + @Override public int[] getRecordTypes() { + return new int[] {Type.A, Type.AAAA, Type.PTR, Type.TXT}; + } + + /** + * A container TXT record descriptor. + */ + class TXTContainerRecordDescriptor + extends ContainerRecordDescriptor<List<String>> { + + /** + * Creates a container TXT record descriptor. + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public TXTContainerRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(path, record); + } + + /** + * Initializes the descriptor parameters. + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) { + try { + this.setNames(new Name[] {getContainerName()}); + } catch (TextParseException e) { + // log + } catch (PathNotFoundException e) { + // log + } + List<String> txts = new ArrayList<>(); + txts.add("id=" + serviceRecord.get(YarnRegistryAttributes.YARN_ID)); + this.setTarget(txts); + } + + } + + /** + * A container PTR record descriptor. + */ + class PTRContainerRecordDescriptor extends ContainerRecordDescriptor<Name> { + + /** + * Creates a container PTR record descriptor. + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public PTRContainerRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(path, record); + } + + /** + * Initializes the descriptor parameters. + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) { + String host = serviceRecord.get(YarnRegistryAttributes.YARN_HOSTNAME); + String ip = serviceRecord.get(YarnRegistryAttributes.YARN_IP); + Name reverseLookupName = null; + if (host != null && ip != null) { + try { + reverseLookupName = reverseIP(ip); + } catch (UnknownHostException e) { + //LOG + } + } + this.setNames(new Name[] {reverseLookupName}); + try { + this.setTarget(getContainerName()); + } catch (TextParseException e) { + //LOG + } catch (PathNotFoundException e) { + //LOG + } + } + + } + + + /** + * A container A record descriptor. + */ + class AContainerRecordDescriptor + extends ContainerRecordDescriptor<InetAddress> { + + /** + * Creates a container A record descriptor. + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public AContainerRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(path, record); + } + + /** + * Initializes the descriptor parameters. + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) { + String ip = serviceRecord.get(YarnRegistryAttributes.YARN_IP); + if (ip == null) { + throw new IllegalArgumentException("No IP specified"); + } + try { + this.setTarget(InetAddress.getByName(ip)); + this.setNames(new Name[] {getContainerName(), getContainerIDName(), + getComponentName()}); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + } + + } + + /** + * A container AAAA record descriptor. + */ + class AAAAContainerRecordDescriptor extends AContainerRecordDescriptor { + + /** + * Creates a container AAAA record descriptor. + * @param path registry path for service record + * @param record service record + * @throws Exception + */ + public AAAAContainerRecordDescriptor(String path, + ServiceRecord record) throws Exception { + super(path, record); + } + + /** + * Initializes the descriptor parameters. + * @param serviceRecord the service record. + */ + @Override protected void init(ServiceRecord serviceRecord) { + super.init(serviceRecord); + try { + this.setTarget(getIpv6Address(getTarget())); + } catch (UnknownHostException e) { + throw new IllegalStateException(e); + } + } + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2a9fa84/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java new file mode 100644 index 0000000..c2fc4a9 --- /dev/null +++ b/hadoop-common-project/hadoop-registry/src/main/java/org/apache/hadoop/registry/server/dns/LookupTask.java @@ -0,0 +1,39 @@ +/* + * 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 java.util.concurrent.Callable; + +import org.xbill.DNS.Lookup; +import org.xbill.DNS.Name; +import org.xbill.DNS.Record; + +public class LookupTask implements Callable<Record[]> { + + private Name name; + private int type; + + public LookupTask(Name name, int type) { + this.name = name; + this.type = type; + } + + @Override + public Record[] call() throws Exception { + return new Lookup(name, type).run(); + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
