blob: 313d3bd01b5d505bfd4f5486a85989aa32a8e705 [file] [log] [blame]
/*
*
* * 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.ambari.server.stack;
import static org.apache.commons.lang.StringUtils.isBlank;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.utils.HTTPUtils;
import org.apache.ambari.server.utils.HostAndPort;
import org.apache.commons.lang.builder.ToStringBuilder;
/**
* I represent a nameServiceId that belongs to HDFS. Multiple namenodes may belong to the same nameServiceId.
* Each NameNode has either an http or https address.
*/
public class NameService {
public static class NameNode {
private final String uniqueId;
private final String address;
private final boolean encrypted;
private final String propertyName;
public static NameNode fromConfig(String nameServiceId, String nnUniqueId, ConfigHelper config, Cluster cluster) {
String namenodeFragment = "dfs.namenode." + (isEncrypted(config, cluster) ? "https-address" : "http-address") + ".{0}.{1}";
String propertyName = MessageFormat.format(namenodeFragment, nameServiceId, nnUniqueId);
return new NameNode(
nnUniqueId,
config.getValueFromDesiredConfigurations(cluster, ConfigHelper.HDFS_SITE, propertyName),
isEncrypted(config, cluster),
propertyName);
}
NameNode(String uniqueId, String address, boolean encrypted, String propertyName) {
this.uniqueId = uniqueId;
this.address = address;
this.encrypted = encrypted;
this.propertyName = propertyName;
}
public String getHost() {
return getAddress().host.toLowerCase();
}
public int getPort() {
return getAddress().port;
}
private HostAndPort getAddress() {
HostAndPort hp = HTTPUtils.getHostAndPortFromProperty(address);
if (hp == null) {
throw new IllegalArgumentException("Could not parse host and port from " + address);
}
return hp;
}
private static boolean isEncrypted(ConfigHelper config, Cluster cluster) {
String policy = config.getValueFromDesiredConfigurations(cluster, ConfigHelper.HDFS_SITE, "dfs.http.policy");
return (policy != null && policy.equalsIgnoreCase(ConfigHelper.HTTPS_ONLY));
}
public boolean isEncrypted() {
return encrypted;
}
public String getPropertyName() {
return propertyName;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("uniqueId", uniqueId)
.append("address", address)
.append("encrypted", encrypted)
.append("propertyName", propertyName)
.toString();
}
}
public final String nameServiceId;
/**
* NameNodes in this nameservice.
* The minimum number of NameNodes for HA is two, but more can be configured.
*/
private final List<NameNode> nameNodes;
public static List<NameService> fromConfig(ConfigHelper config, Cluster cluster) {
return nameServiceIds(config, cluster).stream()
.map(nameServiceId -> nameService(nameServiceId, config, cluster))
.collect(Collectors.toList());
}
private static List<String> nameServiceIds(ConfigHelper config, Cluster cluster) {
return separateByComma(config, cluster, "dfs.internal.nameservices");
}
private static NameService nameService(String nameServiceId, ConfigHelper config, Cluster cluster) {
List<NameNode> namenodes = nnUniqueIds(nameServiceId, config, cluster).stream()
.map(nnUniquId -> NameNode.fromConfig(nameServiceId, nnUniquId, config, cluster))
.collect(Collectors.toList());
return new NameService(nameServiceId, namenodes);
}
private static List<String> nnUniqueIds(String nameServiceId, ConfigHelper config, Cluster cluster) {
return separateByComma(config, cluster, "dfs.ha.namenodes." + nameServiceId);
}
private static List<String> separateByComma(ConfigHelper config, Cluster cluster, String propertyName) {
String propertyValue = config.getValueFromDesiredConfigurations(cluster, ConfigHelper.HDFS_SITE, propertyName);
return isBlank(propertyValue)
? Collections.emptyList()
: Arrays.asList(propertyValue.split(","));
}
private NameService(String nameServiceId, List<NameNode> nameNodes) {
this.nameServiceId = nameServiceId;
this.nameNodes = nameNodes;
}
public List<NameNode> getNameNodes() {
return nameNodes;
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("nameServiceId", nameServiceId)
.append("nameNodes", getNameNodes())
.toString();
}
}