org.apache.oozie.service.UUIDService Maven / Gradle / Ivy
/**
* Copyright (c) 2010 Yahoo! 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. See accompanying LICENSE file.
*/
package org.apache.oozie.service;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.oozie.ErrorCode;
import org.apache.oozie.util.ParamChecker;
import org.apache.oozie.util.XLog;
/**
* The UUID service generates unique IDs.
*
* The configuration property {@link #CONF_GENERATOR} specifies the ID generation type, 'random' or 'counter'.
*
* For 'random' uses the JDK UUID.randomUUID() method.
*
* For 'counter' uses a counter postfixed wit the system start up time.
*/
public class UUIDService implements Service {
public static final String CONF_PREFIX = Service.CONF_PREFIX + "UUIDService.";
public static final String CONF_GENERATOR = CONF_PREFIX + "generator";
private String startTime;
private AtomicLong counter;
private String systemId;
/**
* Initialize the UUID service.
*
* @param services services instance.
* @throws ServiceException thrown if the UUID service could not be initialized.
*/
@Override
public void init(Services services) throws ServiceException {
String genType = services.getConf().get(CONF_GENERATOR, "counter").trim();
if (genType.equals("counter")) {
counter = new AtomicLong();
startTime = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date());
}
else {
if (!genType.equals("random")) {
throw new ServiceException(ErrorCode.E0120, genType);
}
}
systemId = services.getSystemId();
}
/**
* Destroy the UUID service.
*/
@Override
public void destroy() {
counter = null;
startTime = null;
}
/**
* Return the public interface for UUID service.
*
* @return {@link UUIDService}.
*/
@Override
public Class extends Service> getInterface() {
return UUIDService.class;
}
private String longPadding(long number) {
StringBuilder sb = new StringBuilder();
sb.append(number);
if (sb.length() <= 7) {
sb.insert(0, "0000000".substring(sb.length()));
}
return sb.toString();
}
/**
* Create a unique ID.
*
* @param type: Type of Id. Generally 'C' for Coordinator and 'W' for Workflow.
* @return unique ID.
*/
public String generateId(ApplicationType type) {
StringBuilder sb = new StringBuilder();
if (counter != null) {
sb.append(longPadding(counter.getAndIncrement())).append('-').append(startTime);
}
else {
sb.append(UUID.randomUUID().toString());
if (sb.length() > (37 - systemId.length())) {
sb.setLength(37 - systemId.length());
}
}
sb.append('-').append(systemId);
sb.append('-').append(type.getType());
// limitation due to current DB schema for action ID length (100)
if (sb.length() > 40) {
throw new RuntimeException(XLog.format("ID exceeds limit of 40 characters, [{0}]", sb));
}
return sb.toString();
}
/**
* Create a child ID.
*
* If the same child name is given the returned child ID is the same.
*
* @param id unique ID.
* @param childName child name.
* @return a child ID.
*/
public String generateChildId(String id, String childName) {
id = ParamChecker.notEmpty(id, "id") + "@" + ParamChecker.notEmpty(childName, "childName");
// limitation due to current DB schema for action ID length (100)
if (id.length() > 95) {
throw new RuntimeException(XLog.format("Child ID exceeds limit of 95 characters, [{0}]", id));
}
return id;
}
/**
* Return the ID from a child ID.
*
* @param childId child ID.
* @return ID of the child ID.
*/
public String getId(String childId) {
int index = ParamChecker.notEmpty(childId, "childId").indexOf("@");
if (index == -1) {
throw new IllegalArgumentException(XLog.format("invalid child id [{0}]", childId));
}
return childId.substring(0, index);
}
/**
* Return the child name from a child ID.
*
* @param childId child ID.
* @return child name.
*/
public String getChildName(String childId) {
int index = ParamChecker.notEmpty(childId, "childId").indexOf("@");
if (index == -1) {
throw new IllegalArgumentException(XLog.format("invalid child id [{0}]", childId));
}
return childId.substring(index + 1);
}
public enum ApplicationType {
WORKFLOW('W'), COORDINATOR('C'), BUNDLE('B');
private final char type;
private ApplicationType(char type) {
this.type = type;
}
public char getType() {
return type;
}
}
}