/* * Copyright 2014 the original author or authors. * * 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 org.springframework.xd.dirt.core; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.springframework.util.Assert; import org.springframework.xd.dirt.zookeeper.Paths; /** * Builder object for paths under {@link Paths#REQUESTED}. {@code ModuleDeploymentRequestsPath} * represents all the requested modules upon deployment. * * @author Ilayaperumal Gopinathan */ public class ModuleDeploymentRequestsPath { /** * Index for {@link Paths#DEPLOYMENTS} in {@link #elements} array. */ private static final int DEPLOYMENTS = 0; /** * Index for {@code modules} in {@link #elements} array. */ private static final int MODULES = 1; /** * Index for {@link Paths#REQUESTED} node in {@link #elements} array. */ private static final int REQUESTED = 2; /** * Index for dot delimited module deployment description in {@link #elements} array. */ private static final int DEPLOYMENT_DESC = 3; /** * Index for deployment unit (stream/job) name in dot delimited deployment description. */ private static final int DEPLOYMENT_UNIT_NAME = 0; /** * Index for module type in dot delimited deployment description. */ private static final int MODULE_TYPE = 1; /** * Index for module label in dot delimited deployment description. */ private static final int MODULE_LABEL = 2; /** * Index for module sequence in dot delimited deployment description. */ private static final int MODULE_SEQUENCE = 3; /** * Array of path elements. */ private final String[] elements = new String[4]; /** * Array of module deployment description elements. */ private final String[] deploymentDesc = new String[4]; /** * Construct a {@code ModuleDeploymentRequestsPath}. * Use of this constructor means that a path will be created via {@link #build()}. */ public ModuleDeploymentRequestsPath() { elements[DEPLOYMENTS] = Paths.DEPLOYMENTS; elements[MODULES] = Paths.MODULES; elements[REQUESTED] = Paths.REQUESTED; } /** * Construct a {@code ModuleDeploymentRequestsPath}. * Use of this constructor means that an existing path will be provided and * this object will be used to extract the individual elements of the path. * Both full paths (including and excluding the {@link Paths#XD_NAMESPACE XD namespace prefix}) are supported. * * @param path stream path */ public ModuleDeploymentRequestsPath(String path) { Assert.hasText(path); String[] pathElements = path.split("\\/"); // offset is the element array that contains the 'deployments' // path element; the location may vary depending on whether // the path string includes the '/xd' namespace int offset = -1; for (int i = 0; i < pathElements.length; i++) { if (pathElements[i].equals(Paths.DEPLOYMENTS)) { offset = i; break; } } if (offset == -1) { throw new IllegalArgumentException(String.format( "Path '%s' does not include a '%s' element", path, Paths.DEPLOYMENTS)); } System.arraycopy(pathElements, offset, elements, 0, elements.length); Assert.noNullElements(elements); Assert.state(elements[DEPLOYMENTS].equals(Paths.DEPLOYMENTS)); Assert.state(elements[MODULES].equals(Paths.MODULES)); Assert.state(elements[REQUESTED].equals(Paths.REQUESTED)); if (elements[DEPLOYMENT_DESC] != null) { int deploymentDescCount = deploymentDesc.length; String[] deploymentElements = elements[DEPLOYMENT_DESC].split(" ")[0].split("\\."); Assert.state(deploymentElements.length == deploymentDescCount); System.arraycopy(deploymentElements, 0, deploymentDesc, 0, deploymentDescCount); } } /** * Return the string representation of the module instance that has the following dot limited * values. * <ul> * <li>Module Type</li> * <li>Module Label</li> * <li>Module Sequence</li> * </ul> * @return the string representation of the module instance. */ public String getModuleInstanceAsString() { return String.format("%s.%s.%s", this.getModuleType(), this.getModuleLabel(), this.getModuleSequence()); } /** * Return the deployment unit name. * * @return the deployment unit (stream/job) name */ public String getDeploymentUnitName() { return deploymentDesc[DEPLOYMENT_UNIT_NAME]; } /** * Set the deployment unit name. * * @param deploymentUnitName the deployment unit name * * @return this object */ public ModuleDeploymentRequestsPath setDeploymentUnitName(String deploymentUnitName) { deploymentDesc[DEPLOYMENT_UNIT_NAME] = deploymentUnitName; return this; } /** * Return the module type. * * @return module type */ public String getModuleType() { return deploymentDesc[MODULE_TYPE]; } /** * Set the module type. * * @param moduleType module type * * @return this object */ public ModuleDeploymentRequestsPath setModuleType(String moduleType) { deploymentDesc[MODULE_TYPE] = moduleType; return this; } /** * Return the module label. * * @return module label */ public String getModuleLabel() { return deploymentDesc[MODULE_LABEL]; } /** * Set the module label. * * @param moduleLabel module label * * @return this object */ public ModuleDeploymentRequestsPath setModuleLabel(String moduleLabel) { deploymentDesc[MODULE_LABEL] = moduleLabel; return this; } /** * Return the module sequence. * * @return module sequence */ public String getModuleSequence() { return deploymentDesc[MODULE_SEQUENCE]; } /** * Set the module sequence. * * @param moduleSequence module sequence * * @return this object */ public ModuleDeploymentRequestsPath setModuleSequence(String moduleSequence) { deploymentDesc[MODULE_SEQUENCE] = moduleSequence; return this; } /** * Build the path string using the field values. * * @return path string * * @see Paths#build */ public String build() { elements[DEPLOYMENT_DESC] = String.format("%s.%s.%s.%s", deploymentDesc[DEPLOYMENT_UNIT_NAME], deploymentDesc[MODULE_TYPE], deploymentDesc[MODULE_LABEL], deploymentDesc[MODULE_SEQUENCE]); return Paths.build(elements); } /** * {@inheritDoc} */ @Override public String toString() { return build(); } /** * Return all the modules for a given deployment unit name. * * @param requestedModulesPaths the collection of module deployment requests' paths * @param unitName the deployment unit (stream/job) name * @return the modules that correspond to the given deployment unit. */ public static List<ModuleDeploymentRequestsPath> getModulesForDeploymentUnit( Collection<ModuleDeploymentRequestsPath> requestedModulesPaths, String unitName) { List<ModuleDeploymentRequestsPath> pathsToReturn = new ArrayList<ModuleDeploymentRequestsPath>(); for (ModuleDeploymentRequestsPath path : requestedModulesPaths) { if (path.getDeploymentUnitName().equals(unitName)) { pathsToReturn.add(path); } } return pathsToReturn; } }