/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.falcon.oozie; import org.apache.falcon.FalconException; import org.apache.falcon.Tag; import org.apache.falcon.entity.ClusterHelper; import org.apache.falcon.entity.EntityUtil; import org.apache.falcon.entity.ExternalId; import org.apache.falcon.entity.v0.Entity; import org.apache.falcon.entity.v0.cluster.Cluster; import org.apache.falcon.entity.v0.feed.Feed; import org.apache.falcon.messaging.EntityInstanceMessage.ARG; import org.apache.falcon.oozie.coordinator.CONFIGURATION; import org.apache.falcon.oozie.coordinator.CONFIGURATION.Property; import org.apache.falcon.oozie.coordinator.COORDINATORAPP; import org.apache.falcon.oozie.coordinator.ObjectFactory; import org.apache.falcon.oozie.feed.FeedReplicationCoordinatorBuilder; import org.apache.falcon.oozie.feed.FeedRetentionCoordinatorBuilder; import org.apache.falcon.oozie.process.ProcessExecutionCoordinatorBuilder; import org.apache.falcon.util.OozieUtils; import org.apache.falcon.util.StartupProperties; import org.apache.hadoop.fs.Path; import org.apache.oozie.client.OozieClient; import java.util.List; import java.util.Map.Entry; import java.util.Properties; /** * Base class for building oozie coordinator. * @param <T> */ public abstract class OozieCoordinatorBuilder<T extends Entity> extends OozieEntityBuilder<T> { protected static final String NOMINAL_TIME_EL = "${coord:formatTime(coord:nominalTime(), 'yyyy-MM-dd-HH-mm')}"; protected static final String ACTUAL_TIME_EL = "${coord:formatTime(coord:actualTime(), 'yyyy-MM-dd-HH-mm')}"; protected static final Long DEFAULT_BROKER_MSG_TTL = 3 * 24 * 60L; protected static final String MR_QUEUE_NAME = "queueName"; protected static final String MR_JOB_PRIORITY = "jobPriority"; protected static final String IGNORE = "IGNORE"; protected final Tag lifecycle; public OozieCoordinatorBuilder(T entity, Tag tag) { super(entity); this.lifecycle = tag; } public static final OozieCoordinatorBuilder get(Entity entity, Tag tag) { switch(entity.getEntityType()) { case FEED: switch (tag) { case RETENTION: return new FeedRetentionCoordinatorBuilder((Feed)entity); case REPLICATION: return new FeedReplicationCoordinatorBuilder((Feed)entity); default: throw new IllegalArgumentException("Unhandled type " + entity.getEntityType() + ", lifecycle " + tag); } case PROCESS: return new ProcessExecutionCoordinatorBuilder((org.apache.falcon.entity.v0.process.Process) entity); default: break; } throw new IllegalArgumentException("Unhandled type " + entity.getEntityType() + ", lifecycle " + tag); } protected Path getBuildPath(Path buildPath) { return new Path(buildPath, lifecycle.name()); } protected String getEntityName() { return EntityUtil.getWorkflowName(lifecycle, entity).toString(); } protected Path marshal(Cluster cluster, COORDINATORAPP coord, Path outPath) throws FalconException { return marshal(cluster, new ObjectFactory().createCoordinatorApp(coord), OozieUtils.COORD_JAXB_CONTEXT, new Path(outPath, "coordinator.xml")); } protected Properties createCoordDefaultConfiguration(Cluster cluster, String coordName) throws FalconException { Properties props = new Properties(); props.put(ARG.entityName.getPropName(), entity.getName()); props.put(ARG.nominalTime.getPropName(), NOMINAL_TIME_EL); props.put(ARG.timeStamp.getPropName(), ACTUAL_TIME_EL); props.put("userBrokerUrl", ClusterHelper.getMessageBrokerUrl(cluster)); props.put("userBrokerImplClass", ClusterHelper.getMessageBrokerImplClass(cluster)); String falconBrokerUrl = StartupProperties.get().getProperty(ARG.brokerUrl.getPropName(), "tcp://localhost:61616?daemon=true"); props.put(ARG.brokerUrl.getPropName(), falconBrokerUrl); String falconBrokerImplClass = StartupProperties.get().getProperty(ARG.brokerImplClass.getPropName(), ClusterHelper.DEFAULT_BROKER_IMPL_CLASS); props.put(ARG.brokerImplClass.getPropName(), falconBrokerImplClass); String jmsMessageTTL = StartupProperties.get().getProperty("broker.ttlInMins", DEFAULT_BROKER_MSG_TTL.toString()); props.put(ARG.brokerTTL.getPropName(), jmsMessageTTL); props.put(ARG.entityType.getPropName(), entity.getEntityType().name()); props.put("logDir", getLogDirectory(cluster)); props.put(OozieClient.EXTERNAL_ID, new ExternalId(entity.getName(), EntityUtil.getWorkflowNameTag(coordName, entity), "${coord:nominalTime()}").getId()); props.put("workflowEngineUrl", ClusterHelper.getOozieUrl(cluster)); if (EntityUtil.getLateProcess(entity) == null || EntityUtil.getLateProcess(entity).getLateInputs() == null || EntityUtil.getLateProcess(entity).getLateInputs().size() == 0) { props.put("shouldRecord", "false"); } else { props.put("shouldRecord", "true"); } props.put("entityName", entity.getName()); props.put("entityType", entity.getEntityType().name().toLowerCase()); props.put(ARG.cluster.getPropName(), cluster.getName()); props.put(MR_QUEUE_NAME, "default"); props.put(MR_JOB_PRIORITY, "NORMAL"); //props in entity override the set props. props.putAll(getEntityProperties(entity)); return props; } protected CONFIGURATION getConfig(Properties props) { CONFIGURATION conf = new CONFIGURATION(); for (Entry<Object, Object> prop : props.entrySet()) { Property confProp = new Property(); confProp.setName((String) prop.getKey()); confProp.setValue((String) prop.getValue()); conf.getProperty().add(confProp); } return conf; } public final Properties build(Cluster cluster, Path buildPath) throws FalconException { throw new IllegalStateException("Not implemented for coordinator!"); } public abstract List<Properties> buildCoords(Cluster cluster, Path buildPath) throws FalconException; protected COORDINATORAPP unmarshal(String template) throws FalconException { return unmarshal(template, OozieUtils.COORD_JAXB_CONTEXT, COORDINATORAPP.class); } }