You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sh...@apache.org on 2014/11/07 01:11:19 UTC

[04/23] airavata git commit: re-arrange server and clint code to create seperate distributions. AIRAVATA-1471

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/cpi/orchestrator_cpi_serviceConstants.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/cpi/orchestrator_cpi_serviceConstants.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/cpi/orchestrator_cpi_serviceConstants.java
deleted file mode 100644
index 9f62eeb..0000000
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/cpi/orchestrator_cpi_serviceConstants.java
+++ /dev/null
@@ -1,55 +0,0 @@
-    /*
-     * 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.
-     */
-/**
- * Autogenerated by Thrift Compiler (0.9.1)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- *  @generated
- */
-package org.apache.airavata.orchestrator.cpi;
-
-import org.apache.thrift.scheme.IScheme;
-import org.apache.thrift.scheme.SchemeFactory;
-import org.apache.thrift.scheme.StandardScheme;
-
-import org.apache.thrift.scheme.TupleScheme;
-import org.apache.thrift.protocol.TTupleProtocol;
-import org.apache.thrift.protocol.TProtocolException;
-import org.apache.thrift.EncodingUtils;
-import org.apache.thrift.TException;
-import org.apache.thrift.async.AsyncMethodCallback;
-import org.apache.thrift.server.AbstractNonblockingServer.*;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class orchestrator_cpi_serviceConstants {
-
-  public static final String ORCHESTRATOR_CPI_VERSION = "0.12.0";
-
-}

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
index 0139fad..de293e4 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/server/OrchestratorServerHandler.java
@@ -26,30 +26,44 @@ import org.airavata.appcatalog.cpi.AppCatalogException;
 import org.airavata.appcatalog.cpi.ComputeResource;
 import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
 import org.apache.aiaravata.application.catalog.data.resources.AbstractResource;
+import org.apache.airavata.common.exception.AiravataException;
 import org.apache.airavata.common.exception.ApplicationSettingsException;
 import org.apache.airavata.common.logger.AiravataLogger;
 import org.apache.airavata.common.logger.AiravataLoggerFactory;
+import org.apache.airavata.common.utils.AiravataUtils;
 import org.apache.airavata.common.utils.AiravataZKUtils;
 import org.apache.airavata.common.utils.Constants;
 import org.apache.airavata.common.utils.ServerSettings;
 import org.apache.airavata.gfac.core.scheduler.HostScheduler;
 import org.apache.airavata.gfac.core.utils.GFacUtils;
+import org.apache.airavata.messaging.core.MessageContext;
+import org.apache.airavata.messaging.core.Publisher;
+import org.apache.airavata.messaging.core.PublisherFactory;
 import org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription;
 import org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription;
 import org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription;
 import org.apache.airavata.model.error.LaunchValidationException;
+import org.apache.airavata.model.messaging.event.ExperimentStatusChangeEvent;
+import org.apache.airavata.model.messaging.event.MessageType;
+import org.apache.airavata.model.util.ExecutionType;
 import org.apache.airavata.model.workspace.experiment.*;
 import org.apache.airavata.orchestrator.core.exception.OrchestratorException;
 import org.apache.airavata.orchestrator.cpi.OrchestratorService;
+import org.apache.airavata.orchestrator.cpi.OrchestratorService.Client;
 import org.apache.airavata.orchestrator.cpi.impl.SimpleOrchestratorImpl;
 import org.apache.airavata.orchestrator.cpi.orchestrator_cpi_serviceConstants;
 import org.apache.airavata.orchestrator.util.OrchestratorRecoveryHandler;
+import org.apache.airavata.orchestrator.util.OrchestratorServerThreadPoolExecutor;
 import org.apache.airavata.persistance.registry.jpa.impl.RegistryFactory;
 import org.apache.airavata.registry.cpi.Registry;
 import org.apache.airavata.registry.cpi.RegistryException;
 import org.apache.airavata.registry.cpi.RegistryModelType;
 import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.TaskDetailConstants;
 import org.apache.airavata.registry.cpi.utils.Constants.FieldConstants.WorkflowNodeConstants;
+import org.apache.airavata.workflow.engine.WorkflowEngine;
+import org.apache.airavata.workflow.engine.WorkflowEngineException;
+import org.apache.airavata.workflow.engine.WorkflowEngineFactory;
+import org.apache.airavata.orchestrator.util.DataModelUtils;
 import org.apache.thrift.TException;
 import org.apache.zookeeper.*;
 import org.apache.zookeeper.data.Stat;
@@ -73,6 +87,7 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
 
 	private String airavataUserName;
 	private String gatewayName;
+	private Publisher publisher;
 
 	/**
 	 * Query orchestrator server to fetch the CPI version
@@ -85,6 +100,9 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
 	public OrchestratorServerHandler() {
 		// registering with zk
 		try {
+			if (ServerSettings.isRabbitMqPublishEnabled()) {
+	                publisher = PublisherFactory.createPublisher();
+	        }
 			String zkhostPort = AiravataZKUtils.getZKhostPort();
 			String airavataServerHostPort = ServerSettings
 					.getSetting(Constants.ORCHESTRATOR_SERVER_HOST)
@@ -119,6 +137,8 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
 			}
 		} catch (ApplicationSettingsException e) {
 			e.printStackTrace();
+		}catch (AiravataException e) {
+			e.printStackTrace();
 		}
 		// orchestrator init
 		try {
@@ -160,7 +180,7 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
 	 * 
 	 * @param experimentId
 	 */
-	public boolean launchExperiment(String experimentId) throws TException {
+	public boolean launchExperiment(String experimentId, String token) throws TException {
         Experiment experiment = null; // this will inside the bottom catch statement
         try {
             experiment = (Experiment) registry.get(
@@ -169,59 +189,26 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
                 log.errorId(experimentId, "Error retrieving the Experiment by the given experimentID: {} ", experimentId);
                 return false;
             }
-            List<String> ids = registry.getIds(
-					RegistryModelType.WORKFLOW_NODE_DETAIL,
-					WorkflowNodeConstants.EXPERIMENT_ID, experimentId);
-            for (String workflowNodeId : ids) {
-                WorkflowNodeDetails workflowNodeDetail = (WorkflowNodeDetails) registry
-						.get(RegistryModelType.WORKFLOW_NODE_DETAIL,
-								workflowNodeId);
-                List<Object> taskDetailList = registry.get(
-						RegistryModelType.TASK_DETAIL,
-						TaskDetailConstants.NODE_ID, workflowNodeId);
-                for (Object o : taskDetailList) {
-                    TaskDetails taskID = (TaskDetails) o;
-                    // iterate through all the generated tasks and performs the
-                    // job submisssion+monitoring
-					ExperimentStatus status = new ExperimentStatus();
-					status.setExperimentState(ExperimentState.LAUNCHED);
-					status.setTimeOfStateChange(Calendar.getInstance()
-							.getTimeInMillis());
-					experiment.setExperimentStatus(status);
-					registry.update(RegistryModelType.EXPERIMENT, experiment,
-							experimentId);
-					// launching the experiment
-					orchestrator.launchExperiment(experiment,
-							workflowNodeDetail, taskID,null);
-				}
-			}
-
-		} catch (Exception e) {
-			// Here we really do not have to do much because only potential
-			// failure can happen
-			// is in gfac, if there are errors in gfac, it will handle the
-			// experiment/task/job statuses
-			// We might get failures in registry access before submitting the
-			// jobs to gfac, in that case we
-			// leave the status of these as created.
-			ExperimentStatus status = new ExperimentStatus();
-			status.setExperimentState(ExperimentState.FAILED);
-			status.setTimeOfStateChange(Calendar.getInstance()
-					.getTimeInMillis());
-			experiment.setExperimentStatus(status);
-			try {
-				registry.update(RegistryModelType.EXPERIMENT, experiment,
-						experimentId);
-            } catch (RegistryException e1) {
-                log.errorId(experimentId, "Couldn't update the status {} of the experiment {}.",
-                        ExperimentState.FAILED.toString(), experimentId);
-				throw new TException(e);
-			}
-            log.errorId(experimentId, "Error while launching experiment {}.", experimentId);
-            throw new TException(e);
-		}
-        log.infoId(experimentId, "Successfully launched experiment {}.", experimentId);
-		return true;
+            ExecutionType executionType = DataModelUtils.getExecutionType(experiment);
+            synchronized (this) {
+      		if (executionType==ExecutionType.SINGLE_APP) {
+                  //its an single application execution experiment
+                  log.debugId(experimentId, "Launching single application experiment {}.", experimentId);
+                  OrchestratorServerThreadPoolExecutor.getFixedThreadPool().execute(new SingleAppExperimentRunner(experimentId, token));
+            } 
+      		else if (executionType == ExecutionType.WORKFLOW){
+  					//its a workflow execution experiment
+                  log.debugId(experimentId, "Launching workflow experiment {}.", experimentId);
+  				  launchWorkflowExperiment(experimentId, token);
+  	          } else {
+                  log.errorId(experimentId, "Couldn't identify experiment type, experiment {} is neither single application nor workflow.", experimentId);
+                  throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
+              }
+          }
+         }catch(Exception e){
+             throw new TException("Experiment '" + experimentId + "' launch failed. Unable to figureout execution type for application " + experiment.getApplicationId());
+         }
+        return true;
 	}
 
 	/**
@@ -634,4 +621,89 @@ public class OrchestratorServerHandler implements OrchestratorService.Iface,
         }
         return true;
     }
+    private void launchWorkflowExperiment(String experimentId, String airavataCredStoreToken) throws TException {
+    	try {
+			WorkflowEngine workflowEngine = WorkflowEngineFactory.getWorkflowEngine();
+			workflowEngine.launchExperiment(experimentId, airavataCredStoreToken);
+		} catch (WorkflowEngineException e) {
+            log.errorId(experimentId, "Error while launching experiment.", e);
+        }
+    }
+
+
+    private class SingleAppExperimentRunner implements Runnable {
+
+        String experimentId;
+        String airavataCredStoreToken;
+        public SingleAppExperimentRunner(String experimentId,String airavataCredStoreToken){
+            this.experimentId = experimentId;
+            this.airavataCredStoreToken = airavataCredStoreToken;
+        }
+        @Override
+        public void run() {
+            try {
+                launchSingleAppExperiment();
+            } catch (TException e) {
+                e.printStackTrace();
+            }
+        }
+
+        private boolean launchSingleAppExperiment() throws TException {
+            Experiment experiment = null;
+            try {
+                List<String> ids = registry.getIds(RegistryModelType.WORKFLOW_NODE_DETAIL, WorkflowNodeConstants.EXPERIMENT_ID, experimentId);
+                for (String workflowNodeId : ids) {
+//                WorkflowNodeDetails workflowNodeDetail = (WorkflowNodeDetails) registry.get(RegistryModelType.WORKFLOW_NODE_DETAIL, workflowNodeId);
+                    List<Object> taskDetailList = registry.get(RegistryModelType.TASK_DETAIL, TaskDetailConstants.NODE_ID, workflowNodeId);
+                    for (Object o : taskDetailList) {
+                        TaskDetails taskData = (TaskDetails) o;
+                        //iterate through all the generated tasks and performs the job submisssion+monitoring
+                        experiment = (Experiment) registry.get(RegistryModelType.EXPERIMENT, experimentId);
+                        if (experiment == null) {
+                            log.errorId(experimentId, "Error retrieving the Experiment by the given experimentID: {}", experimentId);
+                            return false;
+                        }
+                        ExperimentStatus status = new ExperimentStatus();
+                        status.setExperimentState(ExperimentState.LAUNCHED);
+                        status.setTimeOfStateChange(Calendar.getInstance().getTimeInMillis());
+                        experiment.setExperimentStatus(status);
+                        registry.update(RegistryModelType.EXPERIMENT_STATUS, status, experimentId);
+                        if (ServerSettings.isRabbitMqPublishEnabled()) {
+                            String gatewayId = ServerSettings.getDefaultUserGateway();
+                            ExperimentStatusChangeEvent event = new ExperimentStatusChangeEvent(ExperimentState.LAUNCHED,
+                                    experimentId,
+                                    gatewayId);
+                            String messageId = AiravataUtils.getId("EXPERIMENT");
+                            MessageContext messageContext = new MessageContext(event, MessageType.EXPERIMENT, messageId, gatewayId);
+                            messageContext.setUpdatedTime(AiravataUtils.getCurrentTimestamp());
+                            publisher.publish(messageContext);
+                        }
+                        registry.update(RegistryModelType.TASK_DETAIL, taskData, taskData.getTaskID());
+                        //launching the experiment
+                        launchTask(taskData.getTaskID(), airavataCredStoreToken);
+                    }
+                }
+
+            } catch (Exception e) {
+                // Here we really do not have to do much because only potential failure can happen
+                // is in gfac, if there are errors in gfac, it will handle the experiment/task/job statuses
+                // We might get failures in registry access before submitting the jobs to gfac, in that case we
+                // leave the status of these as created.
+                ExperimentStatus status = new ExperimentStatus();
+                status.setExperimentState(ExperimentState.FAILED);
+                status.setTimeOfStateChange(Calendar.getInstance().getTimeInMillis());
+                experiment.setExperimentStatus(status);
+                try {
+                    registry.update(RegistryModelType.EXPERIMENT_STATUS, status, experimentId);
+                } catch (RegistryException e1) {
+                    log.errorId(experimentId, "Error while updating experiment status to " + status.toString(), e);
+                    throw new TException(e);
+                }
+                log.errorId(experimentId, "Error while updating task status, hence updated experiment status to " + status.toString(), e);
+                throw new TException(e);
+            }
+            return true;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
new file mode 100644
index 0000000..ce71f2a
--- /dev/null
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/DataModelUtils.java
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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.airavata.orchestrator.util;
+
+import java.util.List;
+
+import org.airavata.appcatalog.cpi.AppCatalogException;
+import org.airavata.appcatalog.cpi.ApplicationInterface;
+import org.apache.aiaravata.application.catalog.data.impl.AppCatalogFactory;
+import org.apache.airavata.model.util.ExecutionType;
+import org.apache.airavata.model.workspace.experiment.Experiment;
+import org.apache.airavata.workflow.catalog.WorkflowCatalogFactory;
+
+public class DataModelUtils {
+
+	public static ExecutionType getExecutionType(Experiment experiment){
+		try {
+			ApplicationInterface applicationInterface = AppCatalogFactory.getAppCatalog().getApplicationInterface();
+			List<String> allApplicationInterfaceIds = applicationInterface.getAllApplicationInterfaceIds();
+			String applicationId = experiment.getApplicationId();
+			if (allApplicationInterfaceIds.contains(applicationId)){
+				return ExecutionType.SINGLE_APP;
+			} else {
+				List<String> allWorkflows = WorkflowCatalogFactory.getWorkflowCatalog().getAllWorkflows();
+				if (allWorkflows.contains(applicationId)){
+					return ExecutionType.WORKFLOW;
+				}
+			}
+		} catch (AppCatalogException e) {
+			e.printStackTrace();
+		}
+		return ExecutionType.UNKNOWN;
+	}
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorRecoveryHandler.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorRecoveryHandler.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorRecoveryHandler.java
index d57e9a8..ff16848 100644
--- a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorRecoveryHandler.java
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorRecoveryHandler.java
@@ -84,7 +84,7 @@ public class OrchestratorRecoveryHandler implements Watcher {
                 if(GFacUtils.isCancelled(expId.split("\\+")[0], expId.split("\\+")[1], zk)) {// during relaunching we check the operation and then launch
                     serverHandler.terminateExperiment(expId.split("\\+")[0]);
                 }else {
-                    serverHandler.launchExperiment(expId.split("\\+")[0]);
+                    serverHandler.launchExperiment(expId.split("\\+")[0], null);
                 }
                 // we do not move the old experiment in to new gfac node, gfac will do it
             } catch (Exception e) {       // we attempt all the experiments

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorServerThreadPoolExecutor.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorServerThreadPoolExecutor.java b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorServerThreadPoolExecutor.java
new file mode 100644
index 0000000..da7c06c
--- /dev/null
+++ b/modules/orchestrator/airavata-orchestrator-service/src/main/java/org/apache/airavata/orchestrator/util/OrchestratorServerThreadPoolExecutor.java
@@ -0,0 +1,35 @@
+package org.apache.airavata.orchestrator.util;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+import org.apache.airavata.common.exception.ApplicationSettingsException;
+import org.apache.airavata.common.logger.AiravataLogger;
+import org.apache.airavata.common.logger.AiravataLoggerFactory;
+import org.apache.airavata.common.utils.ServerSettings;
+
+public class OrchestratorServerThreadPoolExecutor {
+	    private final static AiravataLogger logger = AiravataLoggerFactory.getLogger(OrchestratorServerThreadPoolExecutor.class);
+	    public static final String AIRAVATA_SERVER_THREAD_POOL_SIZE = "airavata.server.thread.pool.size";
+
+	    private static ExecutorService threadPool;
+
+	    public static ExecutorService getThreadPool() {
+	        if(threadPool ==null){
+	            threadPool = Executors.newCachedThreadPool();
+	        }
+	        return threadPool;
+	    }
+
+	    public static ExecutorService getFixedThreadPool() {
+	        if(threadPool ==null){
+	            try {
+	                threadPool = Executors.newFixedThreadPool(Integer.parseInt(ServerSettings.getSetting(AIRAVATA_SERVER_THREAD_POOL_SIZE)));
+	            } catch (ApplicationSettingsException e) {
+	                logger.error("Error reading " + AIRAVATA_SERVER_THREAD_POOL_SIZE+ " property");
+	            }
+	        }
+	        return threadPool;
+	    }
+}

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-stubs/pom.xml
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-stubs/pom.xml b/modules/orchestrator/airavata-orchestrator-stubs/pom.xml
new file mode 100644
index 0000000..30cb4ae
--- /dev/null
+++ b/modules/orchestrator/airavata-orchestrator-stubs/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--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. -->
+
+<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">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>orchestrator</artifactId>
+        <groupId>org.apache.airavata</groupId>
+        <version>0.14-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <name>Airavata Orchestrator Client SDK</name>
+    <artifactId>airavata-orchestrator-stubs</artifactId>
+    <packaging>jar</packaging>
+    <url>http://airavata.apache.org/</url>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+            <version>${thrift.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>${org.slf4j.version}</version>
+        </dependency>
+      	<dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>airavata-data-models</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>airavata-model-utils</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+	<dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>airavata-client-configuration</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+    
+</project>

http://git-wip-us.apache.org/repos/asf/airavata/blob/a133fa8c/modules/orchestrator/airavata-orchestrator-stubs/src/main/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactory.java
----------------------------------------------------------------------
diff --git a/modules/orchestrator/airavata-orchestrator-stubs/src/main/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactory.java b/modules/orchestrator/airavata-orchestrator-stubs/src/main/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactory.java
new file mode 100644
index 0000000..c2a31cc
--- /dev/null
+++ b/modules/orchestrator/airavata-orchestrator-stubs/src/main/java/org/apache/airavata/orchestrator/client/OrchestratorClientFactory.java
@@ -0,0 +1,44 @@
+/*
+ *
+ * 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.airavata.orchestrator.client;
+
+import org.apache.airavata.model.error.AiravataClientConnectException;
+import org.apache.airavata.orchestrator.cpi.OrchestratorService;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+
+public class OrchestratorClientFactory {
+
+    public static OrchestratorService.Client createOrchestratorClient(String serverHost, int serverPort)  throws AiravataClientConnectException{
+        try {
+            TTransport transport = new TSocket(serverHost, serverPort);
+            transport.open();
+            TProtocol protocol = new TBinaryProtocol(transport);
+            return new OrchestratorService.Client(protocol);
+        } catch (TTransportException e) {
+        	throw new AiravataClientConnectException("Unable to connect to the server at "+serverHost+":"+serverPort);
+        }
+    }
+}