You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by la...@apache.org on 2013/12/10 21:52:25 UTC
svn commit: r1549966 [1/2] - in /airavata/trunk/modules:
distribution/airavata-server/src/main/resources/conf/ gfac-core/ gfac/
gfac/gfac-core/
gfac/gfac-core/src/main/java/org/apache/airavata/gfac/context/security/
gfac/gfac-core/src/main/java/org/apa...
Author: lahiru
Date: Tue Dec 10 20:52:23 2013
New Revision: 1549966
URL: http://svn.apache.org/r1549966
Log:
restructuring gfac-core.
Added:
airavata/trunk/modules/gfac/
airavata/trunk/modules/gfac/gfac-core/
- copied from r1549938, airavata/trunk/modules/gfac-core/
airavata/trunk/modules/gfac/gfac-ec2/
airavata/trunk/modules/gfac/gfac-ec2/pom.xml
airavata/trunk/modules/gfac/gfac-ec2/src/
airavata/trunk/modules/gfac/gfac-ec2/src/main/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonInstanceScheduler.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonSecurityContext.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonUtil.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/EC2Provider.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/GreedyScheduler.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/SchedulingAlgorithm.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/AmazonEC2Util.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/EC2ProviderUtil.java
airavata/trunk/modules/gfac/gfac-ec2/src/main/resources/
airavata/trunk/modules/gfac/gfac-ec2/src/main/resources/errors.properties
airavata/trunk/modules/gfac/gfac-ec2/src/main/resources/service.properties
airavata/trunk/modules/gfac/gfac-ec2/src/test/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/apache/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/apache/airavata/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/apache/airavata/gfac/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/apache/airavata/gfac/ec2/
airavata/trunk/modules/gfac/gfac-ec2/src/test/java/org/apache/airavata/gfac/ec2/EC2ProviderTest.java
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/airavata-client.properties
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/airavata-server.properties
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/echo.bat
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/gfac-config.xml
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/logging.properties
airavata/trunk/modules/gfac/gfac-ec2/src/test/resources/service.properties
Removed:
airavata/trunk/modules/gfac-core/
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/context/security/AmazonSecurityContext.java
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/ec2/
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/impl/EC2Provider.java
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/utils/AmazonEC2Util.java
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/utils/EC2ProviderUtil.java
airavata/trunk/modules/gfac/gfac-core/src/test/java/org/apache/airavata/core/gfac/services/impl/EC2ProviderTest.java
Modified:
airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/gfac-config.xml
airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/host.xml
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/handler/SCPInputHandler.java
airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/GFacProviderException.java
airavata/trunk/modules/gfac/gfac-core/src/test/resources/gfac-config.xml
airavata/trunk/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/invoker/EmbeddedGFacInvoker.java
Modified: airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/gfac-config.xml
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/gfac-config.xml?rev=1549966&r1=1549965&r2=1549966&view=diff
==============================================================================
--- airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/gfac-config.xml (original)
+++ airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/gfac-config.xml Tue Dec 10 20:52:23 2013
@@ -46,7 +46,7 @@
</OutHandlers>
</Provider>
- <Provider class="org.apache.airavata.gfac.provider.impl.EC2Provider" host="org.apache.airavata.schemas.gfac.impl.Ec2HostTypeImpl">
+ <Provider class="org.apache.airavata.gfac.ec2.EC2Provider" host="org.apache.airavata.schemas.gfac.impl.Ec2HostTypeImpl">
<InHandlers/>
<OutHandlers/>
</Provider>
Modified: airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/host.xml
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/host.xml?rev=1549966&r1=1549965&r2=1549966&view=diff
==============================================================================
--- airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/host.xml (original)
+++ airavata/trunk/modules/distribution/airavata-server/src/main/resources/conf/host.xml Tue Dec 10 20:52:23 2013
@@ -44,6 +44,14 @@
<server>
<name>globus-stampede</name>
<type>globus</type>
+ <monitor host="stampede.tacc.utexas.edu">
+ <primary>org.apache.airavata.monitor.impl.AMQPMonitor</primary>
+ <secondary>org.apache.airavata.monitor.impl.GramMonitor</secondary>
+ </monitor>
+ <monitor hostType="SSHHostTypeImpl">
+ <primary>org.apache.airavata.monitor.impl.MoabMonitor</primary>
+ <secondary>org.apache.airavata.monitor.impl.QstatMonitor</secondary>
+ </monitor>
<host>stampede.tacc.utexas.edu</host>
<gram.endpoint>login5.stampede.tacc.utexas.edu:2119/jobmanager-slurm3</gram.endpoint>
<gridftp.endpoint>gsiftp://data1.stampede.tacc.utexas.edu:2811/</gridftp.endpoint>
Modified: airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/handler/SCPInputHandler.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/handler/SCPInputHandler.java?rev=1549966&r1=1549938&r2=1549966&view=diff
==============================================================================
--- airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/handler/SCPInputHandler.java (original)
+++ airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/handler/SCPInputHandler.java Tue Dec 10 20:52:23 2013
@@ -32,7 +32,9 @@ import org.apache.airavata.commons.gfac.
import org.apache.airavata.gfac.GFacException;
import org.apache.airavata.gfac.context.JobExecutionContext;
import org.apache.airavata.gfac.context.MessageContext;
+import org.apache.airavata.gfac.context.security.GSISecurityContext;
import org.apache.airavata.gfac.context.security.SSHSecurityContext;
+import org.apache.airavata.gfac.provider.GFacProviderException;
import org.apache.airavata.gsi.ssh.api.Cluster;
import org.apache.airavata.gsi.ssh.api.SSHApiException;
import org.apache.airavata.schemas.gfac.ApplicationDeploymentDescriptionType;
@@ -41,52 +43,64 @@ import org.apache.airavata.schemas.gfac.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class SCPInputHandler implements GFacHandler{
+public class SCPInputHandler implements GFacHandler {
- private static final Logger log = LoggerFactory.getLogger(SCPInputHandler.class);
+ private static final Logger log = LoggerFactory.getLogger(SCPInputHandler.class);
- public void invoke(JobExecutionContext jobExecutionContext) throws GFacHandlerException,GFacException {
+ public void invoke(JobExecutionContext jobExecutionContext) throws GFacHandlerException, GFacException {
- log.info("Invoking SCPInputHandler");
+ log.info("Invoking SCPInputHandler");
- MessageContext inputNew = new MessageContext();
- try {
- MessageContext input = jobExecutionContext.getInMessageContext();
- Set<String> parameters = input.getParameters().keySet();
- for (String paramName : parameters) {
- ActualParameter actualParameter = (ActualParameter) input.getParameters().get(paramName);
- String paramValue = MappingFactory.toString(actualParameter);
- //TODO: Review this with type
- if ("URI".equals(actualParameter.getType().getType().toString())) {
- ((URIParameterType) actualParameter.getType()).setValue(stageInputFiles(jobExecutionContext, paramValue));
- } else if ("URIArray".equals(actualParameter.getType().getType().toString())) {
- List<String> split = Arrays.asList(StringUtil.getElementsFromString(paramValue));
- List<String> newFiles = new ArrayList<String>();
- for (String paramValueEach : split) {
- newFiles.add(stageInputFiles(jobExecutionContext, paramValueEach));
- }
- ((URIArrayType) actualParameter.getType()).setValueArray(newFiles.toArray(new String[newFiles.size()]));
- }
- inputNew.getParameters().put(paramName, actualParameter);
- }
- } catch (Exception e) {
- log.error(e.getMessage());
- throw new GFacHandlerException("Error while input File Staging", e, e.getLocalizedMessage());
- }
- jobExecutionContext.setInMessageContext(inputNew);
- }
-
- private static String stageInputFiles(JobExecutionContext context, String paramValue) throws IOException, GFacException {
- SSHSecurityContext securityContext = (SSHSecurityContext)context.getSecurityContext(SSHSecurityContext.SSH_SECURITY_CONTEXT);
- Cluster pbsCluster = securityContext.getPbsCluster();
- ApplicationDeploymentDescriptionType app = context.getApplicationContext().getApplicationDeploymentDescription().getType();
+ MessageContext inputNew = new MessageContext();
+ try {
+ MessageContext input = jobExecutionContext.getInMessageContext();
+ Set<String> parameters = input.getParameters().keySet();
+ for (String paramName : parameters) {
+ ActualParameter actualParameter = (ActualParameter) input.getParameters().get(paramName);
+ String paramValue = MappingFactory.toString(actualParameter);
+ //TODO: Review this with type
+ if ("URI".equals(actualParameter.getType().getType().toString())) {
+ ((URIParameterType) actualParameter.getType()).setValue(stageInputFiles(jobExecutionContext, paramValue));
+ } else if ("URIArray".equals(actualParameter.getType().getType().toString())) {
+ List<String> split = Arrays.asList(StringUtil.getElementsFromString(paramValue));
+ List<String> newFiles = new ArrayList<String>();
+ for (String paramValueEach : split) {
+ newFiles.add(stageInputFiles(jobExecutionContext, paramValueEach));
+ }
+ ((URIArrayType) actualParameter.getType()).setValueArray(newFiles.toArray(new String[newFiles.size()]));
+ }
+ inputNew.getParameters().put(paramName, actualParameter);
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage());
+ throw new GFacHandlerException("Error while input File Staging", e, e.getLocalizedMessage());
+ }
+ jobExecutionContext.setInMessageContext(inputNew);
+ }
+
+ private static String stageInputFiles(JobExecutionContext jobExecutionContext, String paramValue) throws IOException, GFacException {
+ Cluster cluster = null;
+ if (jobExecutionContext.getSecurityContext(GSISecurityContext.GSI_SECURITY_CONTEXT) != null) {
+ cluster = ((GSISecurityContext) jobExecutionContext.getSecurityContext(GSISecurityContext.GSI_SECURITY_CONTEXT)).getPbsCluster();
+ } else {
+ cluster = ((SSHSecurityContext) jobExecutionContext.getSecurityContext(SSHSecurityContext.SSH_SECURITY_CONTEXT)).getPbsCluster();
+ }
+ if (cluster == null) {
+ throw new GFacException("Security context is not set properly");
+ } else {
+ log.info("Successfully retrieved the Security Context");
+ }
+ ApplicationDeploymentDescriptionType app = jobExecutionContext.getApplicationContext().getApplicationDeploymentDescription().getType();
int i = paramValue.lastIndexOf(File.separator);
String substring = paramValue.substring(i + 1);
try {
- String targetFile = app.getInputDataDirectory()+ File.separator + substring;
- pbsCluster.scpTo(targetFile, paramValue);
+ String targetFile = app.getInputDataDirectory() + File.separator + substring;
+ if(paramValue.startsWith("file")){
+ paramValue = paramValue.substring(paramValue.indexOf(":") + 1, paramValue.length());
+ }
+ cluster.scpTo(targetFile, paramValue);
return targetFile;
} catch (SSHApiException e) {
throw new GFacHandlerException("Error while input File Staging", e, e.getLocalizedMessage());
Modified: airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/GFacProviderException.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/GFacProviderException.java?rev=1549966&r1=1549938&r2=1549966&view=diff
==============================================================================
--- airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/GFacProviderException.java (original)
+++ airavata/trunk/modules/gfac/gfac-core/src/main/java/org/apache/airavata/gfac/provider/GFacProviderException.java Tue Dec 10 20:52:23 2013
@@ -32,14 +32,12 @@ public class GFacProviderException exten
public GFacProviderException(String message) {
super(message);
- sendFaultNotification(message, new Exception(message));
log.error(message);
}
public GFacProviderException(String message, Throwable cause) {
super(message, cause);
- sendFaultNotification(message, new Exception(cause));
log.error(message,cause);
}
@@ -47,19 +45,7 @@ public class GFacProviderException exten
public GFacProviderException(String message, Exception e, String... additionExceptiondata) {
super(message);
this.aditionalInfo = additionExceptiondata;
- sendFaultNotification(message, e, additionExceptiondata);
log.error(message,e);
}
- private void sendFaultNotification(String message,
- Exception e,
- String... additionalExceptiondata) {
- if (additionalExceptiondata == null || additionalExceptiondata.length == 0) {
- additionalExceptiondata = new String[]{message, e.getLocalizedMessage()};
- }
- }
-
- public String[] getAditionalInfo() {
- return aditionalInfo;
- }
}
Modified: airavata/trunk/modules/gfac/gfac-core/src/test/resources/gfac-config.xml
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-core/src/test/resources/gfac-config.xml?rev=1549966&r1=1549938&r2=1549966&view=diff
==============================================================================
--- airavata/trunk/modules/gfac/gfac-core/src/test/resources/gfac-config.xml (original)
+++ airavata/trunk/modules/gfac/gfac-core/src/test/resources/gfac-config.xml Tue Dec 10 20:52:23 2013
@@ -46,7 +46,7 @@
</OutHandlers>
</Provider>
- <Provider class="org.apache.airavata.gfac.provider.impl.EC2Provider" host="org.apache.airavata.schemas.gfac.impl.Ec2HostTypeImpl">
+ <Provider class="org.apache.airavata.gfac.ec2.EC2Provider" host="org.apache.airavata.schemas.gfac.impl.Ec2HostTypeImpl">
<InHandlers/>
<OutHandlers/>
</Provider>
Added: airavata/trunk/modules/gfac/gfac-ec2/pom.xml
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/pom.xml?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/pom.xml (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/pom.xml Tue Dec 10 20:52:23 2013
@@ -0,0 +1,149 @@
+<?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">
+ <parent>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata</artifactId>
+ <version>0.11-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>airavata-gfac-ec2</artifactId>
+ <name>Airavata GFac Core</name>
+ <description>The core GFAC functionality independent from any webservice implementation.</description>
+ <url>http://airavata.apache.org/</url>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-gfac-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-configuration</groupId>
+ <artifactId>commons-configuration</artifactId>
+ <version>1.6</version>
+ </dependency>
+
+ <!-- Logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <!-- GFAC schemas -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-client-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-workflow-execution-context</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- Workflow Tracking -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-workflow-tracking</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- SSH -->
+ <dependency>
+ <groupId>net.schmizz</groupId>
+ <artifactId>sshj</artifactId>
+ <version>0.8.0</version>
+ </dependency>
+
+ <!-- Credential Store -->
+ <dependency>
+ <groupId>org.apache.airavata</groupId>
+ <artifactId>airavata-credential-store</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+
+ <!-- Amazon EC2 Provider -->
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk</artifactId>
+ <version>1.3.20</version>
+ </dependency>
+ <dependency>
+ <groupId>sshtools</groupId>
+ <artifactId>j2ssh-core</artifactId>
+ <version>0.2.9</version>
+ </dependency>
+ <dependency>
+ <groupId>sshtools</groupId>
+ <artifactId>j2ssh-common</artifactId>
+ <version>0.2.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.3</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ <version>4.3</version>
+ <type>jar</type>
+ </dependency>
+
+ <!-- Test -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>6.1.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!--skip>true</skip -->
+ <excludes>
+ <exclude>**/services/**</exclude>
+ <exclude>**/gfac/**</exclude>
+ </excludes>
+ <forkMode>always</forkMode>
+ <failIfNoTests>false</failIfNoTests>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonInstanceScheduler.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonInstanceScheduler.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonInstanceScheduler.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonInstanceScheduler.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,233 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.cloudwatch.AmazonCloudWatchClient;
+import com.amazonaws.services.cloudwatch.model.Datapoint;
+import com.amazonaws.services.cloudwatch.model.Dimension;
+import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest;
+import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.DescribeInstancesResult;
+import com.amazonaws.services.ec2.model.Instance;
+import com.amazonaws.services.ec2.model.Reservation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class AmazonInstanceScheduler {
+ private static final Logger log = LoggerFactory.getLogger(AmazonInstanceScheduler.class);
+
+ /* Maximum number of instances that the Scheduler will create*/
+ //private static final int MAX_INSTANCE_COUNT = 3;
+
+ /* Maximum number of minutes an instance should be kept alive*/
+ public static final int INSTANCE_UP_TIME_THRESHOLD = 60;
+
+ private static volatile AmazonInstanceScheduler scheduler = null;
+
+ private static String imageId = null;
+
+ private static AWSCredentials credential = null;
+
+ private static AmazonEC2Client ec2client = null;
+
+ /* The time interval(minutes) in which the instances will be checked whether they have timed-out*/
+ public static final long TERMINATE_THREAD_UPDATE_INTERVAL = 5;
+
+ public static AmazonInstanceScheduler getInstance(String imageId, String accessKey, String secretKey)
+ throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
+
+ if(scheduler == null) {
+ synchronized (AmazonInstanceScheduler.class) {
+ if(scheduler == null) {
+ new Thread() {
+ @Override
+ public void run() {
+ //noinspection InfiniteLoopStatement
+ while(true) {
+ try {
+ Thread.sleep(TERMINATE_THREAD_UPDATE_INTERVAL * 60 * 1000);
+ } catch (InterruptedException e ) {
+ // do-nothing
+ }
+
+ try {
+ terminateTimedOutAmazonInstances();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ }.start();
+
+ scheduler = new AmazonInstanceScheduler();
+ }
+ }
+ }
+
+ AmazonInstanceScheduler.imageId = imageId;
+ AmazonInstanceScheduler.credential = new BasicAWSCredentials(accessKey, secretKey);
+ AmazonInstanceScheduler.ec2client = new AmazonEC2Client(credential);
+
+ return scheduler;
+ }
+
+
+ /**
+ * Returns the amazon instance id of the amazon instance which is having the minimum
+ * CPU utilization (out of the already running instances). If the instance which
+ * is having the minimum CPU utilization exceeds 80%, ami-id will be returned
+ * instead of a an instance id. If a particular running instance's uptime is
+ * greater than 55 minutes, that instance will be shut down.
+ *
+ * @return instance id
+ * @throws NoSuchAlgorithmException
+ * @throws InvalidKeySpecException
+ * @throws IOException
+ */
+ public String getScheduledAmazonInstance()
+ throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
+
+ SchedulingAlgorithm greedyAglo = new GreedyScheduler();
+ return greedyAglo.getScheduledAmazonInstance(ec2client,imageId, credential);
+ }
+
+ /**
+ * Terminates the Amazon instances that are timed out. Timed out refers to the
+ * instances which have been running for more than the INSTANCE_UP_TIME_THRESHOLD.
+ */
+ private static void terminateTimedOutAmazonInstances(){
+ System.out.println("Checking for timed-out instances");
+ List<Instance> instanceList = loadInstances(ec2client);
+ for (Instance instance : instanceList) {
+ String instanceId = instance.getInstanceId();
+
+ long upTime = getInstanceUptime(instance);
+ // if the instance up time is greater than the threshold, terminate the instance
+ if (upTime > INSTANCE_UP_TIME_THRESHOLD) {
+ List<String> requestIds = new ArrayList<String>();
+ requestIds.add(instanceId);
+ // terminate instance
+ System.out.println("Terminating the instance " + instanceId +
+ " as the up time threshold is exceeded");
+ AmazonUtil.terminateInstances(requestIds);
+ }
+ }
+
+ }
+
+ /**
+ * Calculates the instance up time in minutes.
+ *
+ * @param instance instance to be monitored.
+ * @return up time of the instance.
+ */
+ private static long getInstanceUptime(Instance instance) {
+ Date startTime = instance.getLaunchTime();
+ Date today = new Date();
+ long diff = (today.getTime() - startTime.getTime()) / (1000 * 60);
+ System.out.println("Instance launch time : " + startTime);
+ System.out.println("Instance up time (mins): " + diff);
+ return diff;
+ }
+
+ /**
+ * Monitors the CPU Utilization using Amazon Cloud Watch. In order to monitor the instance, Cloud Watch Monitoring
+ * should be enabled for the running instance.
+ *
+ * @param credential EC2 credentials
+ * @param instanceId instance id
+ * @return average CPU utilization of the instance
+ */
+ public static double monitorInstance(AWSCredentials credential, String instanceId) {
+ try {
+ AmazonCloudWatchClient cw = new AmazonCloudWatchClient(credential) ;
+
+ long offsetInMilliseconds = 1000 * 60 * 60 * 24;
+ GetMetricStatisticsRequest request = new GetMetricStatisticsRequest()
+ .withStartTime(new Date(new Date().getTime() - offsetInMilliseconds))
+ .withNamespace("AWS/EC2")
+ .withPeriod(60 * 60)
+ .withDimensions(new Dimension().withName("InstanceId").withValue(instanceId))
+ .withMetricName("CPUUtilization")
+ .withStatistics("Average", "Maximum")
+ .withEndTime(new Date());
+ GetMetricStatisticsResult getMetricStatisticsResult = cw.getMetricStatistics(request);
+
+ double avgCPUUtilization = 0;
+ List dataPoint = getMetricStatisticsResult.getDatapoints();
+ for (Object aDataPoint : dataPoint) {
+ Datapoint dp = (Datapoint) aDataPoint;
+ avgCPUUtilization = dp.getAverage();
+ log.info(instanceId + " instance's average CPU utilization : " + dp.getAverage());
+ }
+
+ return avgCPUUtilization;
+
+ } catch (AmazonServiceException ase) {
+ log.error("Caught an AmazonServiceException, which means the request was made "
+ + "to Amazon EC2, but was rejected with an error response for some reason.");
+ log.error("Error Message: " + ase.getMessage());
+ log.error("HTTP Status Code: " + ase.getStatusCode());
+ log.error("AWS Error Code: " + ase.getErrorCode());
+ log.error("Error Type: " + ase.getErrorType());
+ log.error("Request ID: " + ase.getRequestId());
+
+ }
+ return 0;
+ }
+
+ /**
+ * Load instances associated with the given ec2 client
+ *
+ * @param ec2client ec2 client
+ * @return list of instances
+ */
+ public static List<Instance> loadInstances(AmazonEC2Client ec2client) {
+ List<Instance> resultList = new ArrayList<Instance>();
+ DescribeInstancesResult describeInstancesResult = ec2client.describeInstances();
+ List<Reservation> reservations = describeInstancesResult.getReservations();
+ for (Reservation reservation : reservations) {
+ for (Instance instance : reservation.getInstances()) {
+ System.out.println("instance : " + instance);
+ if ("running".equalsIgnoreCase(instance.getState().getName())) {
+ resultList.add(instance);
+ }
+ }
+ }
+ return resultList;
+ }
+
+}
+
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonSecurityContext.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonSecurityContext.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonSecurityContext.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonSecurityContext.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import org.apache.airavata.gfac.SecurityContext;
+
+public class AmazonSecurityContext implements SecurityContext {
+
+ public static final String AMAZON_SECURITY_CONTEXT = "amazon";
+ private String userName;
+ private String accessKey;
+ private String secretKey;
+ private String amiId;
+ private String instanceType;
+ private String instanceId;
+ private boolean isRunningInstance = false;
+
+ public AmazonSecurityContext(String userName, String accessKey, String secretKey, String amiId, String instanceType) {
+ this.userName = userName;
+ this.accessKey = accessKey;
+ this.secretKey = secretKey;
+ this.amiId = amiId;
+ this.instanceType = instanceType;
+ }
+
+ public AmazonSecurityContext(String userName, String accessKey, String secretKey, String instanceId) {
+ this.userName = userName;
+ this.accessKey = accessKey;
+ this.secretKey = secretKey;
+ this.instanceId = instanceId;
+ this.isRunningInstance = true;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ public String getInstanceType() {
+ return instanceType;
+ }
+
+ public String getAmiId() {
+ return amiId;
+ }
+
+ public boolean isRunningInstance() {
+ return isRunningInstance;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+}
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonUtil.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonUtil.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonUtil.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/AmazonUtil.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class AmazonUtil {
+
+ /* Amazon EC2 instance type */
+ public final static String[] INSTANCE_TYPE =
+ { "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge",
+ "m2.4xlarge", "c1.medium", "c1.xlarge" };
+
+ private static AmazonEC2 getEC2Client() {
+ // FIXME : Fix this properly after adding UI components.
+ String accessKey = "";
+ String secretKey = "";
+ AmazonEC2 ec2 = new AmazonEC2Client(new BasicAWSCredentials(accessKey, secretKey));
+ return ec2;
+ }
+
+ /**
+ * Launch a new EC2 instance
+ *
+ * @param amiId
+ * @param type
+ * @param number
+ * @return list of newly launched instances
+ */
+ public static List<Instance> launchInstance(String amiId, String type, Integer number) {
+ List<Instance> resultList = new ArrayList<Instance>();
+
+ RunInstancesRequest request = new RunInstancesRequest(amiId, number, number);
+ request.setInstanceType(type);
+
+ RunInstancesResult result = getEC2Client().runInstances(request);
+ resultList.addAll(result.getReservation().getInstances());
+ return resultList;
+ }
+
+ /**
+ * Launch a new EC2 instance
+ *
+ * @param amiId
+ * @param type
+ * @param number
+ * @param keyname
+ * @return list of newly launched instances
+ */
+ public static List<Instance> launchInstance(String amiId, String type, Integer number, String keyname) {
+ List<Instance> resultList = new ArrayList<Instance>();
+
+ RunInstancesRequest request = new RunInstancesRequest(amiId, number, number);
+ request.setInstanceType(type);
+ request.setKeyName(keyname);
+
+ RunInstancesResult result = getEC2Client().runInstances(request);
+ resultList.addAll(result.getReservation().getInstances());
+ return resultList;
+ }
+
+ /**
+ * Load instances
+ *
+ * @return list of instances
+ */
+ public static List<Instance> loadInstances() {
+ List<Instance> resultList = new ArrayList<Instance>();
+ DescribeInstancesResult describeInstancesResult = getEC2Client().describeInstances();
+ List<Reservation> reservations = describeInstancesResult.getReservations();
+ for (Iterator<Reservation> iterator = reservations.iterator(); iterator.hasNext();) {
+ Reservation reservation = iterator.next();
+ for (Instance instance : reservation.getInstances()) {
+ resultList.add(instance);
+ }
+ }
+ return resultList;
+ }
+
+ /**
+ * Load key pairs
+ *
+ * @return list of keypairs
+ */
+ public static List<String> loadKeypairs(){
+ List<String> resultList = new ArrayList<String>();
+ DescribeKeyPairsResult results = getEC2Client().describeKeyPairs();
+ for (KeyPairInfo key : results.getKeyPairs()) {
+ resultList.add(key.getKeyName());
+ }
+ return resultList;
+ }
+
+ /**
+ * Terminate instances
+ *
+ * @param instanceIds instance ids of the running instances.
+ */
+ public static void terminateInstances(List<String> instanceIds) {
+ // terminate
+ TerminateInstancesRequest request = new TerminateInstancesRequest(instanceIds);
+ getEC2Client().terminateInstances(request);
+ }
+
+ /**
+ * Terminate instances
+ *
+ * @param instanceIds instance ids of the running instances.
+ */
+ public static void terminateInstances(String... instanceIds) {
+ // terminate
+ TerminateInstancesRequest request = new TerminateInstancesRequest();
+ getEC2Client().terminateInstances(request.withInstanceIds(instanceIds));
+ }
+
+}
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/EC2Provider.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/EC2Provider.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/EC2Provider.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/EC2Provider.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,378 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.*;
+import com.sshtools.j2ssh.SshClient;
+import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
+import com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient;
+import com.sshtools.j2ssh.configuration.SshConnectionProperties;
+import com.sshtools.j2ssh.session.SessionChannelClient;
+import com.sshtools.j2ssh.transport.HostKeyVerification;
+import com.sshtools.j2ssh.transport.TransportProtocolException;
+import com.sshtools.j2ssh.transport.publickey.InvalidSshKeyException;
+import com.sshtools.j2ssh.transport.publickey.SshPrivateKey;
+import com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile;
+import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
+
+import org.apache.airavata.client.api.AiravataAPI;
+import org.apache.airavata.client.api.exception.AiravataAPIInvocationException;
+import org.apache.airavata.commons.gfac.type.ActualParameter;
+import org.apache.airavata.commons.gfac.type.ApplicationDescription;
+import org.apache.airavata.gfac.GFacException;
+import org.apache.airavata.gfac.context.JobExecutionContext;
+import org.apache.airavata.gfac.ec2.util.AmazonEC2Util;
+import org.apache.airavata.gfac.ec2.util.EC2ProviderUtil;
+import org.apache.airavata.gfac.notification.events.EC2ProviderEvent;
+import org.apache.airavata.gfac.provider.GFacProvider;
+import org.apache.airavata.gfac.provider.GFacProviderException;
+import org.apache.airavata.gfac.provider.utils.ProviderUtils;
+import org.apache.airavata.gfac.utils.GFacUtils;
+import org.apache.airavata.registry.api.workflow.ApplicationJob;
+import org.apache.airavata.registry.api.workflow.ApplicationJob.ApplicationJobStatus;
+import org.apache.airavata.schemas.gfac.ApplicationDeploymentDescriptionType;
+import org.apache.airavata.schemas.gfac.Ec2ApplicationDeploymentType;
+import org.apache.airavata.schemas.gfac.OutputParameterType;
+import org.apache.airavata.schemas.gfac.StringParameterType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+
+public class EC2Provider implements GFacProvider {
+
+ private static final Logger log = LoggerFactory.getLogger(EC2Provider.class);
+
+ public static final int SOCKET_TIMEOUT = 30000;
+
+ public static final int SSH_PORT = 22;
+
+ public static final String KEY_PAIR_NAME = "ec2_rsa";
+
+ private Instance instance = null;
+
+ private AmazonSecurityContext amazonSecurityContext;
+
+ private String jobId;
+
+ public void initialize(JobExecutionContext jobExecutionContext) throws GFacProviderException,GFacException{
+ if (jobExecutionContext != null) {
+ jobId="EC2_"+jobExecutionContext.getApplicationContext().getHostDescription().getType().getHostAddress()+"_"+Calendar.getInstance().getTimeInMillis();
+ if (jobExecutionContext.getSecurityContext(AmazonSecurityContext.AMAZON_SECURITY_CONTEXT)
+ instanceof AmazonSecurityContext) {
+ this.amazonSecurityContext = (AmazonSecurityContext) jobExecutionContext.
+ getSecurityContext(AmazonSecurityContext.AMAZON_SECURITY_CONTEXT);
+ } else {
+ throw new GFacProviderException("Amazon Security Context is not set" + jobExecutionContext);
+ }
+ } else {
+ throw new GFacProviderException("Job Execution Context is null" + jobExecutionContext);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("ACCESS_KEY:" + amazonSecurityContext.getAccessKey());
+ log.debug("SECRET_KEY:" + amazonSecurityContext.getSecretKey());
+ log.debug("AMI_ID:" + amazonSecurityContext.getAmiId());
+ log.debug("INS_ID:" + amazonSecurityContext.getInstanceId());
+ log.debug("INS_TYPE:" + amazonSecurityContext.getInstanceType());
+ log.debug("USERNAME:" + amazonSecurityContext.getUserName());
+ }
+ saveApplicationJob(jobExecutionContext);
+// job
+ /* Validation */
+ if (amazonSecurityContext.getAccessKey() == null || amazonSecurityContext.getAccessKey().isEmpty())
+ throw new GFacProviderException("EC2 Access Key is empty");
+ if (amazonSecurityContext.getSecretKey() == null || amazonSecurityContext.getSecretKey().isEmpty())
+ throw new GFacProviderException("EC2 Secret Key is empty");
+ if ((amazonSecurityContext.getAmiId() == null && amazonSecurityContext.getInstanceId() == null) ||
+ (amazonSecurityContext.getAmiId() != null && amazonSecurityContext.getAmiId().isEmpty()) ||
+ (amazonSecurityContext.getInstanceId() != null && amazonSecurityContext.getInstanceId().isEmpty()))
+ throw new GFacProviderException("EC2 AMI or Instance ID is empty");
+ if (amazonSecurityContext.getUserName() == null || amazonSecurityContext.getUserName().isEmpty())
+ throw new GFacProviderException("EC2 Username is empty");
+
+ /* Need to start EC2 instance before running it */
+ AWSCredentials credential =
+ new BasicAWSCredentials(amazonSecurityContext.getAccessKey(), amazonSecurityContext.getSecretKey());
+ AmazonEC2Client ec2client = new AmazonEC2Client(credential);
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.AUTHENTICATE);
+ initEc2Environment(jobExecutionContext, ec2client);
+ checkConnection(instance, ec2client);
+ }
+
+ private void saveApplicationJob(JobExecutionContext jobExecutionContext) {
+ ApplicationJob job = GFacUtils.createApplicationJob(jobExecutionContext);
+ job.setJobId(jobId);
+ job.setStatus(ApplicationJobStatus.VALIDATE_INPUT);
+ job.setSubmittedTime(Calendar.getInstance().getTime());
+ job.setStatusUpdateTime(job.getSubmittedTime());
+ GFacUtils.recordApplicationJob(jobExecutionContext, job);
+ }
+
+ public void execute(JobExecutionContext jobExecutionContext) throws GFacProviderException {
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.INITIALIZE);
+ String shellCmd = createShellCmd(jobExecutionContext);
+ AiravataAPI airavataAPI = jobExecutionContext.getGFacConfiguration().getAiravataAPI();
+ if (airavataAPI!=null){
+ try {
+ airavataAPI.getProvenanceManager().updateApplicationJobData(jobId, shellCmd);
+ } catch (AiravataAPIInvocationException e) {
+ log.error("Error in saving EC2 shell command!!!", e);
+ }
+ }
+ SshClient sshClient = new SshClient();
+ sshClient.setSocketTimeout(SOCKET_TIMEOUT);
+ SshConnectionProperties properties = new SshConnectionProperties();
+ properties.setHost(this.instance.getPublicDnsName());
+ properties.setPort(SSH_PORT);
+
+ // Connect to the host
+ try
+ {
+ String outParamName;
+ OutputParameterType[] outputParametersArray = jobExecutionContext.getApplicationContext().
+ getServiceDescription().getType().getOutputParametersArray();
+ if(outputParametersArray != null) {
+ outParamName = outputParametersArray[0].getParameterName();
+ } else {
+ throw new GFacProviderException("Output parameter name is not set. Therefore, not being able " +
+ "to filter the job result from standard out ");
+ }
+
+ sshClient.connect(properties, new HostKeyVerification() {
+ public boolean verifyHost(String s, SshPublicKey sshPublicKey) throws TransportProtocolException {
+ log.debug("Verifying Host: " + s);
+ return true;
+ }
+ });
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.AUTHENTICATE);
+ // Initialize the authentication data.
+ PublicKeyAuthenticationClient publicKeyAuth = new PublicKeyAuthenticationClient();
+ publicKeyAuth.setUsername(amazonSecurityContext.getUserName());
+ SshPrivateKeyFile file = SshPrivateKeyFile.
+ parse(new File(System.getProperty("user.home") + "/.ssh/" + KEY_PAIR_NAME));
+ SshPrivateKey privateKey = file.toPrivateKey("");
+ publicKeyAuth.setKey(privateKey);
+
+ // Authenticate
+ int result = sshClient.authenticate(publicKeyAuth);
+ if(result== AuthenticationProtocolState.FAILED) {
+ throw new GFacProviderException("The authentication failed");
+ } else if(result==AuthenticationProtocolState.PARTIAL) {
+ throw new GFacProviderException("The authentication succeeded but another"
+ + "authentication is required");
+ } else if(result==AuthenticationProtocolState.COMPLETE) {
+ log.info("ssh client authentication is complete...");
+ }
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.SUBMITTED);
+ SessionChannelClient session = sshClient.openSessionChannel();
+ log.info("ssh session successfully opened...");
+ session.requestPseudoTerminal("vt100", 80, 25, 0, 0, "");
+ session.startShell();
+
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.EXECUTING);
+ session.getOutputStream().write(shellCmd.getBytes());
+
+ InputStream in = session.getInputStream();
+ byte buffer[] = new byte[255];
+ int read;
+ String executionResult = "";
+ while((read = in.read(buffer)) > 0) {
+ String out = new String(buffer, 0, read);
+// System.out.println(out);
+
+ if(out.startsWith(outParamName)) {
+ executionResult = out.split("=")[1];
+ log.debug("Result found in the StandardOut ");
+ break;
+ }
+ }
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.RESULTS_RETRIEVE);
+
+ executionResult = executionResult.replace("\r","").replace("\n","");
+ log.info("Result of the job : " + executionResult);
+
+ for(OutputParameterType outparamType : outputParametersArray){
+ /* Assuming that there is just a single result. If you want to add more results, update the necessary
+ logic below */
+ String paramName = outparamType.getParameterName();
+ ActualParameter outParam = new ActualParameter();
+ outParam.getType().changeType(StringParameterType.type);
+ ((StringParameterType) outParam.getType()).setValue(executionResult);
+ jobExecutionContext.getOutMessageContext().addParameter(paramName, outParam);
+ }
+ GFacUtils.updateApplicationJobStatus(jobExecutionContext, jobId, ApplicationJobStatus.FINISHED);
+ } catch (InvalidSshKeyException e) {
+ throw new GFacProviderException("Invalid SSH key", e);
+ } catch (IOException e) {
+ throw new GFacProviderException("Error in occurred during IO", e);
+ } catch (Exception e) {
+ throw new GFacProviderException("Error parsing standard out for job execution result", e);
+ }
+
+ }
+
+ public void dispose(JobExecutionContext jobExecutionContext) throws GFacProviderException {
+ // Do nothing
+ }
+
+ public void cancelJob(String jobId, JobExecutionContext jobExecutionContext) throws GFacException {
+ throw new NotImplementedException();
+ }
+
+ /**
+ * Creates the command to be executed in the remote shell.
+ *
+ * @param jobExecutionContext JobExecutionContext for the cloud job
+ * @return shell command to be executed
+ * @throws GFacProviderException GFacProviderException
+ */
+ private String createShellCmd(JobExecutionContext jobExecutionContext) throws GFacProviderException {
+ String command = "";
+ ApplicationDescription appDesc = jobExecutionContext.getApplicationContext().
+ getApplicationDeploymentDescription();
+
+ if(appDesc.getType() instanceof Ec2ApplicationDeploymentType) {
+ Ec2ApplicationDeploymentType type = (Ec2ApplicationDeploymentType) appDesc.getType();
+ if(type.getExecutable() != null) {
+ command = type.getExecutableType() + " " + type.getExecutable();
+ } else {
+ command = "sh" + " " + type.getExecutable();
+ }
+ command = setCmdParams(jobExecutionContext, command);
+
+ } else {
+ ApplicationDeploymentDescriptionType type = appDesc.getType();
+ command = "sh" + " " + type.getExecutableLocation();
+ command = setCmdParams(jobExecutionContext, command);
+ }
+
+ return command + '\n';
+ }
+
+ private String setCmdParams(JobExecutionContext jobExecutionContext, String command) throws GFacProviderException {
+ List<String> inputParams = null;
+ try {
+ inputParams = ProviderUtils.getInputParameters(jobExecutionContext);
+ } catch (GFacProviderException e) {
+ throw new GFacProviderException("Error in extracting input values from JobExecutionContext");
+ }
+
+ for(String param : inputParams){
+ command = " " + command + " " + param;
+ }
+
+ log.info("Command to be executed on EC2 : " + command);
+ return command;
+ }
+
+ /**
+ * Checks whether the port 22 of the Amazon instance is accessible.
+ *
+ * @param instance Amazon instance id.
+ * @param ec2client AmazonEC2Client object
+ */
+ private void checkConnection(Instance instance, AmazonEC2Client ec2client) {
+ /* Make sure port 22 is connectible */
+ for (GroupIdentifier g : instance.getSecurityGroups()) {
+ IpPermission ip = new IpPermission();
+ ip.setIpProtocol("tcp");
+ ip.setFromPort(SSH_PORT);
+ ip.setToPort(SSH_PORT);
+ AuthorizeSecurityGroupIngressRequest r = new AuthorizeSecurityGroupIngressRequest();
+ r = r.withIpPermissions(ip.withIpRanges("0.0.0.0/0"));
+ r.setGroupId(g.getGroupId());
+ try {
+ ec2client.authorizeSecurityGroupIngress(r);
+ } catch (AmazonServiceException as) {
+ /* If exception is from duplicate room, ignore it. */
+ if (!as.getErrorCode().equals("InvalidPermission.Duplicate"))
+ throw as;
+ }
+ }
+ }
+
+ /**
+ * Initializes the Amazon EC2 environment needed to run the Cloud job submission. This will bring
+ * up an Amazon instance (out of an AMI) or use an existing instance id.
+ *
+ * @param jobExecutionContext Job execution context.
+ * @param ec2client EC2 Client.
+ * @return instance id of the running Amazon instance.
+ * @throws GFacProviderException
+ */
+ private void initEc2Environment(JobExecutionContext jobExecutionContext, AmazonEC2Client ec2client)
+ throws GFacProviderException {
+ try {
+ /* Build key pair before start instance */
+ EC2ProviderUtil.buildKeyPair(ec2client, KEY_PAIR_NAME);
+
+ // right now, we can run it on one host
+ if (amazonSecurityContext.getAmiId() != null)
+ instance = AmazonEC2Util.startInstances(ec2client, amazonSecurityContext.getAmiId(),
+ amazonSecurityContext.getInstanceType(), jobExecutionContext, KEY_PAIR_NAME).get(0);
+ else {
+
+ // already running instance
+ DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest();
+ DescribeInstancesResult describeInstancesResult =
+ ec2client.describeInstances(describeInstancesRequest.
+ withInstanceIds(amazonSecurityContext.getInstanceId()));
+
+ if (describeInstancesResult.getReservations().size() == 0 ||
+ describeInstancesResult.getReservations().get(0).getInstances().size() == 0) {
+ throw new GFacProviderException("Instance not found:" + amazonSecurityContext.getInstanceId());
+ }
+
+ instance = describeInstancesResult.getReservations().get(0).getInstances().get(0);
+
+ // check instance keypair
+ if (instance.getKeyName() == null || !instance.getKeyName().equals(KEY_PAIR_NAME)) {
+ throw new GFacProviderException("Keypair for instance:" + amazonSecurityContext.getInstanceId() +
+ " is not valid");
+ }
+ }
+
+ jobExecutionContext.getNotificationService().publish(new EC2ProviderEvent("EC2 Instance " +
+ this.instance.getInstanceId() + " is running with public name " + this.instance.getPublicDnsName()));
+
+ } catch (Exception e) {
+ throw new GFacProviderException("Invalid Request",e);
+ }
+
+ }
+
+ public void initProperties(Map<String, String> properties) throws GFacProviderException, GFacException {
+ // do nothing
+ }
+
+}
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/GreedyScheduler.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/GreedyScheduler.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/GreedyScheduler.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/GreedyScheduler.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.Instance;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GreedyScheduler implements SchedulingAlgorithm {
+
+ /**
+ * Returns the amazon instance id of the amazon instance which is having the minimum
+ * CPU utilization (out of the already running instances). If the instance which
+ * is having the minimum CPU utilization exceeds 80%, ami-id will be returned
+ * instead of a an instance id. If a particular running instance's uptime is
+ * greater than 55 minutes, that instance will be shut down.
+ *
+ * @return instance id
+ * @throws java.security.NoSuchAlgorithmException
+ * @throws java.security.spec.InvalidKeySpecException
+ * @throws java.io.IOException
+ */
+ public String getScheduledAmazonInstance(AmazonEC2Client ec2client, String imageId, AWSCredentials credential)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
+
+ Map<String, Double> instanceUtilMap = new HashMap<String, Double>();
+ List<Instance> instanceList = AmazonInstanceScheduler.loadInstances(ec2client);
+ // If there are no instances created at this point return the imageId
+ if(instanceList.isEmpty()){
+ return imageId;
+ }
+
+ for (Instance instance : instanceList) {
+ String instanceImageId = instance.getImageId();
+ String instanceId = instance.getInstanceId();
+ double avgCPUUtilization = AmazonInstanceScheduler.monitorInstance(credential, instanceId);
+
+ System.out.println("Image id : " + instanceImageId);
+ System.out.println("Instance id : " + instanceId);
+ System.out.println("CPU Utilization : " + avgCPUUtilization);
+
+ //Storing the instance id, if that particular instance was created by the given AMI(imageId)
+ if(imageId.equalsIgnoreCase(instanceImageId)) {
+ instanceUtilMap.put(instanceId, avgCPUUtilization);
+ }
+ }
+
+ // Selects the instance with minimum CPU utilization
+ Map.Entry<String, Double> min = null;
+ for (Map.Entry<String, Double> entry : instanceUtilMap.entrySet()) {
+ if (min == null || min.getValue() > entry.getValue()) {
+ min = entry;
+ }
+ }
+
+ if((min!=null) && (min.getValue()<80)) {
+ System.out.println("Use the existing instance " + min.getKey() + " with CPU Utilization : " + min.getValue());
+ return min.getKey();
+ } else {
+ System.out.println("Create a new instance using AMI : " + imageId);
+ return imageId;
+ }
+ }
+
+}
+
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/SchedulingAlgorithm.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/SchedulingAlgorithm.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/SchedulingAlgorithm.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/SchedulingAlgorithm.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,36 @@
+/*
+ *
+ * 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.gfac.ec2;
+
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+public interface SchedulingAlgorithm {
+
+ String getScheduledAmazonInstance(AmazonEC2Client ec2client, String imageId, AWSCredentials credential)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, IOException;
+}
+
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/AmazonEC2Util.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/AmazonEC2Util.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/AmazonEC2Util.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/AmazonEC2Util.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,118 @@
+/*
+ *
+ * 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.gfac.ec2.util;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.*;
+import org.apache.airavata.gfac.context.JobExecutionContext;
+import org.apache.airavata.gfac.notification.events.EC2ProviderEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/* This class holds the commonly used methods to communicate with Amazon EC2 environment*/
+public class AmazonEC2Util {
+
+ public static final int SLEEP_TIME_SECOND = 120;
+
+ /**
+ * Starts an Amazon instance with the given information.
+ *
+ * @param ec2 Amazon ec2 client
+ * @param amiId Amazon Machine Image (AMI) id
+ * @param insType Instance type
+ * @param jobExecutionContext Job Execution context
+ * @param keyPairName Key pair name
+ * @return list of instances
+ * @throws AmazonServiceException AmazonServiceException
+ */
+ public static List<Instance> startInstances(AmazonEC2Client ec2, String amiId, String insType,
+ JobExecutionContext jobExecutionContext, String keyPairName)
+ throws AmazonServiceException {
+ // start only 1 instance
+ RunInstancesRequest request = new RunInstancesRequest(amiId, 1, 1);
+ request.setKeyName(keyPairName);
+ request.setInstanceType(insType);
+
+ RunInstancesResult result = ec2.runInstances(request);
+
+ List<Instance> instances = result.getReservation().getInstances();
+
+ while (!allInstancesStateEqual(instances, InstanceStateName.Running)) {
+
+ // instance status should not be Terminated
+ if (anyInstancesStateEqual(instances, InstanceStateName.Terminated)) {
+ throw new AmazonClientException("Some Instance is terminated before running a job");
+ }
+
+ // notify the status
+ for (Instance ins: instances) {
+ jobExecutionContext.getNotificationService().publish(new EC2ProviderEvent("EC2 Instance " +
+ ins.getInstanceId() + " is " + ins.getState().getName()));
+ }
+
+ try {
+ Thread.sleep(SLEEP_TIME_SECOND * 1000l);
+ } catch (Exception ex) {
+ // no op
+ }
+
+ DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest();
+ describeInstancesRequest.setInstanceIds(getInstanceIDs(instances));
+
+ DescribeInstancesResult describeInstancesResult = ec2.describeInstances(describeInstancesRequest);
+ instances = describeInstancesResult.getReservations().get(0).getInstances();
+ }
+
+ return instances;
+ }
+
+ public static boolean anyInstancesStateEqual(List<Instance> instances, InstanceStateName name) {
+ for (Instance instance : instances) {
+ // if one of instance is not running, return false
+ if (InstanceStateName.fromValue(instance.getState().getName()) == name) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean allInstancesStateEqual(List<Instance> instances, InstanceStateName name) {
+ for (Instance instance : instances) {
+ // if one of instance is not running, return false
+ if (InstanceStateName.fromValue(instance.getState().getName()) != name) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static List<String> getInstanceIDs(List<Instance> instances) {
+ List<String> ret = new ArrayList<String>();
+ for (Instance instance : instances) {
+ ret.add(instance.getInstanceId());
+ }
+ return ret;
+ }
+}
Added: airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/EC2ProviderUtil.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/EC2ProviderUtil.java?rev=1549966&view=auto
==============================================================================
--- airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/EC2ProviderUtil.java (added)
+++ airavata/trunk/modules/gfac/gfac-ec2/src/main/java/org/apache/airavata/gfac/ec2/util/EC2ProviderUtil.java Tue Dec 10 20:52:23 2013
@@ -0,0 +1,172 @@
+/*
+ *
+ * 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.gfac.ec2.util;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.AmazonServiceException;
+import com.amazonaws.services.ec2.AmazonEC2Client;
+import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
+import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
+import com.amazonaws.services.ec2.model.ImportKeyPairRequest;
+import com.sshtools.j2ssh.util.Base64;
+import org.bouncycastle.openssl.PEMWriter;
+
+import java.io.*;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+/*This class holds the utility methods used for the EC2Provider*/
+public class EC2ProviderUtil {
+
+ /**
+ * Builds a key pair with the given AmazonEC2Client and the generated key will have
+ * the name keyPairName.
+ *
+ * @param ec2 ec2client
+ * @param keyPairName name for the generated key pair
+ * @throws NoSuchAlgorithmException NoSuchAlgorithmException
+ * @throws InvalidKeySpecException InvalidKeySpecException
+ * @throws AmazonServiceException AmazonServiceException
+ * @throws AmazonClientException AmazonClientException
+ * @throws IOException IOException
+ */
+ public static void buildKeyPair(AmazonEC2Client ec2, String keyPairName)
+ throws NoSuchAlgorithmException, InvalidKeySpecException,
+ AmazonServiceException, AmazonClientException, IOException {
+ boolean newKey = false;
+
+ String privateKeyFilePath = System.getProperty("user.home") + "/.ssh/" + keyPairName;
+ File privateKeyFile = new File(privateKeyFilePath);
+ File publicKeyFile = new File(privateKeyFilePath + ".pub");
+
+ /* Check if Key-pair already created on the server */
+ if (!privateKeyFile.exists()) {
+
+ // check folder and create if it does not exist
+ File sshDir = new File(System.getProperty("user.home") + "/.ssh/");
+ if (!sshDir.exists())
+ sshDir.mkdir();
+
+ // Generate a 1024-bit RSA key pair
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
+ keyGen.initialize(1024);
+ KeyPair keypair = keyGen.genKeyPair();
+
+ FileOutputStream fos = null;
+
+ // Store Public Key.
+ try {
+ fos = new FileOutputStream(privateKeyFilePath + ".pub");
+ fos.write(Base64.encodeBytes(keypair.getPublic().getEncoded(), true).getBytes());
+ } catch (IOException ioe) {
+ throw ioe;
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ fos = null;
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+ }
+
+ // Store Private Key.
+ try {
+ fos = new FileOutputStream(privateKeyFilePath);
+ StringWriter stringWriter = new StringWriter();
+
+ /* Write in PEM format (openssl support) */
+ PEMWriter pemFormatWriter = new PEMWriter(stringWriter);
+ pemFormatWriter.writeObject(keypair.getPrivate());
+ pemFormatWriter.close();
+ fos.write(stringWriter.toString().getBytes());
+ } catch (IOException ioe) {
+ throw ioe;
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ fos = null;
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+ }
+
+ privateKeyFile.setWritable(false, false);
+ privateKeyFile.setExecutable(false, false);
+ privateKeyFile.setReadable(false, false);
+ privateKeyFile.setReadable(true);
+ privateKeyFile.setWritable(true);
+
+ // set that this key is just created
+ newKey = true;
+ }
+
+ /* Read Public Key */
+ String encodedPublicKey = null;
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new FileReader(publicKeyFile));
+ encodedPublicKey = br.readLine();
+ } catch (IOException ioe) {
+ throw ioe;
+ } finally {
+ if (br != null) {
+ try {
+ br.close();
+ br = null;
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+ }
+
+ /* Generate key pair in Amazon if necessary */
+ try {
+ /* Get current key pair in Amazon */
+ DescribeKeyPairsRequest describeKeyPairsRequest = new DescribeKeyPairsRequest();
+ ec2.describeKeyPairs(describeKeyPairsRequest.withKeyNames(keyPairName));
+
+ /* If key exists and new key is created, delete old key and replace
+ * with new one. Else, do nothing */
+ if (newKey) {
+ DeleteKeyPairRequest deleteKeyPairRequest = new DeleteKeyPairRequest(keyPairName);
+ ec2.deleteKeyPair(deleteKeyPairRequest);
+ ImportKeyPairRequest importKeyPairRequest = new ImportKeyPairRequest(keyPairName, encodedPublicKey);
+ ec2.importKeyPair(importKeyPairRequest);
+ }
+
+ } catch (AmazonServiceException ase) {
+ /* Key doesn't exists, import new key. */
+ if (ase.getErrorCode().equals("InvalidKeyPair.NotFound")) {
+ ImportKeyPairRequest importKeyPairRequest = new ImportKeyPairRequest(keyPairName, encodedPublicKey);
+ ec2.importKeyPair(importKeyPairRequest);
+ } else {
+ throw ase;
+ }
+ }
+ }
+}
\ No newline at end of file