/*************************************************************************** * Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved. * Licensed 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 com.vmware.bdd.plugin.clouderamgr.model.support; import com.google.gson.annotations.Expose; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.regex.Pattern; /** * Author: Xiaoding Bian * Date: 6/12/14 * Time: 3:37 PM */ public class AvailableServiceRole implements Comparable<AvailableServiceRole> { public static final String ROOT_SERVICE = "CLUSTER"; @Expose private String name; // the name used in Cloudera Manager, i.e, "SERVER" for zookeeper server @Expose private String displayName; // the alias name used in BDE, i.e, "ZOOKEEPER_SERVER" for role "SERVER" @Expose(serialize = false) private AvailableServiceRole parent; @Expose private AvailableParcelRepo repository; @Expose private String versionApiMin; @Expose private String versionApiMax; @Expose private String versionCdhMin; @Expose private String versionCdhMax; @Expose(serialize = false) private Map<String, AvailableConfiguration> availableConfigurations; private List<Dependency> dependencies; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public AvailableServiceRole getParent() { return parent; } public void setParent(String parent) throws IOException { this.parent = null; if (parent != null) { this.parent = AvailableServiceRoleContainer.load(parent); } } public AvailableParcelRepo getRepository() { return repository; } public void setRepository(String repository) { this.repository = AvailableParcelRepo.valueOf(repository); } public String getVersionApiMin() { return versionApiMin; } public void setVersionApiMin(String versionApiMin) { this.versionApiMin = versionApiMin; } public String getVersionApiMax() { return versionApiMax; } public void setVersionApiMax(String versionApiMax) { this.versionApiMax = versionApiMax; } public String getVersionCdhMin() { return versionCdhMin; } public void setVersionCdhMin(String versionCdhMin) { this.versionCdhMin = versionCdhMin; } public String getVersionCdhMax() { return versionCdhMax; } public void setVersionCdhMax(String versionCdhMax) { this.versionCdhMax = versionCdhMax; } public Map<String, AvailableConfiguration> getAvailableConfigurations() { return availableConfigurations; } public void setAvailableConfigurations(List<AvailableConfiguration> configs) { this.availableConfigurations = new HashMap<String, AvailableConfiguration>(); this.dependencies = new ArrayList<Dependency>(); Pattern serviceDependPattern = Pattern.compile("([a-z]+\\_)+service$"); for (AvailableConfiguration config : configs) { this.availableConfigurations.put(config.getName(), config); if (serviceDependPattern.matcher(config.getName()).matches()) { try { Dependency dependency = new Dependency(config); this.dependencies.add(dependency); } catch (Exception e) { } } } } public List<Dependency> getDependencies() { return dependencies; } public boolean isService() { return parent != null && parent.getDisplayName().equalsIgnoreCase(ROOT_SERVICE); } public boolean isRole() { return parent != null && parent.isService(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || this.getClass() != o.getClass()) { return false; } AvailableServiceRole other = (AvailableServiceRole) o; if (this.getName().equalsIgnoreCase(other.getName()) && this.getDisplayName().equalsIgnoreCase(other.getDisplayName())) { return true; } return false; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (name == null? 0 : name.hashCode()); result = prime * result + (displayName == null? 0 : displayName.hashCode()); return result; } @Override public int compareTo(AvailableServiceRole other) { if (!isService() || !other.isService()) { return 0; } if (dependsOn(other)) { return 1; } if (other.dependsOn(this)) { return -1; } return 0; } private boolean dependsOn(AvailableServiceRole other) { Queue<AvailableServiceRole> queue = new LinkedList<AvailableServiceRole>(); queue.add(this); while (!queue.isEmpty()) { AvailableServiceRole item = queue.poll(); for (Dependency dependency : item.getDependencies()) { for (String serviceName : dependency.getServices()) { if (serviceName.equals(other.getDisplayName())) { return true; } try { queue.add(AvailableServiceRoleContainer.load(serviceName)); } catch (IOException e) { } } } } return false; } public static class Dependency { private List<String> services; private String configKey; private boolean required; public boolean isRequired() { return required; } public void setRequired(boolean required) { this.required = required; } public List<String> getServices() { return services; } public void setServices(List<String> services) { this.services = services; } public String getConfigKey() { return configKey; } public void setConfigKey(String configKey) { this.configKey = configKey; } public Dependency(AvailableConfiguration config) { String[] item = config.getName().split("_"); this.services = new ArrayList<String>(); for (int i = 0; i < item.length - 1; i++) { this.services.add(item[i].toUpperCase()); } this.configKey = config.getName(); this.required = config.isRequired(); } } }