/*
* 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.zookeeper;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.utils.EnsurePath;
import org.springframework.xd.dirt.module.store.ModuleMetadata;
/**
* Common paths and path utilities for XD components.
*
* @author Patrick Peralta
* @author David Turanski
*/
public class Paths {
/**
* Map of paths to {@link org.apache.curator.utils.EnsurePath} instances.
*/
private static final ConcurrentMap<String, EnsurePath> ensurePaths = new ConcurrentHashMap<String, EnsurePath>();
/**
* Namespace path (i.e. the top node in the hierarchy) for XD nodes.
*/
public static final String XD_NAMESPACE = "xd";
/**
* Name of admins (that could participate to become leader) node.
* Admin lock nodes are written as children of this node. This node
* is solely used from curator.
*/
public static final String ADMINELECTION = "adminelection";
/**
* Name of admins node. Containers are written as children of this node.
* Used to store admin metadata while curator election is handled under
* adminelection.
*/
public static final String ADMINS = "admins";
/**
* Name of containers node. Containers are written as children of this node.
*/
public static final String CONTAINERS = "containers";
/**
* Name of modules node. Module definitions are written as children of this node.
*/
public static final String MODULES = "modules";
/**
* Name of streams node. Streams are written as children of this node.
*/
public static final String STREAMS = "streams";
/**
* Name of jobs node. Jobs are written as children of this node.
*/
public static final String JOBS = "jobs";
/**
* Name of taps node. Channel names with active taps are written as children of this node.
*/
public static final String TAPS = "taps";
/**
* Name of deployments node. Deployments are written as children of this node.
*/
public static final String DEPLOYMENTS = "deployments";
/**
* Name of the deployment modules node that are allocated to containers.
* Allocated modules are written as children of this node.
*/
public static final String ALLOCATED = "allocated";
/**
* Name of metadata node. The data for this node contains {@link ModuleMetadata}.
*/
public static final String METADATA = "metadata";
/**
* Name of the module deployment requests node. Requested modules are written as children of this node.
*/
public static final String REQUESTED = "requested";
/**
* Name of status node. The data for this node contains status information.
*/
public static final String STATUS = "status";
/**
* Name of the queue node.
*/
public static final String QUEUE = "queue";
/**
* Name of the parent node for deployment request responses.
*/
public static final String RESPONSES = "responses";
/**
* Name of module deployments node. Module deployment requests for
* individual containers are written as children of this node.
*/
public static final String MODULE_DEPLOYMENTS = DEPLOYMENTS + '/' + MODULES;
/**
* Name of stream deployments node. Stream deployment requests are written
* as children of this node.
*/
public static final String STREAM_DEPLOYMENTS = DEPLOYMENTS + '/' + STREAMS;
/**
* Name of job deployments node. Job deployment requests are written
* as children of this node.
*/
public static final String JOB_DEPLOYMENTS = DEPLOYMENTS + '/' + JOBS;
/**
* Name of the stream deployment queue path.
*/
public static final String DEPLOYMENT_QUEUE = QUEUE + '/' + DEPLOYMENTS;
/**
* Strip path information from a string. For example, given an input of
* {@code /xd/path/location}, return {@code location}.
*
* @param path path string
*
* @return string with path stripped
*/
public static String stripPath(String path) {
int i = path.lastIndexOf('/');
return i > -1 ? path.substring(i + 1) : path;
}
/**
* Return a string with the provided path elements separated by a slash {@code /}.
* The leading slash is created if required.
*
* @param elements path elements
*
* @return the full path
*/
public static String build(String... elements) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < elements.length; i++) {
if (i == 0 && elements[i].charAt(0) != '/') {
builder.append('/');
}
builder.append(elements[i]);
if (i + 1 < elements.length) {
builder.append('/');
}
}
return builder.toString();
}
/**
* Ensure the existence of the given path.
*
* @param client curator client
* @param path path to create, if needed
*/
public static void ensurePath(CuratorFramework client, String path) {
EnsurePath ensurePath = ensurePaths.get(path);
if (ensurePath == null) {
ensurePaths.putIfAbsent(path, client.newNamespaceAwareEnsurePath(path));
ensurePath = ensurePaths.get(path);
}
try {
ensurePath.ensure(client.getZookeeperClient());
}
catch (Exception e) {
throw ZooKeeperUtils.wrapThrowable(e);
}
}
}