You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sm...@apache.org on 2017/12/06 03:14:03 UTC

[airavata-sandbox] 19/19: Adding async monitor component

This is an automated email from the ASF dual-hosted git repository.

smarru pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-sandbox.git

commit c38e09e9664f5d00ef784e33c153f1128790260a
Author: dimuthu.upeksha2@gmail.com <Di...@1234>
AuthorDate: Sun Dec 3 13:38:38 2017 +0530

    Adding async monitor component
---
 .../airavata/agents/core/AsyncCommandStatus.java   |  19 ++++
 .../airavata/agents/core/StatusPublisher.java      |   4 +-
 .../agents/thrift/handler/OperationHandler.java    |   8 +-
 .../thrift/operation/ThriftAgentOperation.java     |  23 +++--
 .../event/listener/service/ListenerService.java    |   2 +-
 .../tasks/async-command-monitor/pom.xml            | 113 +++++++++++++++++++++
 .../async/command/monitor/AsyncCommandMonitor.java | 111 ++++++++++++++++++++
 .../task/async/command/monitor/Participant.java    |  54 ++++++++++
 .../src/main/resources/application.properties      |   7 ++
 .../src/main/resources/log4j.properties            |   9 ++
 .../helix/task/async/command/AsyncCommandTask.java |   1 +
 .../airavata/helix/task/command/CommandTask.java   |   2 +-
 airavata-kubernetes/pom.xml                        |   1 +
 .../components/workflow/create/create.component.ts |   5 +-
 14 files changed, 339 insertions(+), 20 deletions(-)

diff --git a/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/AsyncCommandStatus.java b/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/AsyncCommandStatus.java
new file mode 100644
index 0000000..1176f3d
--- /dev/null
+++ b/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/AsyncCommandStatus.java
@@ -0,0 +1,19 @@
+package org.apache.airavata.agents.core;
+
+/**
+ * TODO: Class level comments please
+ *
+ * @author dimuthu
+ * @since 1.0.0-SNAPSHOT
+ */
+public enum AsyncCommandStatus {
+
+    PENDING,
+    RUNNING,
+    SUCCESS,
+    PAUSE,
+    WARNING,
+    ERROR,
+    CANCEL,
+    MANUAL_RECOVERY;
+}
diff --git a/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/StatusPublisher.java b/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/StatusPublisher.java
index 71af84e..c689d02 100644
--- a/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/StatusPublisher.java
+++ b/airavata-kubernetes/modules/agents/agent-core/src/main/java/org/apache/airavata/agents/core/StatusPublisher.java
@@ -24,9 +24,9 @@ public class StatusPublisher {
         this.initializeKafkaEventProducer();
     }
 
-    public void publishStatus(long callbackWorkflowId, String status, String message) {
+    public void publishStatus(long callbackWorkflowId, AsyncCommandStatus status, String message) {
         this.eventProducer.send(new ProducerRecord<String, String>(
-                this.topicName, String.join(",", callbackWorkflowId + "", status, message)));
+                this.topicName, String.join(",", callbackWorkflowId + "", status.name(), message)));
     }
 
     public void initializeKafkaEventProducer() {
diff --git a/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/handler/OperationHandler.java b/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/handler/OperationHandler.java
index c402a83..3dd4b09 100644
--- a/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/handler/OperationHandler.java
+++ b/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/handler/OperationHandler.java
@@ -5,6 +5,8 @@ import org.apache.airavata.agents.thrift.stubs.OperationException;
 import org.apache.airavata.agents.thrift.stubs.OperationService;
 import org.apache.thrift.TException;
 
+import static org.apache.airavata.agents.core.AsyncCommandStatus.*;
+
 /**
  * TODO: Class level comments please
  *
@@ -19,13 +21,13 @@ public class OperationHandler extends StatusPublisher implements OperationServic
 
     @Override
     public void executeCommand(String command, long callbackWorkflowId) throws OperationException, TException {
-        publishStatus(callbackWorkflowId, "PENDING", "Pending for execution");
-        publishStatus(callbackWorkflowId, "STARTED", "Starting command execution");
+        publishStatus(callbackWorkflowId, PENDING, "Pending for execution");
+        publishStatus(callbackWorkflowId, RUNNING, "Starting command execution");
         Runnable task = new Runnable() {
             @Override
             public void run() {
                 System.out.println("Executing command " + command);
-                publishStatus(callbackWorkflowId, "SUCCESS", "Command execution succeeded");
+                publishStatus(callbackWorkflowId, SUCCESS, "Command execution succeeded");
             }
         };
 
diff --git a/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/operation/ThriftAgentOperation.java b/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/operation/ThriftAgentOperation.java
index cb9010b..e46fea3 100644
--- a/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/operation/ThriftAgentOperation.java
+++ b/airavata-kubernetes/modules/agents/thrift-agent/src/main/java/org/apache/airavata/agents/thrift/operation/ThriftAgentOperation.java
@@ -22,22 +22,23 @@ public class ThriftAgentOperation extends AsyncOperation {
 
     public ThriftAgentOperation(ComputeResource computeResource) {
         super(computeResource);
-
-        try {
-            TTransport transport = new TSocket(computeResource.getHost(), 9090);
-            transport.open();
-            TProtocol protocol = new TBinaryProtocol(transport);
-            this.client = new OperationService.Client(protocol);
-
-        } catch (TTransportException e) {
-            e.printStackTrace();
-        }
     }
 
     @Override
     public void executeCommandAsync(String command, long callbackWorkflowId) {
         try {
-            client.executeCommand(command, callbackWorkflowId);
+            System.out.println("Submitting command");
+            try {
+                TTransport transport = new TSocket(getComputeResource().getHost(), 9090);
+                transport.open();
+                TProtocol protocol = new TBinaryProtocol(transport);
+                this.client = new OperationService.Client(protocol);
+                client.executeCommand(command, callbackWorkflowId);
+                System.out.println("Finished submitting");
+                transport.close();
+            } catch (TTransportException e) {
+                e.printStackTrace();
+            }
         } catch (TException e) {
             e.printStackTrace();
         }
diff --git a/airavata-kubernetes/modules/microservices/async-event-listener/src/main/java/org/apache/airavata/async/event/listener/service/ListenerService.java b/airavata-kubernetes/modules/microservices/async-event-listener/src/main/java/org/apache/airavata/async/event/listener/service/ListenerService.java
index 72f5309..896b6f9 100644
--- a/airavata-kubernetes/modules/microservices/async-event-listener/src/main/java/org/apache/airavata/async/event/listener/service/ListenerService.java
+++ b/airavata-kubernetes/modules/microservices/async-event-listener/src/main/java/org/apache/airavata/async/event/listener/service/ListenerService.java
@@ -30,6 +30,6 @@ public class ListenerService {
         Map<String, String> boostrapData = new HashMap<>();
         boostrapData.put("event", event);
         boostrapData.put("message", message);
-        this.restTemplate.postForObject(apiServerUrl + "/workflow/" + workflowId + "/launch", boostrapData, Long.class);
+        this.restTemplate.postForObject("http://" + apiServerUrl + "/workflow/" + workflowId + "/launch", boostrapData, Long.class);
     }
 }
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/pom.xml b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/pom.xml
new file mode 100644
index 0000000..7373733
--- /dev/null
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/pom.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>airavata-kubernetes</artifactId>
+        <groupId>org.apache.airavata</groupId>
+        <version>1.0-SNAPSHOT</version>
+        <relativePath>../../../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>async-command-monitor</artifactId>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>org.apache.airavata.helix.task.async.command.Participant</mainClass>
+                        </manifest>
+                    </archive>
+                    <descriptorRefs>
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
+                    </descriptorRefs>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <!-- Create a docker image that runs the executable jar-->
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>1.0.0</version>
+                <configuration>
+                    <imageName>${docker.image.prefix}/async-command-monitor</imageName>
+                    <baseImage>java:openjdk-8-jdk-alpine</baseImage>
+                    <exposes>
+                        <expose>8080</expose>
+                    </exposes>
+                    <entryPoint>["java","-jar","/${project.build.finalName}-jar-with-dependencies.jar"]</entryPoint>
+                    <resources>
+                        <resource>
+                            <targetPath>/</targetPath>
+                            <directory>${project.build.directory}</directory>
+                            <include>${project.build.finalName}-jar-with-dependencies.jar</include>
+                        </resource>
+                    </resources>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>helix-task-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.helix</groupId>
+            <artifactId>helix-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>api-resource</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>agent-core</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/AsyncCommandMonitor.java b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/AsyncCommandMonitor.java
new file mode 100644
index 0000000..095b40f
--- /dev/null
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/AsyncCommandMonitor.java
@@ -0,0 +1,111 @@
+package org.apache.airavata.task.async.command.monitor;
+
+import org.apache.airavata.agents.core.AsyncCommandStatus;
+import org.apache.airavata.helix.api.AbstractTask;
+import org.apache.airavata.helix.api.PropertyResolver;
+import org.apache.airavata.k8s.api.resources.task.TaskStatusResource;
+import org.apache.airavata.k8s.api.resources.task.type.TaskInputTypeResource;
+import org.apache.airavata.k8s.api.resources.task.type.TaskOutPortTypeResource;
+import org.apache.airavata.k8s.api.resources.task.type.TaskTypeResource;
+import org.apache.helix.task.TaskCallbackContext;
+import org.apache.helix.task.TaskResult;
+
+import java.util.Arrays;
+
+/**
+ * TODO: Class level comments please
+ *
+ * @author dimuthu
+ * @since 1.0.0-SNAPSHOT
+ */
+public class AsyncCommandMonitor extends AbstractTask {
+
+    public static final String NAME = "ASYNC_COMMAND_MONITOR";
+
+    private AsyncCommandStatus status;
+    private String message;
+
+    public AsyncCommandMonitor(TaskCallbackContext callbackContext, PropertyResolver propertyResolver) {
+        super(callbackContext, propertyResolver);
+    }
+
+    @Override
+    public void init() {
+        super.init();
+        this.status = AsyncCommandStatus.valueOf(getCallbackContext().getTaskConfig().getConfigMap().get("event"));
+        this.message = getCallbackContext().getTaskConfig().getConfigMap().get("message");
+    }
+
+    @Override
+    public TaskResult onRun() {
+        System.out.println("Received status " + this.status.name() + " with message " + this.message);
+        if (this.status != null) {
+            sendToOutPort(this.status.name());
+            publishTaskStatus(TaskStatusResource.State.COMPLETED, "Sending to out port " + this.status.name());
+            return new TaskResult(TaskResult.Status.COMPLETED, "Sending to out port " + this.status.name());
+
+        } else {
+            publishTaskStatus(TaskStatusResource.State.FAILED, "Unsupported status");
+            return new TaskResult(TaskResult.Status.FATAL_FAILED, "Unsupported status");
+        }
+    }
+
+    @Override
+    public void onCancel() {
+
+    }
+
+    public static TaskTypeResource getTaskType() {
+        TaskTypeResource taskTypeResource = new TaskTypeResource();
+        taskTypeResource.setName(NAME);
+        taskTypeResource.setIcon("assets/icons/ssh.png");
+        taskTypeResource.getInputTypes().addAll(
+                Arrays.asList(
+                        new TaskInputTypeResource()
+                                .setName(PARAMS.STATUS_KEY)
+                                .setType("String")
+                                .setDefaultValue("status"),
+                        new TaskInputTypeResource()
+                                .setName(PARAMS.MESSAGE_KEY)
+                                .setType("String")
+                                .setDefaultValue("message")
+                ));
+
+        taskTypeResource.getOutPorts().addAll(
+                Arrays.asList(
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.PENDING.name())
+                                .setOrder(0),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.RUNNING.name())
+                                .setOrder(1),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.SUCCESS.name())
+                                .setOrder(2),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.CANCEL.name())
+                                .setOrder(3),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.ERROR.name())
+                                .setOrder(4),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.PAUSE.name())
+                                .setOrder(5),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.WARNING.name())
+                                .setOrder(6),
+                        new TaskOutPortTypeResource()
+                                .setName(AsyncCommandStatus.MANUAL_RECOVERY.name())
+                                .setOrder(7)
+                )
+
+        );
+
+        return taskTypeResource;
+    }
+
+    public static final class PARAMS {
+        public static final String STATUS_KEY = "status-key";
+        public static final String MESSAGE_KEY = "message-key";
+    }
+}
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/Participant.java b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/Participant.java
new file mode 100644
index 0000000..ed4f0bd
--- /dev/null
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/java/org/apache/airavata/task/async/command/monitor/Participant.java
@@ -0,0 +1,54 @@
+package org.apache.airavata.task.async.command.monitor;
+
+import org.apache.airavata.helix.api.HelixParticipant;
+import org.apache.airavata.k8s.api.resources.task.type.TaskTypeResource;
+import org.apache.helix.task.Task;
+import org.apache.helix.task.TaskCallbackContext;
+import org.apache.helix.task.TaskFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TODO: Class level comments please
+ *
+ * @author dimuthu
+ * @since 1.0.0-SNAPSHOT
+ */
+public class Participant extends HelixParticipant {
+
+    public Participant(String propertyFile) throws IOException {
+        super(propertyFile);
+    }
+
+    @Override
+    public Map<String, TaskFactory> getTaskFactory() {
+        Map<String, TaskFactory> taskRegistry = new HashMap<String, TaskFactory>();
+
+        TaskFactory commandTaskFac = new TaskFactory() {
+            @Override
+            public Task createNewTask(TaskCallbackContext context) {
+                return new AsyncCommandMonitor(context, getPropertyResolver());
+            }
+        };
+
+        taskRegistry.put(AsyncCommandMonitor.NAME, commandTaskFac);
+
+        return taskRegistry;
+    }
+
+    @Override
+    public TaskTypeResource getTaskType() {
+        return AsyncCommandMonitor.getTaskType();
+    }
+
+    public static void main(String args[]) {
+        try {
+            HelixParticipant participant = new Participant("application.properties");
+            new Thread(participant).start();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/application.properties b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/application.properties
new file mode 100644
index 0000000..f7a613d
--- /dev/null
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/application.properties
@@ -0,0 +1,7 @@
+api.server.url=api-server.default.svc.cluster.local:8080
+zookeeper.connection.url=localhost:2199
+helix.cluster.name=AiravataDemoCluster
+participant.name=async-command-monitor-p1
+task.type.name=ASYNC_COMMAND_MONITOR
+kafka.bootstrap.url=localhost:9092
+event.topic=airavata-task-event
\ No newline at end of file
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/log4j.properties b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/log4j.properties
new file mode 100644
index 0000000..5e31e3c
--- /dev/null
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-monitor/src/main/resources/log4j.properties
@@ -0,0 +1,9 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
\ No newline at end of file
diff --git a/airavata-kubernetes/modules/microservices/tasks/async-command-task/src/main/java/org/apache/airavata/helix/task/async/command/AsyncCommandTask.java b/airavata-kubernetes/modules/microservices/tasks/async-command-task/src/main/java/org/apache/airavata/helix/task/async/command/AsyncCommandTask.java
index 5ece6f2..5108347 100644
--- a/airavata-kubernetes/modules/microservices/tasks/async-command-task/src/main/java/org/apache/airavata/helix/task/async/command/AsyncCommandTask.java
+++ b/airavata-kubernetes/modules/microservices/tasks/async-command-task/src/main/java/org/apache/airavata/helix/task/async/command/AsyncCommandTask.java
@@ -56,6 +56,7 @@ public class AsyncCommandTask extends AbstractTask {
             AsyncOperation operation = (AsyncOperation) Class.forName("org.apache.airavata.agents.thrift.operation.ThriftAgentOperation")
                     .getConstructor(ComputeResource.class).newInstance(this.computeResource);
             operation.executeCommandAsync(this.command, this.callBackWorkflowId);
+            publishTaskStatus(TaskStatusResource.State.COMPLETED, "Task completed");
             return new TaskResult(TaskResult.Status.COMPLETED, "Task completed");
         } catch (InstantiationException | IllegalAccessException |
                 InvocationTargetException | ClassNotFoundException | NoSuchMethodException | ClassCastException e) {
diff --git a/airavata-kubernetes/modules/microservices/tasks/command-task/src/main/java/org/apache/airavata/helix/task/command/CommandTask.java b/airavata-kubernetes/modules/microservices/tasks/command-task/src/main/java/org/apache/airavata/helix/task/command/CommandTask.java
index d5b8bda..f6b1b6a 100644
--- a/airavata-kubernetes/modules/microservices/tasks/command-task/src/main/java/org/apache/airavata/helix/task/command/CommandTask.java
+++ b/airavata-kubernetes/modules/microservices/tasks/command-task/src/main/java/org/apache/airavata/helix/task/command/CommandTask.java
@@ -56,7 +56,7 @@ public class CommandTask extends AbstractTask {
             String finalCommand = command + (arguments != null ? arguments : "") + stdOutSuffix;
 
             System.out.println("Executing command " + finalCommand);
-            Thread.sleep(200000);
+            Thread.sleep(2000);
             ExecutionResult executionResult = fetchComputeResourceOperation(computeResource).executeCommand(finalCommand);
 
             if (executionResult.getExitStatus() == 0) {
diff --git a/airavata-kubernetes/pom.xml b/airavata-kubernetes/pom.xml
index 9ca584f..5d8b118 100644
--- a/airavata-kubernetes/pom.xml
+++ b/airavata-kubernetes/pom.xml
@@ -45,6 +45,7 @@
         <module>modules/agents/thrift-agent</module>
         <module>modules/microservices/tasks/async-command-task</module>
         <module>modules/microservices/async-event-listener</module>
+        <module>modules/microservices/tasks/async-command-monitor</module>
     </modules>
 
     <dependencyManagement>
diff --git a/airavata-kubernetes/web-console/src/app/components/workflow/create/create.component.ts b/airavata-kubernetes/web-console/src/app/components/workflow/create/create.component.ts
index e286c19..a76ff90 100644
--- a/airavata-kubernetes/web-console/src/app/components/workflow/create/create.component.ts
+++ b/airavata-kubernetes/web-console/src/app/components/workflow/create/create.component.ts
@@ -376,8 +376,6 @@ export class WorkflowCreateComponent implements AfterViewInit {
         model.beginUpdate();
 
         try {
-          v1 = graph.insertVertex(parent, null, prototype.cloneNode(true), x, y, 80, 60);
-          v1.setConnectable(false);
 
           let inputs = [];
           let inputKeys = [];
@@ -395,6 +393,9 @@ export class WorkflowCreateComponent implements AfterViewInit {
             }
           }
 
+          v1 = graph.insertVertex(parent, null, prototype.cloneNode(true), x, y, 80, outputs.length*20 + 20);
+          v1.setConnectable(false);
+
           let inputDivision = 1 / (inputs.length + 1);
           let outputDivision = 1 / (outputs.length + 1);
 

-- 
To stop receiving notification emails like this one, please contact
"commits@airavata.apache.org" <co...@airavata.apache.org>.