Skip to content
Browse files

Support for optional input

  • Loading branch information...
1 parent 6543073 commit 82ec9292fedff590c01e2b30696b5edd0e41c576 Shwetha GS committed Oct 29, 2012
Showing with 152 additions and 57 deletions.
  1. +1 −0 client/src/main/resources/process-0.1.xsd
  2. +3 −3 common/src/main/java/org/apache/ivory/entity/EntityUtil.java
  3. +2 −2 common/src/main/java/org/apache/ivory/entity/parser/FeedEntityParser.java
  4. +1 −1 common/src/main/java/org/apache/ivory/entity/store/ConfigurationStore.java
  5. +12 −2 common/src/main/java/org/apache/ivory/service/ServiceInitializer.java
  6. +1 −0 common/src/main/java/org/apache/ivory/util/DeploymentUtil.java
  7. +1 −1 common/src/main/java/org/apache/ivory/util/ReflectionUtils.java
  8. +1 −0 common/src/test/java/org/apache/ivory/entity/parser/ProcessEntityParserTest.java
  9. +1 −1 feed/src/main/java/org/apache/ivory/converter/OozieFeedMapper.java
  10. +1 −1 oozie/pom.xml
  11. +1 −1 oozie/src/main/java/org/apache/ivory/workflow/OozieWorkflowBuilder.java
  12. +1 −1 oozie/src/main/java/org/apache/ivory/workflow/engine/OozieHouseKeepingService.java
  13. +1 −1 prism/src/main/java/org/apache/ivory/resource/AbstractEntityManager.java
  14. +39 −32 process/src/main/java/org/apache/ivory/converter/OozieProcessMapper.java
  15. +49 −1 process/src/main/java/org/apache/ivory/workflow/OozieProcessWorkflowBuilder.java
  16. +0 −1 webapp/src/test/java/org/apache/ivory/cli/IvoryCLITest.java
  17. +4 −2 webapp/src/test/java/org/apache/ivory/resource/AbstractTestBase.java
  18. +28 −5 webapp/src/test/java/org/apache/ivory/resource/EntityManagerJerseyTest.java
  19. +3 −0 webapp/src/test/resources/feed-template1.xml
  20. +2 −2 webapp/src/test/resources/process-template.xml
View
1 client/src/main/resources/process-0.1.xsd
@@ -248,6 +248,7 @@
<xs:attribute type="xs:string" name="start" use="required" />
<xs:attribute type="xs:string" name="end" use="required" />
<xs:attribute type="xs:string" name="partition" use="optional" />
+ <xs:attribute type="xs:boolean" name="optional" use="optional" default="false"/>
</xs:complexType>
<xs:complexType name="outputs">
View
6 common/src/main/java/org/apache/ivory/entity/EntityUtil.java
@@ -45,16 +45,16 @@
private static final long DAY_IN_MS = 86400000L;
private static final long MONTH_IN_MS = 2592000000L;
- public static Entity getEntity(EntityType type, String entityName) throws IvoryException {
+ public static <T extends Entity> T getEntity(EntityType type, String entityName) throws IvoryException {
ConfigurationStore configStore = ConfigurationStore.get();
- Entity entity = configStore.get(type, entityName);
+ T entity = configStore.get(type, entityName);
if (entity == null) {
throw new EntityNotRegisteredException(entityName + " (" + type + ") not found");
}
return entity;
}
- public static Entity getEntity(String type, String entityName) throws IvoryException {
+ public static <T extends Entity> T getEntity(String type, String entityName) throws IvoryException {
EntityType entityType;
try {
entityType = EntityType.valueOf(type.toUpperCase());
View
4 common/src/main/java/org/apache/ivory/entity/parser/FeedEntityParser.java
@@ -156,7 +156,7 @@ private void ensureValidityFor(Feed newFeed, Process process) throws IvoryExcept
private void validateFeedSourceCluster(Feed feed) throws ValidationException {
int i = 0;
for (Cluster cluster : feed.getClusters().getClusters()) {
- if (cluster.getType().equals(ClusterType.SOURCE)) {
+ if (cluster.getType() == ClusterType.SOURCE) {
i++;
}
}
@@ -245,7 +245,7 @@ private void validateClusterExpDefined(Cluster cl) throws IvoryException {
if(cl.getPartition() == null)
return;
- org.apache.ivory.entity.v0.cluster.Cluster cluster = (org.apache.ivory.entity.v0.cluster.Cluster) EntityUtil.getEntity(EntityType.CLUSTER, cl.getName());
+ org.apache.ivory.entity.v0.cluster.Cluster cluster = EntityUtil.getEntity(EntityType.CLUSTER, cl.getName());
String part = FeedHelper.normalizePartitionExpression(cl.getPartition());
if(FeedHelper.evaluateClusterExp(cluster, part).equals(part))
throw new ValidationException("Alteast one of the partition tags has to be a cluster expression for cluster " + cl.getName());
View
2 common/src/main/java/org/apache/ivory/entity/store/ConfigurationStore.java
@@ -229,7 +229,7 @@ public synchronized void initiateUpdate(Entity entity) throws IvoryException {
T entity = (T) entityMap.get(name);
if (entity == NULL) { // Object equality being checked
try {
- entity = restore(type, name);
+ entity = this.<T>restore(type, name);
} catch (IOException e) {
throw new StoreAccessException(e);
}
View
14 common/src/main/java/org/apache/ivory/service/ServiceInitializer.java
@@ -37,15 +37,25 @@ public void initialize() throws IvoryException {
IvoryService service = ReflectionUtils.getInstanceByClassName(serviceClassName);
services.register(service);
LOG.info("Initializing service : " + serviceClassName);
- service.init();
+ try {
+ service.init();
+ } catch(Throwable t) {
+ LOG.fatal("Failed to initialize service " + serviceClassName, t);
+ throw new IvoryException(t);
+ }
LOG.info("Service initialized : " + serviceClassName);
}
}
public void destroy() throws IvoryException {
for (IvoryService service : services) {
LOG.info("Destroying service : " + service.getClass().getName());
- service.destroy();
+ try {
+ service.destroy();
+ } catch(Throwable t) {
+ LOG.fatal("Failed to destroy service " + service.getClass().getName(), t);
+ throw new IvoryException(t);
+ }
LOG.info("Service destroyed : " + service.getClass().getName());
}
}
View
1 common/src/main/java/org/apache/ivory/util/DeploymentUtil.java
@@ -76,6 +76,7 @@ public static String getDefaultColo() {
}
public static Set<String> getDefaultColos() {
+ DEFAULT_ALL_COLOS.add(DEFAULT_COLO);
return DEFAULT_ALL_COLOS;
}
}
View
2 common/src/main/java/org/apache/ivory/util/ReflectionUtils.java
@@ -27,7 +27,7 @@
public static <T> T getInstance(String classKey) throws IvoryException {
String clazzName = StartupProperties.get().getProperty(classKey);
try {
- return getInstanceByClassName(clazzName);
+ return ReflectionUtils.<T>getInstanceByClassName(clazzName);
} catch (IvoryException e) {
throw new IvoryException("Unable to get instance for key: " + classKey, e);
}
View
1 common/src/test/java/org/apache/ivory/entity/parser/ProcessEntityParserTest.java
@@ -91,6 +91,7 @@ public void testParse() throws IvoryException, JAXBException {
Assert.assertEquals(process.getInputs().getInputs().get(0).getStart(), "today(0,0)");
Assert.assertEquals(process.getInputs().getInputs().get(0).getEnd(), "today(2,0)");
Assert.assertEquals(process.getInputs().getInputs().get(0).getPartition(), "*/US");
+ Assert.assertEquals(process.getInputs().getInputs().get(0).isOptional(), false);
Assert.assertEquals(process.getOutputs().getOutputs().get(0).getName(), "impOutput");
Assert.assertEquals(process.getOutputs().getOutputs().get(0).getFeed(), "imp-click-join1");
View
2 feed/src/main/java/org/apache/ivory/converter/OozieFeedMapper.java
@@ -146,7 +146,7 @@ private ACTION getRetentionWorkflowAction(Cluster cluster, Path wfPath, String w
createReplicatonWorkflow(targetCluster, basePath, coordName);
for (org.apache.ivory.entity.v0.feed.Cluster feedCluster : feed.getClusters().getClusters()) {
- if (feedCluster.getType().equals(ClusterType.SOURCE)) {
+ if (feedCluster.getType() == ClusterType.SOURCE) {
COORDINATORAPP coord = createAndGetCoord(feed,
(Cluster) ConfigurationStore.get().get(EntityType.CLUSTER, feedCluster.getName()), targetCluster,
bundlePath);
View
2 oozie/pom.xml
@@ -51,7 +51,7 @@
<dependency>
<groupId>org.apache.oozie</groupId>
<artifactId>oozie-client</artifactId>
- <version>3.1.5-SNAPSHOT</version>
+ <version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
View
2 oozie/src/main/java/org/apache/ivory/workflow/OozieWorkflowBuilder.java
@@ -43,7 +43,7 @@
protected Properties createAppProperties(String clusterName, Path bundlePath) throws IvoryException {
- Cluster cluster = (Cluster) EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
+ Cluster cluster = EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
Properties properties = new Properties();
if (cluster.getProperties() != null) {
addClusterProperties(properties, cluster.getProperties()
View
2 oozie/src/main/java/org/apache/ivory/workflow/engine/OozieHouseKeepingService.java
@@ -48,7 +48,7 @@ public void beforeDelete(Entity entity, String cluster) throws IvoryException {
@Override
public void afterDelete(Entity entity, String clusterName) throws IvoryException {
try {
- Cluster cluster = (Cluster) EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
+ Cluster cluster = EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
Path entityPath = new Path(ClusterHelper.getLocation(cluster, "staging"), EntityUtil.getStagingPath(entity)).getParent();
LOG.info("Deleting entity path " + entityPath + " on cluster " + clusterName);
View
2 prism/src/main/java/org/apache/ivory/resource/AbstractEntityManager.java
@@ -121,7 +121,7 @@ protected void checkColo(String colo) throws IvoryWebException {
Set<String> clusters = EntityUtil.getClustersDefined(entity);
Set<String> colos = new HashSet<String>();
for (String cluster : clusters) {
- Cluster clusterEntity = (Cluster) EntityUtil.getEntity(EntityType.CLUSTER, cluster);
+ Cluster clusterEntity = EntityUtil.getEntity(EntityType.CLUSTER, cluster);
colos.add(clusterEntity.getColo());
}
return colos;
View
71 process/src/main/java/org/apache/ivory/converter/OozieProcessMapper.java
@@ -143,27 +143,22 @@ public COORDINATORAPP createDefaultCoordinator(Cluster cluster, Path bundlePath)
List<String> inputFeeds = new ArrayList<String>();
List<String> inputPaths = new ArrayList<String>();
// inputs
- if (process.getInputs() != null) {
+ if (process.getInputs() != null) {
for (Input input : process.getInputs().getInputs()) {
- SYNCDATASET syncdataset = createDataSet(input.getFeed(), cluster, input.getName());
- if (coord.getDatasets() == null)
- coord.setDatasets(new DATASETS());
- coord.getDatasets().getDatasetOrAsyncDataset().add(syncdataset);
-
- DATAIN datain = new DATAIN();
- datain.setName(input.getName());
- datain.setDataset(input.getName());
- datain.setStartInstance(getELExpression(input.getStart()));
- datain.setEndInstance(getELExpression(input.getEnd()));
- if (coord.getInputEvents() == null)
- coord.setInputEvents(new INPUTEVENTS());
- coord.getInputEvents().getDataIn().add(datain);
-
- String inputExpr;
- if(input.getPartition() != null)
- inputExpr = getELExpression("dataIn('" + input.getName() + "', '" + input.getPartition() + "')");
- else
- inputExpr = getELExpression("coord:dataIn('" + input.getName() + "')");
+ if(!input.isOptional()) {
+ if (coord.getDatasets() == null)
+ coord.setDatasets(new DATASETS());
+ if (coord.getInputEvents() == null)
+ coord.setInputEvents(new INPUTEVENTS());
+
+ SYNCDATASET syncdataset = createDataSet(input.getFeed(), cluster, input.getName());
+ coord.getDatasets().getDatasetOrAsyncDataset().add(syncdataset);
+
+ DATAIN datain = createDataIn(input);
+ coord.getInputEvents().getDataIn().add(datain);
+ }
+
+ String inputExpr = getELExpression("dataIn('" + input.getName() + "', '" + input.getPartition() + "')");
props.put(input.getName(), inputExpr);
inputFeeds.add(input.getName());
inputPaths.add(inputExpr);
@@ -176,33 +171,28 @@ public COORDINATORAPP createDefaultCoordinator(Cluster cluster, Path bundlePath)
List<String> outputFeeds = new ArrayList<String>();
List<String> outputPaths = new ArrayList<String>();
if (process.getOutputs() != null) {
+ if (coord.getDatasets() == null)
+ coord.setDatasets(new DATASETS());
+ if (coord.getOutputEvents() == null)
+ coord.setOutputEvents(new OUTPUTEVENTS());
+
for (Output output : process.getOutputs().getOutputs()) {
SYNCDATASET syncdataset = createDataSet(output.getFeed(), cluster, output.getName());
- if (coord.getDatasets() == null)
- coord.setDatasets(new DATASETS());
coord.getDatasets().getDatasetOrAsyncDataset().add(syncdataset);
- DATAOUT dataout = new DATAOUT();
- dataout.setName(output.getName());
- dataout.setDataset(output.getName());
- dataout.setInstance(getELExpression(output.getInstance()));
- if (coord.getOutputEvents() == null)
- coord.setOutputEvents(new OUTPUTEVENTS());
+ DATAOUT dataout = createDataOut(output);
coord.getOutputEvents().getDataOut().add(dataout);
String outputExpr = "${coord:dataOut('" + output.getName() + "')}";
props.put(output.getName(), outputExpr);
outputFeeds.add(output.getName());
outputPaths.add(outputExpr);
-
}
}
// Output feed name and path for parent workflow
props.put(ARG.feedNames.getPropName(), join(outputFeeds.iterator(), ','));
props.put(ARG.feedInstancePaths.getPropName(), join(outputPaths.iterator(), ','));
- props.put("userWorkflowPath", process.getWorkflow().getPath());
-
// create parent wf
createWorkflow(cluster, DEFAULT_WF_TEMPLATE, coordName, coordPath);
@@ -218,6 +208,23 @@ public COORDINATORAPP createDefaultCoordinator(Cluster cluster, Path bundlePath)
return coord;
}
+ private DATAOUT createDataOut(Output output) {
+ DATAOUT dataout = new DATAOUT();
+ dataout.setName(output.getName());
+ dataout.setDataset(output.getName());
+ dataout.setInstance(getELExpression(output.getInstance()));
+ return dataout;
+ }
+
+ private DATAIN createDataIn(Input input) {
+ DATAIN datain = new DATAIN();
+ datain.setName(input.getName());
+ datain.setDataset(input.getName());
+ datain.setStartInstance(getELExpression(input.getStart()));
+ datain.setEndInstance(getELExpression(input.getEnd()));
+ return datain;
+ }
+
private String join(Iterator<String> itr, char sep) {
String joinedStr = StringUtils.join(itr, sep);
if(joinedStr.isEmpty())
@@ -226,7 +233,7 @@ private String join(Iterator<String> itr, char sep) {
}
private SYNCDATASET createDataSet(String feedName, Cluster cluster, String datasetName) throws IvoryException {
- Feed feed = (Feed) EntityUtil.getEntity(EntityType.FEED, feedName);
+ Feed feed = EntityUtil.getEntity(EntityType.FEED, feedName);
SYNCDATASET syncdataset = new SYNCDATASET();
syncdataset.setName(datasetName);
View
50 process/src/main/java/org/apache/ivory/workflow/OozieProcessWorkflowBuilder.java
@@ -32,10 +32,17 @@
import org.apache.ivory.converter.OozieProcessMapper;
import org.apache.ivory.entity.ClusterHelper;
import org.apache.ivory.entity.EntityUtil;
+import org.apache.ivory.entity.FeedHelper;
import org.apache.ivory.entity.ProcessHelper;
import org.apache.ivory.entity.v0.EntityType;
+import org.apache.ivory.entity.v0.Frequency.TimeUnit;
+import org.apache.ivory.entity.v0.SchemaHelper;
import org.apache.ivory.entity.v0.cluster.Cluster;
+import org.apache.ivory.entity.v0.feed.Feed;
+import org.apache.ivory.entity.v0.feed.LocationType;
+import org.apache.ivory.entity.v0.process.Input;
import org.apache.ivory.entity.v0.process.Process;
+import org.apache.oozie.client.CoordinatorJob.Timeunit;
import org.apache.oozie.client.OozieClient;
public class OozieProcessWorkflowBuilder extends OozieWorkflowBuilder<Process> {
@@ -47,17 +54,58 @@
for (String clusterName: clusters) {
org.apache.ivory.entity.v0.process.Cluster processCluster = ProcessHelper.getCluster(process, clusterName);
Properties properties = newWorkflowSchedule(process, processCluster.getValidity().getStart(), clusterName);
+ if (properties == null) continue;
+
+ //Add libpath
String libPath = process.getWorkflow().getLib();
if (!StringUtils.isEmpty(libPath)) {
String path = libPath.replace("${nameNode}", "");
properties.put(OozieClient.LIBPATH, "${nameNode}" + path);
}
- if (properties == null) continue;
+
+ if(process.getInputs() != null) {
+ for(Input in:process.getInputs().getInputs())
+ if(in.isOptional())
+ addOptionalInputProperties(properties, in, clusterName);
+ }
+
propertiesMap.put(clusterName, properties);
}
return propertiesMap;
}
+ private void addOptionalInputProperties(Properties properties, Input in, String clusterName) throws IvoryException {
+ Feed feed = EntityUtil.getEntity(EntityType.FEED, in.getFeed());
+ org.apache.ivory.entity.v0.feed.Cluster cluster = FeedHelper.getCluster(feed, clusterName);
+ String inName = in.getName();
+ properties.put(inName + ".frequency", String.valueOf(feed.getFrequency().getFrequency()));
+ properties.put(inName + ".freq_timeunit", mapToCoordTimeUnit(feed.getFrequency().getTimeUnit()).name());
+ properties.put(inName + ".timezone", feed.getTimezone().getID());
+ properties.put(inName + ".end_of_duration", Timeunit.NONE.name());
+ properties.put(inName + ".initial-instance", SchemaHelper.formatDateUTC(cluster.getValidity().getStart()));
+ properties.put(inName + ".done-flag", "notused");
+ properties.put(inName + ".uri-template", "${nameNode}" + FeedHelper.getLocation(feed, LocationType.DATA).getPath().replace('$', '%'));
+ properties.put(inName + ".start-instance", in.getStart());
+ properties.put(inName + ".end-instance", in.getEnd());
+ }
+
+ private Timeunit mapToCoordTimeUnit(TimeUnit tu) {
+ switch(tu) {
+ case days:
+ return Timeunit.DAY;
+
+ case hours:
+ return Timeunit.HOUR;
+
+ case minutes:
+ return Timeunit.MINUTE;
+
+ case months:
+ return Timeunit.MONTH;
+ }
+ throw new IllegalArgumentException("Unhandled time unit " + tu);
+ }
+
@Override
public Properties newWorkflowSchedule(Process process, Date startDate, String clusterName) throws IvoryException {
org.apache.ivory.entity.v0.process.Cluster processCluster = ProcessHelper.getCluster(process, clusterName);
View
1 webapp/src/test/java/org/apache/ivory/cli/IvoryCLITest.java
@@ -27,7 +27,6 @@
import junit.framework.Assert;
-import org.apache.ivory.IvoryException;
import org.apache.ivory.resource.AbstractTestBase;
import org.testng.annotations.Test;
View
6 webapp/src/test/java/org/apache/ivory/resource/AbstractTestBase.java
@@ -119,9 +119,9 @@ protected void waitForWorkflowStart(String entityName) throws Exception {
return;
System.out.println("Waiting for workflow to start");
- Thread.sleep(1000);
+ Thread.sleep(i * 1000);
}
- throw new Exception(entityName + " hasn't started in oozie");
+ throw new Exception("Workflow for " + entityName + " hasn't started in oozie");
}
protected void waitForProcessWFtoStart() throws Exception{
@@ -176,6 +176,8 @@ public void configure() throws Exception {
"application.services",
StartupProperties.get().getProperty("application.services")
.replace("org.apache.ivory.service.ProcessSubscriberService", ""));
+ String store = StartupProperties.get().getProperty("config.store.uri");
+ StartupProperties.get().setProperty("config.store.uri", store + System.currentTimeMillis());
if (new File("webapp/src/main/webapp").exists()) {
this.server = new EmbeddedServer(15000, "webapp/src/main/webapp");
} else if (new File("src/main/webapp").exists()) {
View
33 webapp/src/test/java/org/apache/ivory/resource/EntityManagerJerseyTest.java
@@ -43,6 +43,7 @@
import org.apache.ivory.entity.v0.feed.Feed;
import org.apache.ivory.entity.v0.process.Input;
import org.apache.ivory.entity.v0.process.Process;
+import org.apache.ivory.entity.v0.process.Property;
import org.apache.ivory.entity.v0.process.Validity;
import org.apache.ivory.util.BuildProperties;
import org.apache.ivory.util.DeploymentProperties;
@@ -60,16 +61,38 @@
* instance of webserver
*/
+ @Test
+ public void testOptionalInput() throws Exception {
+ Map<String, String> overlay = getUniqueOverlay();
+ String tmpFileName = overlayParametersOverTemplate(PROCESS_TEMPLATE, overlay);
+ Process process = (Process) EntityType.PROCESS.getUnmarshaller().unmarshal(new File(tmpFileName));
+
+ Input in1 = process.getInputs().getInputs().get(0);
+ Input in2 = new Input();
+ in2.setFeed(in1.getFeed());
+ in2.setName("input2");
+ in2.setOptional(true);
+ in2.setPartition(in1.getPartition());
+ in2.setStart("now(-1,0)");
+ in2.setEnd("now(0,0)");
+ process.getInputs().getInputs().add(in2);
+
+ File tmpFile = getTempFile();
+ EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
+ scheduleProcess(tmpFile.getAbsolutePath(), overlay);
+ waitForWorkflowStart(processName);
+ }
+
@Test
public void testProcessDeleteAndSchedule() throws Exception {
- //Submit process with no workflow so that bundle goes to failed state
+ //Submit process with invalid property so that coord submit fails and bundle goes to failed state
Map<String, String> overlay = getUniqueOverlay();
String tmpFileName = overlayParametersOverTemplate(PROCESS_TEMPLATE, overlay);
Process process = (Process) EntityType.PROCESS.getUnmarshaller().unmarshal(new File(tmpFileName));
- FileSystem fs = FileSystem.get(this.cluster.getConf());
- Path invalidPath = new Path("/ivory/test/invalidWorkflow");
- fs.mkdirs(invalidPath);
- process.getWorkflow().setPath(invalidPath.toString());
+ Property prop = new Property();
+ prop.setName("newProp");
+ prop.setValue("${formatTim()}");
+ process.getProperties().getProperties().add(prop);
File tmpFile = getTempFile();
EntityType.PROCESS.getMarshaller().marshal(process, tmpFile);
scheduleProcess(tmpFile.getAbsolutePath(), overlay);
View
3 webapp/src/test/resources/feed-template1.xml
@@ -17,6 +17,9 @@
~ limitations under the License.
-->
<feed description="clicks log" name="##inputFeedName##" xmlns="uri:ivory:feed:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <partitions>
+ <partition name="timestamp"/>
+ </partitions>
<groups>input</groups>
<frequency>hours(1)</frequency>
View
4 webapp/src/test/resources/process-template.xml
@@ -2,7 +2,7 @@
<process name="##processName##" xmlns="uri:ivory:process:0.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<clusters>
<cluster name="##cluster##">
- <validity end="2012-04-21T00:00Z" start="2012-04-20T00:00Z" />
+ <validity end="2012-04-21T00:00Z" start="2012-04-20T10:00Z" />
</cluster>
</clusters>
@@ -12,7 +12,7 @@
<timezone>UTC</timezone>
<inputs>
- <input end="today(0,0)" start="today(0,0)" feed="##inputFeedName##" name="input" />
+ <input end="today(0,0)" start="today(0,0)" feed="##inputFeedName##" name="input" partition="${fileTime}"/>
</inputs>
<outputs>
<output instance="now(0,0)" feed="##outputFeedName##" name="output" />

0 comments on commit 82ec929

Please sign in to comment.
Something went wrong with that request. Please try again.