falcon-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pavanku...@apache.org
Subject [1/2] falcon git commit: FALCON-1802 EL Expressions support in Native Scheduler
Date Tue, 19 Apr 2016 06:34:58 GMT
Repository: falcon
Updated Branches:
  refs/heads/master 62393fe33 -> 7e4dc0d92


http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/scheduler/src/main/java/org/apache/falcon/workflow/engine/OozieDAGEngine.java
----------------------------------------------------------------------
diff --git a/scheduler/src/main/java/org/apache/falcon/workflow/engine/OozieDAGEngine.java
b/scheduler/src/main/java/org/apache/falcon/workflow/engine/OozieDAGEngine.java
index b5a3500..ff8bf37 100644
--- a/scheduler/src/main/java/org/apache/falcon/workflow/engine/OozieDAGEngine.java
+++ b/scheduler/src/main/java/org/apache/falcon/workflow/engine/OozieDAGEngine.java
@@ -26,6 +26,7 @@ import org.apache.falcon.entity.store.ConfigurationStore;
 import org.apache.falcon.entity.v0.Entity;
 import org.apache.falcon.entity.v0.EntityType;
 import org.apache.falcon.entity.v0.cluster.Cluster;
+import org.apache.falcon.entity.v0.process.Process;
 import org.apache.falcon.exception.DAGEngineException;
 import org.apache.falcon.execution.ExecutionInstance;
 import org.apache.falcon.hadoop.HadoopClientFactory;
@@ -43,8 +44,6 @@ import org.apache.oozie.client.OozieClientException;
 import org.apache.oozie.client.WorkflowAction;
 import org.apache.oozie.client.WorkflowJob;
 import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -95,10 +94,15 @@ public class OozieDAGEngine implements DAGEngine {
     }
 
     @Override
-    public String run(ExecutionInstance instance) throws DAGEngineException {
+    public String run(ExecutionInstance instance, Properties props) throws DAGEngineException
{
         try {
-            Properties properties = getRunProperties(instance);
+            OozieOrchestrationWorkflowBuilder builder =
+                    OozieOrchestrationWorkflowBuilder.get(instance.getEntity(), cluster,
Tag.DEFAULT,
+                            OozieOrchestrationWorkflowBuilder.Scheduler.NATIVE);
+            prepareEntityBuildPath(instance.getEntity());
             Path buildPath = EntityUtil.getLatestStagingPath(cluster, instance.getEntity());
+            builder.setNominalTime(instance.getInstanceTime());
+            Properties properties = builder.build(cluster, buildPath, props);
             switchUserTo(instance.getEntity().getACL().getOwner());
             properties.setProperty(OozieClient.USER_NAME, instance.getEntity().getACL().getOwner());
             properties.setProperty(OozieClient.APP_PATH, buildPath.toString());
@@ -141,7 +145,6 @@ public class OozieDAGEngine implements DAGEngine {
         switchUserTo(entity.getACL().getOwner());
         properties.setProperty(OozieClient.USER_NAME, entity.getACL().getOwner());
         properties.setProperty(OozieClient.APP_PATH, buildPath.toString());
-        properties.putAll(getDryRunProperties(entity));
         //Do dryrun before run as run is asynchronous
         LOG.info("Dry run with properties {}", properties);
         client.dryrun(properties);
@@ -161,42 +164,6 @@ public class OozieDAGEngine implements DAGEngine {
         }
     }
 
-    // TODO : To be implemented. Currently hardcoded for process
-    private Properties getRunProperties(ExecutionInstance instance) {
-        Properties props = new Properties();
-        DateTimeFormatter fmt = DateTimeFormat.forPattern(INSTANCE_FORMAT);
-        String nominalTime = fmt.print(instance.getInstanceTime());
-        props.put("nominalTime", nominalTime);
-        props.put("timeStamp", nominalTime);
-        props.put("feedNames", "NONE");
-        props.put("feedInstancePaths", "NONE");
-        props.put("falconInputFeeds", "NONE");
-        props.put("falconInPaths", "NONE");
-        props.put("feedNames", "NONE");
-        props.put("feedInstancePaths", "NONE");
-        props.put("userJMSNotificationEnabled", "true");
-        props.put("systemJMSNotificationEnabled", "false");
-        return props;
-    }
-
-    // TODO : To be implemented. Currently hardcoded for process
-    private Properties getDryRunProperties(Entity entity) {
-        Properties props = new Properties();
-        DateTimeFormatter fmt = DateTimeFormat.forPattern(INSTANCE_FORMAT);
-        String nominalTime = fmt.print(DateTime.now());
-        props.put("nominalTime", nominalTime);
-        props.put("timeStamp", nominalTime);
-        props.put("feedNames", "NONE");
-        props.put("feedInstancePaths", "NONE");
-        props.put("falconInputFeeds", "NONE");
-        props.put("falconInPaths", "NONE");
-        props.put("feedNames", "NONE");
-        props.put("feedInstancePaths", "NONE");
-        props.put("userJMSNotificationEnabled", "true");
-        props.put("systemJMSNotificationEnabled", "false");
-        return props;
-    }
-
     @Override
     public void suspend(ExecutionInstance instance) throws DAGEngineException {
         try {
@@ -212,6 +179,7 @@ public class OozieDAGEngine implements DAGEngine {
 
     @Override
     public void resume(ExecutionInstance instance) throws DAGEngineException {
+        switchUserTo(instance.getEntity().getACL().getOwner());
         try {
             client.resume(instance.getExternalID());
             assertStatus(instance.getExternalID(), Job.Status.PREP, Job.Status.RUNNING, Job.Status.SUCCEEDED,
@@ -237,6 +205,7 @@ public class OozieDAGEngine implements DAGEngine {
 
     @Override
     public void reRun(ExecutionInstance instance, Properties props, boolean isForced) throws
DAGEngineException {
+        switchUserTo(instance.getEntity().getACL().getOwner());
         String jobId = instance.getExternalID();
         try {
             WorkflowJob jobInfo = client.getJobInfo(jobId);
@@ -274,15 +243,28 @@ public class OozieDAGEngine implements DAGEngine {
     }
 
     @Override
-    public void submit(Entity entity) throws DAGEngineException {
+    public void submit(Entity entity, Properties props) throws DAGEngineException {
         try {
             // TODO : remove hardcoded Tag value when feed support is added.
             OozieOrchestrationWorkflowBuilder builder =
-                    OozieOrchestrationWorkflowBuilder.get(entity, cluster, Tag.DEFAULT);
+                    OozieOrchestrationWorkflowBuilder.get(entity, cluster, Tag.DEFAULT,
+                            OozieOrchestrationWorkflowBuilder.Scheduler.NATIVE);
             prepareEntityBuildPath(entity);
             Path buildPath = EntityUtil.getNewStagingPath(cluster, entity);
-            Properties properties = builder.build(cluster, buildPath);
-            dryRunInternal(properties, buildPath, entity);
+            org.apache.falcon.entity.v0.process.Process process = (Process) entity;
+            builder.setNominalTime(new DateTime(process.getClusters().getClusters().get(0).getValidity().getStart()));
+            Properties properties = builder.build(cluster, buildPath, props);
+            boolean skipDryRun = false;
+            if (props != null && !props.isEmpty() && props.containsKey(FalconWorkflowEngine.FALCON_SKIP_DRYRUN))
{
+                Boolean skipDryRunprop = Boolean
+                        .parseBoolean(props.getProperty(FalconWorkflowEngine.FALCON_SKIP_DRYRUN));
+                if (skipDryRunprop != null) {
+                    skipDryRun = skipDryRunprop;
+                }
+            }
+            if (!skipDryRun) {
+                dryRunInternal(properties, buildPath, entity);
+            }
         } catch (OozieClientException e) {
             LOG.error("Oozie client exception:", e);
             throw new DAGEngineException(e);
@@ -407,7 +389,8 @@ public class OozieDAGEngine implements DAGEngine {
         // TODO : remove hardcoded Tag value when feed support is added.
         try {
             OozieOrchestrationWorkflowBuilder builder =
-                    OozieOrchestrationWorkflowBuilder.get(entity, cluster, Tag.DEFAULT);
+                    OozieOrchestrationWorkflowBuilder.get(entity, cluster, Tag.DEFAULT,
+                            OozieOrchestrationWorkflowBuilder.Scheduler.NATIVE);
             if (!skipDryRun) {
                 Path buildPath = new Path("/tmp", "falcon" + entity.getName() + System.currentTimeMillis());
                 Properties props = builder.build(cluster, buildPath);

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/scheduler/src/test/java/org/apache/falcon/execution/FalconExecutionServiceTest.java
----------------------------------------------------------------------
diff --git a/scheduler/src/test/java/org/apache/falcon/execution/FalconExecutionServiceTest.java
b/scheduler/src/test/java/org/apache/falcon/execution/FalconExecutionServiceTest.java
index 437c5f5..89709dc 100644
--- a/scheduler/src/test/java/org/apache/falcon/execution/FalconExecutionServiceTest.java
+++ b/scheduler/src/test/java/org/apache/falcon/execution/FalconExecutionServiceTest.java
@@ -363,7 +363,7 @@ public class FalconExecutionServiceTest extends AbstractSchedulerTestBase
{
     }
 
     // Non-triggering event should not create an instance
-    @Test
+    @Test(enabled = false)
     public void testNonTriggeringEvents() throws Exception {
         storeEntity(EntityType.PROCESS, "summarize6");
         Process process = getStore().get(EntityType.PROCESS, "summarize6");
@@ -613,12 +613,13 @@ public class FalconExecutionServiceTest extends AbstractSchedulerTestBase
{
         }
     }
 
-    private Event createEvent(NotificationServicesRegistry.SERVICE type, ExecutionInstance
instance) {
+    private Event createEvent(NotificationServicesRegistry.SERVICE type,
+                              ExecutionInstance instance) throws IOException {
         ID id = new InstanceID(instance);
         switch (type) {
         case DATA:
             DataEvent dataEvent = new DataEvent(id,
-                    new ArrayList<Path>(Arrays.asList(new Path("/projects/falcon/clicks"))),
+                    new ArrayList<Path>(Arrays.asList(new Path("/projects/falcon/clicks/_SUCCESS"))),
                     DataEvent.STATUS.AVAILABLE);
             return dataEvent;
         case JOB_SCHEDULE:

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/scheduler/src/test/java/org/apache/falcon/execution/MockDAGEngine.java
----------------------------------------------------------------------
diff --git a/scheduler/src/test/java/org/apache/falcon/execution/MockDAGEngine.java b/scheduler/src/test/java/org/apache/falcon/execution/MockDAGEngine.java
index 245258b..1d82a15 100644
--- a/scheduler/src/test/java/org/apache/falcon/execution/MockDAGEngine.java
+++ b/scheduler/src/test/java/org/apache/falcon/execution/MockDAGEngine.java
@@ -41,7 +41,7 @@ public class MockDAGEngine implements DAGEngine {
     }
 
     @Override
-    public String run(ExecutionInstance instance) throws DAGEngineException {
+    public String run(ExecutionInstance instance, Properties props) throws DAGEngineException
{
         if (failInstances.contains(instance)) {
             throw new DAGEngineException("Mock failure.");
         }
@@ -93,7 +93,7 @@ public class MockDAGEngine implements DAGEngine {
     }
 
     @Override
-    public void submit(Entity entity) throws DAGEngineException {
+    public void submit(Entity entity, Properties props) throws DAGEngineException {
 
     }
 

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/scheduler/src/test/resources/runtime.properties
----------------------------------------------------------------------
diff --git a/scheduler/src/test/resources/runtime.properties b/scheduler/src/test/resources/runtime.properties
new file mode 100644
index 0000000..d3260dc
--- /dev/null
+++ b/scheduler/src/test/resources/runtime.properties
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+
+*.domain=debug
+
+*.falcon.scheduler.minutely.process.polling.frequency.millis=1000
+*.falcon.scheduler.hourly.process.polling.frequency.millis=1000
+*.falcon.scheduler.daily.process.polling.frequency.millis=1000
+*.falcon.scheduler.monthly.process.polling.frequency.millis=1000

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/src/conf/runtime.properties
----------------------------------------------------------------------
diff --git a/src/conf/runtime.properties b/src/conf/runtime.properties
index 2fb148b..013ac18 100644
--- a/src/conf/runtime.properties
+++ b/src/conf/runtime.properties
@@ -75,3 +75,14 @@ falcon.current.colo=local
 *.falcon.service.ProxyUserService.proxyuser.#USER#.groups=*
 
 ######### Proxyuser Configuration End #########
+
+######### Scheduler Configuration Start #######
+## Polling frequencies for processes based on frequency.
+#*.falcon.scheduler.minutely.process.polling.frequency.millis=
+#*.falcon.scheduler.hourly.process.polling.frequency.millis=
+#*.falcon.scheduler.daily.process.polling.frequency.millis=
+#*.falcon.scheduler.monthly.process.polling.frequency.millis=
+######### Scheduler Configuration End #######
+
+### Timeout factor for processes ###
+instance.timeout.factor=5

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
----------------------------------------------------------------------
diff --git a/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java b/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
index 70e1de9..fab794c 100644
--- a/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
+++ b/unit/src/test/java/org/apache/falcon/unit/FalconUnitTestBase.java
@@ -342,7 +342,7 @@ public class FalconUnitTestBase {
                     LOG.info("Waiting up to [{}] msec", waiting);
                     lastEcho = System.currentTimeMillis();
                 }
-                Thread.sleep(5000);
+                Thread.sleep(7000);
             }
             if (!predicate.evaluate()) {
                 LOG.info("Waiting timed out after [{}] msec", timeout);

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/webapp/src/test/java/org/apache/falcon/resource/AbstractSchedulerManagerJerseyIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/AbstractSchedulerManagerJerseyIT.java
b/webapp/src/test/java/org/apache/falcon/resource/AbstractSchedulerManagerJerseyIT.java
index 1bd4f45..c5425b2 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/AbstractSchedulerManagerJerseyIT.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/AbstractSchedulerManagerJerseyIT.java
@@ -57,6 +57,7 @@ public class AbstractSchedulerManagerJerseyIT extends FalconUnitTestBase
{
     private static final String IT_RUN_MODE = "it.run.mode";
 
     public static final String PROCESS_TEMPLATE = "/local-process-noinputs-template.xml";
+    public static final String PROCESS_TEMPLATE_NOLATE_DATA = "/process-nolatedata-template.xml";
     public static final String PROCESS_NAME = "processName";
     protected static final String START_INSTANCE = "2012-04-20T00:00Z";
     private static FalconJPAService falconJPAService = FalconJPAService.get();
@@ -107,12 +108,14 @@ public class AbstractSchedulerManagerJerseyIT extends FalconUnitTestBase
{
     }
 
     protected void setupProcessExecution(UnitTestContext context,
-                                         Map<String, String> overlay, int numInstances)
throws Exception {
+                                         Map<String, String> overlay, int numInstances,
+                                         String processTemplate) throws Exception {
         String colo = overlay.get(COLO);
         String cluster = overlay.get(CLUSTER);
         submitCluster(colo, cluster, null);
+        submitFeeds(overlay);
         context.prepare();
-        submitProcess(overlay);
+        submitProcess(processTemplate, overlay);
 
         String processName = overlay.get(PROCESS_NAME);
         scheduleProcess(processName, cluster, START_INSTANCE, numInstances);

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/webapp/src/test/java/org/apache/falcon/resource/InstanceSchedulerManagerJerseyIT.java
----------------------------------------------------------------------
diff --git a/webapp/src/test/java/org/apache/falcon/resource/InstanceSchedulerManagerJerseyIT.java
b/webapp/src/test/java/org/apache/falcon/resource/InstanceSchedulerManagerJerseyIT.java
index 28a8fa9..6d6d40b 100644
--- a/webapp/src/test/java/org/apache/falcon/resource/InstanceSchedulerManagerJerseyIT.java
+++ b/webapp/src/test/java/org/apache/falcon/resource/InstanceSchedulerManagerJerseyIT.java
@@ -48,8 +48,9 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         String cluster = overlay.get(CLUSTER);
 
         submitCluster(colo, cluster, null);
+        submitFeeds(overlay);
         context.prepare(HELLO_WORLD_WORKFLOW);
-        submitProcess(overlay);
+        submitProcess(PROCESS_TEMPLATE_NOLATE_DATA, overlay);
 
         String processName = overlay.get(PROCESS_NAME);
         scheduleProcess(processName, cluster, START_INSTANCE, 1);
@@ -68,7 +69,7 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         UnitTestContext context = new UnitTestContext();
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        setupProcessExecution(context, overlay, 1);
+        setupProcessExecution(context, overlay, 1, PROCESS_TEMPLATE);
 
         String processName = overlay.get(PROCESS_NAME);
         String colo = overlay.get(COLO);
@@ -102,7 +103,7 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         UnitTestContext context = new UnitTestContext();
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        setupProcessExecution(context, overlay, 1);
+        setupProcessExecution(context, overlay, 1, PROCESS_TEMPLATE_NOLATE_DATA);
 
         String processName = overlay.get(PROCESS_NAME);
         String colo = overlay.get(COLO);
@@ -132,7 +133,7 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         UnitTestContext context = new UnitTestContext();
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        setupProcessExecution(context, overlay, 4);
+        setupProcessExecution(context, overlay, 4, PROCESS_TEMPLATE);
 
         String processName = overlay.get(PROCESS_NAME);
         String colo = overlay.get(COLO);
@@ -153,7 +154,7 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         UnitTestContext context = new UnitTestContext();
         Map<String, String> overlay = context.getUniqueOverlay();
 
-        setupProcessExecution(context, overlay, 3);
+        setupProcessExecution(context, overlay, 3, PROCESS_TEMPLATE);
 
         String processName = overlay.get(PROCESS_NAME);
         String colo = overlay.get(COLO);
@@ -171,4 +172,28 @@ public class InstanceSchedulerManagerJerseyIT extends AbstractSchedulerManagerJe
         Assert.assertEquals(result.getInstancesSummary()[0].getSummaryMap().get("RUNNING").longValue(),
2L);
         Assert.assertEquals(result.getInstancesSummary()[0].getSummaryMap().get("READY").longValue(),
1L);
     }
+
+    @Test
+    public void testProcessWithInputs() throws Exception {
+        UnitTestContext context = new UnitTestContext();
+        Map<String, String> overlay = context.getUniqueOverlay();
+        String colo = overlay.get(COLO);
+        String cluster = overlay.get(CLUSTER);
+
+        submitCluster(colo, cluster, null);
+        submitFeeds(overlay);
+        context.prepare(HELLO_WORLD_WORKFLOW);
+
+        submitProcess(PROCESS_TEMPLATE_NOLATE_DATA, overlay);
+
+        String processName = overlay.get(PROCESS_NAME);
+        scheduleProcess(processName, cluster, START_INSTANCE, 1);
+
+        waitForStatus(EntityType.PROCESS.toString(), processName,
+                START_INSTANCE, InstancesResult.WorkflowStatus.SUCCEEDED);
+
+        InstancesResult.WorkflowStatus status = getClient().getInstanceStatus(EntityType.PROCESS.name(),
+                processName, START_INSTANCE);
+        Assert.assertEquals(status, InstancesResult.WorkflowStatus.SUCCEEDED);
+    }
 }

http://git-wip-us.apache.org/repos/asf/falcon/blob/7e4dc0d9/webapp/src/test/resources/process-nolatedata-template.xml
----------------------------------------------------------------------
diff --git a/webapp/src/test/resources/process-nolatedata-template.xml b/webapp/src/test/resources/process-nolatedata-template.xml
new file mode 100644
index 0000000..4498a22
--- /dev/null
+++ b/webapp/src/test/resources/process-nolatedata-template.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  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.
+  -->
+
+<process name="##processName##" xmlns="uri:falcon:process:0.1">
+    <tags>consumer=consumer@xyz.com, owner=producer@xyz.com, department=forecasting</tags>
+    <pipelines>testPipeline,dataReplicationPipeline</pipelines>
+    <clusters>
+        <cluster name="##src.cluster.name##">
+            <validity end="2012-04-20T01:00Z" start="2012-04-20T00:00Z"/>
+        </cluster>
+    </clusters>
+
+    <parallel>1</parallel>
+    <order>FIFO</order>
+    <frequency>days(1)</frequency>
+    <timezone>UTC</timezone>
+
+    <inputs>
+        <input end="today(0,0)" start="today(0,0)" feed="##inputFeedName##" name="input"
partition="${fileTime}"/>
+        <input name="input1" feed="##inputFeedName##" end="today(0,1)" start="today(0,0)"/>
+    </inputs>
+    <outputs>
+        <output instance="now(0,0)" feed="##outputFeedName##" name="output"/>
+    </outputs>
+    <properties>
+        <property name="fileTime" value="/projects/localdc/${formatTime(dateOffset(instanceTime(),
1, 'DAY'), 'yyyy-MMM-dd')}"/>
+        <property name="userName" value="${user()}"/>
+        <property name="baseTime" value="${today(0,0)}"/>
+        <property name="sundayThisWeek" value="${currentWeek('SUN', 0, 0)}"/>
+        <property name="tempprop" value="tempprop"/>
+    </properties>
+    <workflow engine="oozie" path="##workflow.path##" lib="##workflow.lib.path##"/>
+    <retry policy="periodic" delay="minutes(10)" attempts="3"/>
+</process>


Mime
View raw message