package com.sequenceiq.cloudbreak.orchestrator.yarn.util; import static com.sequenceiq.cloudbreak.orchestrator.yarn.api.ComponentType.AMBARIAGENT; import static com.sequenceiq.cloudbreak.orchestrator.yarn.api.ComponentType.AMBARIDB; import static com.sequenceiq.cloudbreak.orchestrator.yarn.api.ComponentType.AMBARISERVER; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.sequenceiq.cloudbreak.orchestrator.exception.CloudbreakOrchestratorFailedException; import com.sequenceiq.cloudbreak.orchestrator.model.ContainerConstraint; import com.sequenceiq.cloudbreak.orchestrator.model.OrchestrationCredential; import com.sequenceiq.cloudbreak.orchestrator.yarn.api.ComponentType; @Service public final class ApplicationUtils { private static final String AMBARI_DB_PREFIX = "ambari_db"; private static final String AMBARI_SERVER_PREFIX = "ambari-server"; private static final String AMBARI_AGENT_PREFIX = "ambari-agent"; @Value("${cb.yarn.domain:}") private String yarnDomain; /** * Return the application name based on the container name in the constraint. * * This is less than ideal as each containerName follows a different pattern. * * ambari_db-<cluster name> -> return <cluster name>-ambaridb * ambari-server-<cluster name> -> return <cluster name>-ambariserver * ambari-agent%<cluster name>%<host group> -> return <cluster name>-<host group>-<componentNumber> * * @param constraint - ContainerConstraint used to create the application. * @param componentNumber - This number uniquely identifies the component with the application. * @return the application name to use. * @throws CloudbreakOrchestratorFailedException - if the ComponentType is unknown. */ public String getApplicationName(ContainerConstraint constraint, int componentNumber) throws CloudbreakOrchestratorFailedException { String containerName = constraint.getContainerName().getName(); switch (getComponentType(constraint)) { case AMBARIDB: return String.format("%s-%s", containerName.replace("ambari_db-", "").replaceAll("_", "-"), getComponentName(constraint, componentNumber)); case AMBARISERVER: return String.format("%s-%s", containerName.replace("ambari-server-", "").replaceAll("_", "-"), getComponentName(constraint, componentNumber)); case AMBARIAGENT: String[] containerNameParts = constraint.getContainerName().getName().split("%"); return String.format("%s-%s", containerNameParts[1].replace("_", "-"), getComponentName(constraint, componentNumber)); default: throw new CloudbreakOrchestratorFailedException("Unknown component type"); } } /** * Return the component name based on the component type and in the constraint. * * This is less than ideal as each containerName follows a different pattern. * * ambari_db-<cluster name> -> return ambaridb * ambari-server-<cluster name> -> return ambariserver * ambari-agent%<cluster name>%<host group> -> return <host group>-<componentNumber> * * Because Ambari Blueprints allow for hyphens, * * @param constraint - ContainerConstraint used to create the application. * @param componentNumber - This number uniquely identifies the component with the application. * @return the component name to use. * @throws CloudbreakOrchestratorFailedException - if the ComponentType is unknown. */ public String getComponentName(ContainerConstraint constraint, int componentNumber) throws CloudbreakOrchestratorFailedException { switch (getComponentType(constraint)) { case AMBARIDB: return "ambaridb"; case AMBARISERVER: return "ambariserver"; case AMBARIAGENT: String[] containerNameParts = constraint.getContainerName().getName().split("%"); String componentBaseName = containerNameParts[2].substring(0, containerNameParts[2].lastIndexOf("-")).replaceAll("[^a-zA-Z0-9 ]", ""); return String.format("%s-%s", componentBaseName, componentNumber); default: throw new CloudbreakOrchestratorFailedException("Unknown component type"); } } /** * Return the fully qualified hostname for the component. * * @param constraint - ContainerConstraint used to create the application. * @param cred - OrchestrationCredential associated with the application. * @param componentNumber - This number uniquely identifies the component with the application. * @return the fully qualified hostname for the component. */ public String getComponentHostName(ContainerConstraint constraint, OrchestrationCredential cred, int componentNumber) throws CloudbreakOrchestratorFailedException { String component = getComponentName(constraint, componentNumber); String application = getApplicationName(constraint, componentNumber); return String.format("%s.%s.%s", component, application, yarnDomain); } /** * Return the ComponentType based on the constraint container name. * * @param constraint - ContainerConstraint used to create the application. * @return - the ComponentType associated with the container name. */ public ComponentType getComponentType(ContainerConstraint constraint) throws CloudbreakOrchestratorFailedException { String componentName = constraint.getContainerName().getName(); if (componentName.startsWith(AMBARI_DB_PREFIX)) { return AMBARIDB; } else if (componentName.startsWith(AMBARI_SERVER_PREFIX)) { return AMBARISERVER; } else if (componentName.startsWith(AMBARI_AGENT_PREFIX)) { return AMBARIAGENT; } throw new CloudbreakOrchestratorFailedException("Unknown component type."); } }