Add the aws lb extension

Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/c59529a8
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/c59529a8
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/c59529a8

Branch: refs/heads/stratos-4.1.x
Commit: c59529a897266c1ca8759ae7cbdb81d3ed7a55c8
Parents: 4eec2ff
Author: gayangunarathne <[email protected]>
Authored: Fri Oct 9 20:31:03 2015 +0530
Committer: gayangunarathne <[email protected]>
Committed: Fri Oct 9 20:31:52 2015 +0530

----------------------------------------------------------------------
 .../load/balancer/common/domain/Member.java     |   9 +
 .../load-balancer/aws-extension/INSTALL.md      |  45 +
 .../load-balancer/aws-extension/README.md       |   5 +
 extensions/load-balancer/aws-extension/pom.xml  | 119 +++
 .../aws-extension/src/main/assembly/bin.xml     |  91 ++
 .../aws-extension/src/main/bin/aws-extension.sh |  44 +
 .../aws-extension/src/main/conf/aws.properties  |  15 +
 .../aws-extension/src/main/conf/jndi.properties |  22 +
 .../src/main/conf/log4j.properties              |  40 +
 .../src/main/conf/thrift-client-config.xml      |  27 +
 .../aws/extension/AWSExtensionContext.java      | 101 ++
 .../apache/stratos/aws/extension/AWSHelper.java | 926 +++++++++++++++++++
 .../stratos/aws/extension/AWSLoadBalancer.java  | 305 ++++++
 .../aws/extension/AWSStatisticsReader.java      |  89 ++
 .../apache/stratos/aws/extension/Constants.java |  56 ++
 .../org/apache/stratos/aws/extension/Main.java  |  90 ++
 .../aws-extension/src/main/license/LICENSE      | 481 ++++++++++
 .../aws-extension/src/main/notice/NOTICE        | 395 ++++++++
 .../src/main/security/client-truststore.jks     | Bin 0 -> 35240 bytes
 19 files changed, 2860 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/domain/Member.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/domain/Member.java
 
b/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/domain/Member.java
index 953dabd..c0422da 100644
--- 
a/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/domain/Member.java
+++ 
b/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/domain/Member.java
@@ -33,6 +33,7 @@ public class Member {
     private String memberId;
     private String hostName;
     private Map<Integer, Port> portMap;
+    private String instanceId;
 
     public Member(String serviceName, String clusterId, String memberId, 
String hostName) {
         this.serviceName = serviceName;
@@ -86,4 +87,12 @@ public class Member {
     public String getServiceName() {
         return serviceName;
     }
+
+    public String getInstanceId() {
+        return instanceId;
+    }
+
+    public void setInstanceId(String instanceId) {
+        this.instanceId = instanceId;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/INSTALL.md
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/aws-extension/INSTALL.md 
b/extensions/load-balancer/aws-extension/INSTALL.md
new file mode 100644
index 0000000..0ab671f
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/INSTALL.md
@@ -0,0 +1,45 @@
+ #
+ # 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.
+ #
+
+# Installing Apache Stratos AWS Extension
+
+Apache Stratos AWS Extension could be used for integrating AWS load balancer 
with Apache Stratos. Please follow
+below steps to proceed with the installation:
+
+1. Extract org.apache.stratos.aws.extension-<version>.zip to a desired 
location: <aws-extension-home>.
+
+2. Open <aws-extension-home>/conf/aws-credentials.conf file in text editor and 
update AWS access key and secret key information.
+
+3. Open <aws-extension-home>/bin/aws-extension.sh file in a text editor and 
update following system properties:
+   ```
+   # Enable/disable cep statistics publisher:
+   -Dcep.stats.publisher.enabled=false
+
+   # If cep statistics publisher is enabled define the following properties:
+   -Dthrift.receiver.ip=127.0.0.1
+   -Dthrift.receiver.port=7615
+   -Dnetwork.partition.id=network-partition-1
+   ```
+
+4. Open <aws-extension-home>/conf/jndi.properties file in a text editor and 
update message broker information:
+   ```
+   java.naming.provider.url=tcp://localhost:61616
+   ```
+5. Run <aws-extension-home>/bin/aws-extension.sh as the root user.
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/README.md
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/aws-extension/README.md 
b/extensions/load-balancer/aws-extension/README.md
new file mode 100644
index 0000000..75fa622
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/README.md
@@ -0,0 +1,5 @@
+# Apache Stratos AWS Extension
+
+Apache Stratos AWS extension is a load balancer extension for Amazon Web 
Services (AWS). It is an executable program
+which can manage AWS laod balancers according to the topology, composite 
application model, tenant application signups 
+and domain mapping information received from Stratos via the message broker.

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/pom.xml
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/aws-extension/pom.xml 
b/extensions/load-balancer/aws-extension/pom.xml
new file mode 100644
index 0000000..65dc8fb
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/pom.xml
@@ -0,0 +1,119 @@
+<?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>
+    <groupId>org.apache.stratos</groupId>
+    <artifactId>stratos-load-balancer-extensions</artifactId>
+    <version>4.1.4-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>org.apache.stratos.aws.extension</artifactId>
+  <name>Apache Stratos - AWS Extension</name>
+  <description>Apache Stratos AWS Extension for Load Balancing</description>
+  <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.7.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.stratos</groupId>
+            <artifactId>org.apache.stratos.common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.stratos</groupId>
+            <artifactId>org.apache.stratos.messaging</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.stratos</groupId>
+            
<artifactId>org.apache.stratos.load.balancer.extension.api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity</artifactId>
+            <version>1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.wso2.andes.wso2</groupId>
+            <artifactId>andes-client</artifactId>
+            <version>0.13.wso2v8</version>
+        </dependency>
+        <dependency>
+          <groupId>com.amazonaws</groupId>
+          <artifactId>aws-java-sdk</artifactId>
+          <version>1.8.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents.wso2</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.2.5.wso2v1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.4</version>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            
<mainClass>org.apache.stratos.aws.extension.Main</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <configuration>
+                    <descriptors>
+                        <descriptor>src/main/assembly/bin.xml</descriptor>
+                    </descriptors>
+                    <archiverConfig>
+                        <fileMode>420</fileMode>
+                        <directoryMode>493</directoryMode>
+                        <defaultDirectoryMode>493</defaultDirectoryMode>
+                    </archiverConfig>
+                    <appendAssemblyId>false</appendAssemblyId>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>attached</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml 
b/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
new file mode 100644
index 0000000..ba0ad12
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/assembly/bin.xml
@@ -0,0 +1,91 @@
+<!--
+  ~ 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.
+  -->
+
+<assembly 
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0";
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+          
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0
 http://maven.apache.org/xsd/assembly-1.1.0.xsd";>
+    <id>bin</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <fileSets>
+        <fileSet>
+            <directory>${project.basedir}/src/main/bin</directory>
+            <outputDirectory>/bin</outputDirectory>
+            <fileMode>0755</fileMode>
+            <includes>
+                <include>aws-extension.sh</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/conf</directory>
+            <outputDirectory>/conf</outputDirectory>
+            <fileMode>0600</fileMode>
+            <includes>
+                <include>jndi.properties</include>
+                <include>log4j.properties</include>
+                <include>thrift-client-config.xml</include>
+                <include>aws.properties</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/security</directory>
+            <outputDirectory>/security</outputDirectory>
+            <fileMode>0600</fileMode>
+            <includes>
+                <include>client-truststore.jks</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}</directory>
+            <outputDirectory>/</outputDirectory>
+            <fileMode>0600</fileMode>
+            <includes>
+                <include>DISCLAIMER</include>
+                <include>README*</include>
+                <include>LICENSE*</include>
+                <include>INSTALL*</include>
+            </includes>
+        </fileSet>
+       <fileSet>
+            <directory>${project.basedir}/src/main/license</directory>
+            <outputDirectory>/</outputDirectory>
+            <fileMode>0600</fileMode>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/notice</directory>
+            <outputDirectory>/</outputDirectory>
+            <fileMode>0600</fileMode>
+        </fileSet>
+    </fileSets>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/lib</outputDirectory>
+           <excludes>
+                <exclude>*:icu4j*</exclude>
+                <exclude>*:jaxen*</exclude>
+                <exclude>*:jboss-transaction-api*</exclude>
+                <exclude>*:wrapper*</exclude>
+                <exclude>*:xom*</exclude>
+            </excludes>
+            <useProjectArtifact>true</useProjectArtifact>
+            <scope>runtime</scope>
+        </dependencySet>
+    </dependencySets>
+</assembly>

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh 
b/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
new file mode 100755
index 0000000..19936ae
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/bin/aws-extension.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# --------------------------------------------------------------
+#
+# 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.
+#
+# --------------------------------------------------------------
+
+echo "Starting aws extension..."
+script_path="$( cd -P "$( dirname "$SOURCE" )" && pwd )/`dirname $0`"
+lib_path=${script_path}/../lib/
+class_path=`echo ${lib_path}/*.jar | tr ' ' ':'`
+properties="-Djndi.properties.dir=${script_path}/../conf
+            
-Dlog4j.properties.file.path=${script_path}/../conf/log4j.properties
+            -Daws.properties.file=${script_path}/../conf/aws.properties
+            
-Djavax.net.ssl.trustStore=${script_path}/../security/client-truststore.jks
+            -Djavax.net.ssl.trustStorePassword=wso2carbon
+            
-Dthrift.client.config.file.path=${script_path}/../conf/thrift-client-config.xml
+            -Dcep.stats.publisher.enabled=false
+            -Dthrift.receiver.ip=127.0.0.1
+            -Dthrift.receiver.port=7615
+            -Dnetwork.partition.id=network-partition-1
+            -Dcluster.id=cluster-1
+            -Dservice.name=service-1"
+
+
+# Uncomment below line to enable remote debugging
+#debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
+
+java -cp "${class_path}" ${properties} ${debug} 
org.apache.stratos.aws.extension.Main $*

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/conf/aws.properties 
b/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
new file mode 100644
index 0000000..2bb2879
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/conf/aws.properties
@@ -0,0 +1,15 @@
+access-key=
+secret-key=
+# load-balancer-prefix should contain only alphabets and dashes and should not 
exceed 25 characters.
+load-balancer-prefix=LB-
+# security group will be created if does not exist. Should contain only ASCII 
characters and should not exceed 255 characters.
+load-balancer-security-group-name=lb-security-group
+# CIDR IP which can be set as allowed source IP of incoming requests for 
security group mentioned in 'load-balancer-security-group-name'
+# 0.0.0.0/0 allows all IPs
+allowed-cidr-ip=0.0.0.0/0
+# Internet Protocol allowed for incoming requests for security group mentioned 
in 'load-balancer-security-group-name'. 
+# Comma separated e.g. tcp,udp
+allowed-protocols=tcp
+# statistics-interval denotes the interval in seconds for which statistics are 
gathered to calculate request in flight count.
+# This must be multiple of 60.
+statistics-interval=60

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/conf/jndi.properties
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/conf/jndi.properties 
b/extensions/load-balancer/aws-extension/src/main/conf/jndi.properties
new file mode 100644
index 0000000..21d7420
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/conf/jndi.properties
@@ -0,0 +1,22 @@
+#
+# 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.
+#
+
+connectionfactoryName=TopicConnectionFactory
+java.naming.provider.url=tcp://localhost:61616
+java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/conf/log4j.properties
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/conf/log4j.properties 
b/extensions/load-balancer/aws-extension/src/main/conf/log4j.properties
new file mode 100644
index 0000000..fe9ca61
--- /dev/null
+++ b/extensions/load-balancer/aws-extension/src/main/conf/log4j.properties
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+# Set root logger level and appenders
+log4j.rootLogger=INFO, CONSOLE_APPENDER, FILE_APPENDER
+
+# CONSOLE_APPENDER is set to be a ConsoleAppender.
+log4j.appender.CONSOLE_APPENDER=org.apache.log4j.ConsoleAppender
+
+# The standard error log where all the warnings, errors and fatal errors will 
be logged
+log4j.appender.FILE_APPENDER=org.apache.log4j.FileAppender
+log4j.appender.FILE_APPENDER.File=logs/aws-extension.log
+log4j.appender.FILE_APPENDER.layout=org.apache.log4j.PatternLayout
+log4j.appender.FILE_APPENDER.layout.ConversionPattern=%d{ISO8601} 
[%X{ip}-%X{host}] [%t] %5p %c{1} %m%n
+log4j.appender.FILE_APPENDER.threshold=DEBUG
+
+# CONSOLE_APPENDER uses PatternLayout.
+log4j.appender.CONSOLE_APPENDER.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE_APPENDER.layout.ConversionPattern=[%d{ISO8601}] %5p - 
[%c{1}] %m%n
+
+log4j.logger.org.apache.stratos.aws.extension=INFO
+log4j.logger.org.apache.stratos.load.balancer.extension.api=INFO
+log4j.logger.org.apache.stratos.messaging=INFO
+log4j.logger.org.wso2.andes.client=ERROR
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/conf/thrift-client-config.xml
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/conf/thrift-client-config.xml 
b/extensions/load-balancer/aws-extension/src/main/conf/thrift-client-config.xml
new file mode 100644
index 0000000..5cacada
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/conf/thrift-client-config.xml
@@ -0,0 +1,27 @@
+<?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.
+  -->
+
+<!-- Apache thrift client configuration for publishing statistics to WSO2 CEP 
-->
+<thriftClientConfiguration>
+    <username>admin</username>
+    <password>admin</password>
+    <ip>localhost</ip>
+    <port>7611</port>
+</thriftClientConfiguration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java
new file mode 100644
index 0000000..d3da969
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java
@@ -0,0 +1,101 @@
+/*
+ * 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.stratos.aws.extension;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * AWS Load Balancer context to read and store system properties.
+ */
+public class AWSExtensionContext {
+    private static final Log log = 
LogFactory.getLog(AWSExtensionContext.class);
+    private static volatile AWSExtensionContext context;
+
+    private boolean cepStatsPublisherEnabled;
+    private String thriftReceiverIp;
+    private String thriftReceiverPort;
+    private String networkPartitionId;
+    private String clusterId;
+    private String serviceName;
+
+    private AWSExtensionContext() {
+        this.cepStatsPublisherEnabled = 
Boolean.getBoolean(Constants.CEP_STATS_PUBLISHER_ENABLED);
+        this.thriftReceiverIp = 
System.getProperty(Constants.THRIFT_RECEIVER_IP);
+        this.thriftReceiverPort = 
System.getProperty(Constants.THRIFT_RECEIVER_PORT);
+        this.networkPartitionId = 
System.getProperty(Constants.NETWORK_PARTITION_ID);
+        this.clusterId = System.getProperty(Constants.CLUSTER_ID);
+        this.serviceName = System.getProperty(Constants.SERVICE_NAME);
+
+        if (log.isDebugEnabled()) {
+            log.debug(Constants.CEP_STATS_PUBLISHER_ENABLED + " = " + 
cepStatsPublisherEnabled);
+            log.debug(Constants.THRIFT_RECEIVER_IP + " = " + thriftReceiverIp);
+            log.debug(Constants.THRIFT_RECEIVER_PORT + " = " + 
thriftReceiverPort);
+            log.debug(Constants.NETWORK_PARTITION_ID + " = " + 
networkPartitionId);
+            log.debug(Constants.CLUSTER_ID + " = " + clusterId);
+        }
+    }
+
+    public static AWSExtensionContext getInstance() {
+        if (context == null) {
+            synchronized (AWSExtensionContext.class) {
+                if (context == null) {
+                    context = new AWSExtensionContext();
+                }
+            }
+        }
+        return context;
+    }
+
+    public void validate() {
+        validateSystemProperty(Constants.CEP_STATS_PUBLISHER_ENABLED);
+        validateSystemProperty(Constants.CLUSTER_ID);
+
+        if (cepStatsPublisherEnabled) {
+            validateSystemProperty(Constants.THRIFT_RECEIVER_IP);
+            validateSystemProperty(Constants.THRIFT_RECEIVER_PORT);
+            validateSystemProperty(Constants.NETWORK_PARTITION_ID);
+        }
+    }
+
+    private void validateSystemProperty(String propertyName) {
+        String value = System.getProperty(propertyName);
+        if (StringUtils.isEmpty(value)) {
+            throw new RuntimeException("System property was not found: " + 
propertyName);
+        }
+    }
+
+    public boolean isCEPStatsPublisherEnabled() {
+        return cepStatsPublisherEnabled;
+    }
+
+    public String getNetworkPartitionId() {
+        return networkPartitionId;
+    }
+
+    public String getClusterId() {
+        return clusterId;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
new file mode 100644
index 0000000..a8164e7
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java
@@ -0,0 +1,926 @@
+/*
+ * 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.stratos.aws.extension;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.load.balancer.common.domain.*;
+import 
org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.ClientConfiguration;
+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.AuthorizeSecurityGroupIngressRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
+import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
+import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
+import com.amazonaws.services.ec2.model.IpPermission;
+import com.amazonaws.services.ec2.model.SecurityGroup;
+import 
com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
+import com.amazonaws.services.elasticloadbalancing.model.*;
+
+public class AWSHelper {
+       private String awsAccessKey;
+       private String awsSecretKey;
+       private String lbPrefix;
+       private String lbSecurityGroupName;
+       private String lbSecurityGroupDescription;
+       private String allowedCidrIpForLBSecurityGroup;
+       private int statisticsInterval;
+
+       private AtomicInteger lbSequence;
+
+       private List<String> allowedProtocolsForLBSecurityGroup;
+
+       private ConcurrentHashMap<String, String> regionToSecurityGroupIdMap;
+
+       private BasicAWSCredentials awsCredentials;
+       private ClientConfiguration clientConfiguration;
+
+       AmazonElasticLoadBalancingClient elbClient;
+       AmazonEC2Client ec2Client;
+       private AmazonCloudWatchClient cloudWatchClient;
+
+       private static final Log log = LogFactory.getLog(AWSHelper.class);
+
+       public AWSHelper() throws LoadBalancerExtensionException {
+               // Read values for awsAccessKey, awsSecretKey etc. from config 
file
+
+               String awsPropertiesFile = System
+                               .getProperty(Constants.AWS_PROPERTIES_FILE);
+
+               Properties properties = new Properties();
+
+               InputStream inputStream = null;
+
+               try {
+                       inputStream = new FileInputStream(awsPropertiesFile);
+
+                       properties.load(inputStream);
+
+                       this.awsAccessKey = properties
+                                       .getProperty(Constants.AWS_ACCESS_KEY);
+                       this.awsSecretKey = properties
+                                       .getProperty(Constants.AWS_SECRET_KEY);
+
+                       if (this.awsAccessKey.isEmpty() || 
this.awsSecretKey.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid AWS credentials.");
+                       }
+
+                       this.lbPrefix = 
properties.getProperty(Constants.LB_PREFIX);
+
+                       if (this.lbPrefix.isEmpty()
+                                       || this.lbPrefix.length() > 
Constants.LOAD_BALANCER_PREFIX_MAX_LENGTH) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid load balancer 
prefix.");
+                       }
+
+                       lbSequence = new AtomicInteger(1);
+
+                       this.lbSecurityGroupName = properties
+                                       
.getProperty(Constants.LOAD_BALANCER_SECURITY_GROUP_NAME);
+
+                       if (this.lbSecurityGroupName.isEmpty()
+                                       || this.lbSecurityGroupName.length() > 
Constants.SECURITY_GROUP_NAME_MAX_LENGTH) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid load balancer security 
group name.");
+                       }
+
+                       this.allowedCidrIpForLBSecurityGroup = properties
+                                       
.getProperty(Constants.ALLOWED_CIDR_IP_KEY);
+
+                       if (this.allowedCidrIpForLBSecurityGroup.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Invalid allowed CIDR IP.");
+                       }
+
+                       String allowedProtocols = properties
+                                       
.getProperty(Constants.ALLOWED_PROTOCOLS);
+
+                       if (allowedProtocols.isEmpty()) {
+                               throw new LoadBalancerExtensionException(
+                                               "Please specify at least one 
Internet protocol.");
+                       }
+
+                       String[] protocols = allowedProtocols.split(",");
+
+                       this.allowedProtocolsForLBSecurityGroup = new 
ArrayList<String>();
+
+                       for (String protocol : protocols) {
+                               
this.allowedProtocolsForLBSecurityGroup.add(protocol);
+                       }
+
+                       String interval = properties
+                                       
.getProperty(Constants.STATISTICS_INTERVAL);
+
+                       if (interval == null || interval.isEmpty()) {
+                               this.statisticsInterval = 
Constants.STATISTICS_INTERVAL_MULTIPLE_OF;
+                       } else {
+                               try {
+                                       this.statisticsInterval = 
Integer.parseInt(interval);
+
+                                       if (this.statisticsInterval
+                                                       % 
Constants.STATISTICS_INTERVAL_MULTIPLE_OF != 0) {
+                                               this.statisticsInterval = 
Constants.STATISTICS_INTERVAL_MULTIPLE_OF;
+                                       }
+                               } catch (NumberFormatException e) {
+                                       log.warn("Invalid statistics interval. 
Setting it to 15.");
+                                       this.statisticsInterval = 15;
+                               }
+                       }
+
+                       this.lbSecurityGroupDescription = 
Constants.LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION;
+
+                       regionToSecurityGroupIdMap = new 
ConcurrentHashMap<String, String>();
+
+                       awsCredentials = new BasicAWSCredentials(awsAccessKey, 
awsSecretKey);
+                       clientConfiguration = new ClientConfiguration();
+
+                       elbClient = new 
AmazonElasticLoadBalancingClient(awsCredentials,
+                                       clientConfiguration);
+
+                       ec2Client = new AmazonEC2Client(awsCredentials, 
clientConfiguration);
+
+                       cloudWatchClient = new 
AmazonCloudWatchClient(awsCredentials,
+                                       clientConfiguration);
+
+               } catch (IOException e) {
+                       log.error("Error reading aws configuration file.");
+                       throw new LoadBalancerExtensionException(
+                                       "Error reading aws configuration 
file.", e);
+               } finally {
+                       try {
+                               inputStream.close();
+                       } catch (Exception e) {
+                               log.warn("Failed to close input stream to aws 
configuration file.");
+                       }
+               }
+       }
+
+       public int getStatisticsInterval() {
+               return statisticsInterval;
+       }
+
+       public int getNextLBSequence() {
+               return lbSequence.getAndIncrement();
+       }
+
+       public String getLbSecurityGroupName() {
+               return lbSecurityGroupName;
+       }
+
+       public List<String> getAllowedProtocolsForLBSecurityGroup() {
+               return allowedProtocolsForLBSecurityGroup;
+       }
+
+       /**
+        * Creates a load balancer and returns its DNS name. Useful when a new
+        * cluster is added.
+        * 
+        * @param name
+        *            of the load balancer to be created
+        * @param listeners
+        *            to be attached to the load balancer
+        * @param region
+        *            in which the load balancer needs to be created
+        * @return DNS name of newly created load balancer
+        * @throws LoadBalancerExtensionException
+        */
+       public String createLoadBalancer(String name, List<Listener> listeners,
+                       String region) throws LoadBalancerExtensionException {
+
+               log.info("Creating load balancer " + name);
+
+               CreateLoadBalancerRequest createLoadBalancerRequest = new 
CreateLoadBalancerRequest(
+                               name);
+
+               createLoadBalancerRequest.setListeners(listeners);
+
+               Set<String> availabilityZones = new HashSet<String>();
+               availabilityZones.add(getAvailabilityZoneFromRegion(region));
+
+               
createLoadBalancerRequest.setAvailabilityZones(availabilityZones);
+
+               try {
+                       String securityGroupId = 
getSecurityGroupIdForRegion(region);
+
+                       List<String> securityGroups = new ArrayList<String>();
+                       securityGroups.add(securityGroupId);
+
+                       
createLoadBalancerRequest.setSecurityGroups(securityGroups);
+
+                       elbClient.setEndpoint(String.format(
+                                       Constants.ELB_ENDPOINT_URL_FORMAT, 
region));
+
+                       CreateLoadBalancerResult clbResult = elbClient
+                                       
.createLoadBalancer(createLoadBalancerRequest);
+
+                       return clbResult.getDNSName();
+
+               } catch (AmazonClientException e) {
+                       throw new LoadBalancerExtensionException(
+                                       "Could not create load balancer " + 
name, e);
+               }
+       }
+
+       /**
+        * Deletes the load balancer with the name provided. Useful when a 
cluster,
+        * with which this load balancer was associated, is removed.
+        * 
+        * @param loadBalancerName
+        *            to be deleted
+        * @param region
+        *            of the laod balancer
+        */
+       public void deleteLoadBalancer(String loadBalancerName, String region) {
+
+               log.info("Deleting load balancer " + loadBalancerName);
+
+               DeleteLoadBalancerRequest deleteLoadBalancerRequest = new 
DeleteLoadBalancerRequest();
+               deleteLoadBalancerRequest.setLoadBalancerName(loadBalancerName);
+
+               try {
+                       elbClient.setEndpoint(String.format(
+                                       Constants.ELB_ENDPOINT_URL_FORMAT, 
region));
+
+                       elbClient.deleteLoadBalancer(deleteLoadBalancerRequest);
+                       log.info("Deleted load balancer " + loadBalancerName);
+               } catch (AmazonClientException e) {
+                       log.error("Could not delete load balancer : " + 
loadBalancerName, e);
+               }
+       }
+
+       /**
+        * Attaches provided instances to the load balancer. Useful when new
+        * instances get added to the cluster with which this load balancer is
+        * associated.
+        * 
+        * @param loadBalancerName
+        * @param instances
+        *            to attached to the load balancer
+        * @param region
+        *            of the load balancer
+        */
+       public void registerInstancesToLoadBalancer(String loadBalancerName,
+                       List<Instance> instances, String region) {
+
+               log.info("Registering following instance(s) to load balancer "
+                               + loadBalancerName);
+
+               for (Instance instance : instances) {
+                       log.info(instance.getInstanceId());
+               }
+
+               RegisterInstancesWithLoadBalancerRequest 
registerInstancesWithLoadBalancerRequest = new 
RegisterInstancesWithLoadBalancerRequest(
+                               loadBalancerName, instances);
+
+               try {
+                       elbClient.setEndpoint(String.format(
+                                       Constants.ELB_ENDPOINT_URL_FORMAT, 
region));
+
+                       elbClient
+                                       
.registerInstancesWithLoadBalancer(registerInstancesWithLoadBalancerRequest);
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not register instances to load 
balancer "
+                                       + loadBalancerName, e);
+               }
+       }
+
+       /**
+        * Detaches provided instances from the load balancer, associated with 
some
+        * cluster. Useful when instances are removed from the cluster with 
which
+        * this load balancer is associated.
+        * 
+        * @param loadBalancerName
+        * @param instances
+        *            to be de-registered from load balancer
+        * @param region
+        *            of the load balancer
+        */
+       public void deregisterInstancesFromLoadBalancer(String loadBalancerName,
+                       List<Instance> instances, String region) {
+
+               log.info("De-registering following instance(s) from load 
balancer "
+                               + loadBalancerName);
+
+               for (Instance instance : instances) {
+                       log.info(instance.getInstanceId());
+               }
+
+               DeregisterInstancesFromLoadBalancerRequest 
deregisterInstancesFromLoadBalancerRequest = new 
DeregisterInstancesFromLoadBalancerRequest(
+                               loadBalancerName, instances);
+
+               try {
+                       elbClient.setEndpoint(String.format(
+                                       Constants.ELB_ENDPOINT_URL_FORMAT, 
region));
+
+                       elbClient
+                                       
.deregisterInstancesFromLoadBalancer(deregisterInstancesFromLoadBalancerRequest);
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not de-register instances from load 
balancer "
+                                       + loadBalancerName, e);
+               }
+       }
+
+       /**
+        * Returns description of the load balancer which is helpful in 
determining
+        * instances, listeners associated with load balancer
+        * 
+        * @param loadBalancerName
+        * @param region
+        *            of the load balancer
+        * @return description of the load balancer
+        */
+       private LoadBalancerDescription getLoadBalancerDescription(
+                       String loadBalancerName, String region) {
+
+               List<String> loadBalancers = new ArrayList<String>();
+               loadBalancers.add(loadBalancerName);
+
+               DescribeLoadBalancersRequest describeLoadBalancersRequest = new 
DescribeLoadBalancersRequest(
+                               loadBalancers);
+
+               try {
+                       elbClient.setEndpoint(String.format(
+                                       Constants.ELB_ENDPOINT_URL_FORMAT, 
region));
+
+                       DescribeLoadBalancersResult result = elbClient
+                                       
.describeLoadBalancers(describeLoadBalancersRequest);
+
+                       if (result.getLoadBalancerDescriptions() != null
+                                       && 
result.getLoadBalancerDescriptions().size() > 0)
+                               return 
result.getLoadBalancerDescriptions().get(0);
+               } catch (AmazonClientException e) {
+                       log.error("Could not find description of load balancer "
+                                       + loadBalancerName, e);
+               }
+
+               return null;
+       }
+
+       /**
+        * Returns instances attached to the load balancer. Useful when 
deciding if
+        * all attached instances are required or some should be detached.
+        * 
+        * @param loadBalancerName
+        * @param region
+        * @return list of instances attached
+        */
+       public List<Instance> getAttachedInstances(String loadBalancerName,
+                       String region) {
+               try {
+                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(
+                                       loadBalancerName, region);
+
+                       if (lbDescription == null) {
+                               log.warn("Could not find description of load 
balancer "
+                                               + loadBalancerName);
+                               return null;
+                       }
+
+                       return lbDescription.getInstances();
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not find instances attached  load 
balancer "
+                                       + loadBalancerName, e);
+                       return null;
+               }
+       }
+
+       /**
+        * Returns all the listeners attached to the load balancer. Useful while
+        * deciding if all the listeners are necessary or some should be 
removed.
+        * 
+        * @param loadBalancerName
+        * @param region
+        * @return list of instances attached to load balancer
+        */
+       public List<Listener> getAttachedListeners(String loadBalancerName,
+                       String region) {
+               try {
+                       LoadBalancerDescription lbDescription = 
getLoadBalancerDescription(
+                                       loadBalancerName, region);
+
+                       if (lbDescription == null) {
+                               log.warn("Could not find description of load 
balancer "
+                                               + loadBalancerName);
+                               return null;
+                       }
+
+                       List<Listener> listeners = new ArrayList<Listener>();
+
+                       List<ListenerDescription> listenerDescriptions = 
lbDescription
+                                       .getListenerDescriptions();
+
+                       for (ListenerDescription listenerDescription : 
listenerDescriptions) {
+                               
listeners.add(listenerDescription.getListener());
+                       }
+
+                       return listeners;
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not find description of load balancer "
+                                       + loadBalancerName);
+                       return null;
+               }
+
+       }
+
+       /**
+        * Checks if the security group is already present in the given region. 
If
+        * yes, then returns its group id. If not, present the returns null.
+        * 
+        * @param groupName
+        *            to be checked for presence.
+        * @param region
+        * @return id of the security group
+        */
+       public String getSecurityGroupId(String groupName, String region) {
+               if (groupName == null || groupName.isEmpty()) {
+                       return null;
+               }
+
+               DescribeSecurityGroupsRequest describeSecurityGroupsRequest = 
new DescribeSecurityGroupsRequest();
+
+               List<String> groupNames = new ArrayList<String>();
+               groupNames.add(groupName);
+
+               describeSecurityGroupsRequest.setGroupNames(groupNames);
+
+               try {
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
+
+                       DescribeSecurityGroupsResult 
describeSecurityGroupsResult = ec2Client
+                                       
.describeSecurityGroups(describeSecurityGroupsRequest);
+
+                       List<SecurityGroup> securityGroups = 
describeSecurityGroupsResult
+                                       .getSecurityGroups();
+
+                       if (securityGroups != null && securityGroups.size() > 
0) {
+                               return securityGroups.get(0).getGroupId();
+                       }
+               } catch (AmazonClientException e) {
+                       log.debug("Could not describe security groups.", e);
+               }
+
+               return null;
+       }
+
+       /**
+        * Creates security group with the given name in the given region
+        * 
+        * @param groupName
+        *            to be created
+        * @param description
+        * @param region
+        *            in which the security group to be created
+        * @return Id of the security group created
+        * @throws LoadBalancerExtensionException
+        */
+       public String createSecurityGroup(String groupName, String description,
+                       String region) throws LoadBalancerExtensionException {
+               if (groupName == null || groupName.isEmpty()) {
+                       throw new LoadBalancerExtensionException(
+                                       "Invalid Security Group Name.");
+               }
+
+               CreateSecurityGroupRequest createSecurityGroupRequest = new 
CreateSecurityGroupRequest();
+               createSecurityGroupRequest.setGroupName(groupName);
+               createSecurityGroupRequest.setDescription(description);
+
+               try {
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
+
+                       CreateSecurityGroupResult createSecurityGroupResult = 
ec2Client
+                                       
.createSecurityGroup(createSecurityGroupRequest);
+
+                       return createSecurityGroupResult.getGroupId();
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not create security group.", e);
+                       throw new LoadBalancerExtensionException(
+                                       "Could not create security group.", e);
+               }
+
+       }
+
+       /**
+        * Adds inbound rule to the security group which allows users to access 
load
+        * balancer at specified port and using the specified protocol. Port
+        * specified should be a proxy port mentioned in the port mappings of 
the
+        * cartridge.
+        * 
+        * @param groupId
+        *            to which this rule to be added
+        * @param region
+        *            of the security group
+        * @param protocol
+        *            with which load balancer can be accessed
+        * @param port
+        *            at which load balancer can be accessed
+        * @throws LoadBalancerExtensionException
+        */
+       public void addInboundRuleToSecurityGroup(String groupId, String region,
+                       String protocol, int port) throws 
LoadBalancerExtensionException {
+               if (groupId == null || groupId.isEmpty()) {
+                       throw new LoadBalancerExtensionException(
+                                       "Invalid security group Id for 
addInboundRuleToSecurityGroup.");
+               }
+
+               boolean ruleAlreadyPresent = false;
+
+               DescribeSecurityGroupsRequest describeSecurityGroupsRequest = 
new DescribeSecurityGroupsRequest();
+
+               List<String> groupIds = new ArrayList<String>();
+               groupIds.add(groupId);
+
+               describeSecurityGroupsRequest.setGroupIds(groupIds);
+
+               SecurityGroup secirutyGroup = null;
+
+               try {
+                       ec2Client.setEndpoint(String.format(
+                                       Constants.EC2_ENDPOINT_URL_FORMAT, 
region));
+
+                       DescribeSecurityGroupsResult 
describeSecurityGroupsResult = ec2Client
+                                       
.describeSecurityGroups(describeSecurityGroupsRequest);
+
+                       List<SecurityGroup> securityGroups = 
describeSecurityGroupsResult
+                                       .getSecurityGroups();
+
+                       if (securityGroups != null && securityGroups.size() > 
0) {
+                               secirutyGroup = securityGroups.get(0);
+                       }
+               } catch (AmazonClientException e) {
+                       log.error("Could not describe security groups.", e);
+               }
+
+               if (secirutyGroup != null) {
+                       List<IpPermission> existingPermissions = secirutyGroup
+                                       .getIpPermissions();
+
+                       IpPermission neededPermission = new IpPermission();
+                       neededPermission.setFromPort(port);
+                       neededPermission.setToPort(port);
+                       neededPermission.setIpProtocol(protocol);
+
+                       Collection<String> ipRanges = new HashSet<String>();
+                       ipRanges.add(this.allowedCidrIpForLBSecurityGroup);
+
+                       neededPermission.setIpRanges(ipRanges);
+
+                       if (existingPermissions.contains(neededPermission)) {
+                               ruleAlreadyPresent = true;
+                       }
+               }
+
+               if (!ruleAlreadyPresent) {
+                       AuthorizeSecurityGroupIngressRequest 
authorizeSecurityGroupIngressRequest = new 
AuthorizeSecurityGroupIngressRequest();
+                       
authorizeSecurityGroupIngressRequest.setGroupId(groupId);
+                       authorizeSecurityGroupIngressRequest
+                                       
.setCidrIp(this.allowedCidrIpForLBSecurityGroup);
+                       authorizeSecurityGroupIngressRequest.setFromPort(port);
+                       authorizeSecurityGroupIngressRequest.setToPort(port);
+                       
authorizeSecurityGroupIngressRequest.setIpProtocol(protocol);
+
+                       try {
+                               ec2Client.setEndpoint(String.format(
+                                               
Constants.EC2_ENDPOINT_URL_FORMAT, region));
+
+                               ec2Client
+                                               
.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
+
+                       } catch (AmazonClientException e) {
+                               throw new LoadBalancerExtensionException(
+                                               "Could not add inbound rule to 
security group "
+                                                               + groupId + 
".", e);
+                       }
+               }
+       }
+
+       /**
+        * Returns the security group id for the given region if it is already
+        * present. If it is not already present then creates a new security 
group
+        * in that region.
+        * 
+        * @param region
+        * @return Id of the security group
+        * @throws LoadBalancerExtensionException
+        */
+       public String getSecurityGroupIdForRegion(String region)
+                       throws LoadBalancerExtensionException {
+               if (region == null)
+                       return null;
+
+               if (this.regionToSecurityGroupIdMap.contains(region)) {
+                       return this.regionToSecurityGroupIdMap.get(region);
+               } else {
+                       // Get the the security group id if it is already 
present.
+                       String securityGroupId = getSecurityGroupId(
+                                       this.lbSecurityGroupName, region);
+
+                       if (securityGroupId == null) {
+                               securityGroupId = 
createSecurityGroup(this.lbSecurityGroupName,
+                                               
this.lbSecurityGroupDescription, region);
+                       }
+
+                       this.regionToSecurityGroupIdMap.put(region, 
securityGroupId);
+
+                       return securityGroupId;
+               }
+       }
+
+       /**
+        * Retrieves the total number of requests that were made to the load
+        * balancer during the given time interval in the past
+        * 
+        * @param loadBalancerName
+        * @param region
+        * @param timeInterval
+        *            in seconds which must be multiple of 60
+        * @return number of requests made
+        */
+       public int getRequestCount(String loadBalancerName, String region,
+                       int timeInterval) {
+               int count = 0;
+
+               try {
+                       GetMetricStatisticsRequest request = new 
GetMetricStatisticsRequest();
+                       
request.setMetricName(Constants.REQUEST_COUNT_METRIC_NAME);
+                       
request.setNamespace(Constants.CLOUD_WATCH_NAMESPACE_NAME);
+
+                       Date currentTime = new 
DateTime(DateTimeZone.UTC).toDate();
+                       Date pastTime = new 
DateTime(DateTimeZone.UTC).minusSeconds(
+                                       timeInterval).toDate();
+
+                       request.setStartTime(pastTime);
+                       request.setEndTime(currentTime);
+
+                       request.setPeriod(timeInterval);
+
+                       HashSet<String> statistics = new HashSet<String>();
+                       statistics.add(Constants.SUM_STATISTICS_NAME);
+                       request.setStatistics(statistics);
+
+                       HashSet<Dimension> dimensions = new 
HashSet<Dimension>();
+                       Dimension loadBalancerDimension = new Dimension();
+                       loadBalancerDimension
+                                       
.setName(Constants.LOAD_BALANCER_DIMENTION_NAME);
+                       loadBalancerDimension.setValue(loadBalancerName);
+                       dimensions.add(loadBalancerDimension);
+                       request.setDimensions(dimensions);
+
+                       cloudWatchClient.setEndpoint(String.format(
+                                       
Constants.CLOUD_WATCH_ENDPOINT_URL_FORMAT, region));
+
+                       GetMetricStatisticsResult result = cloudWatchClient
+                                       .getMetricStatistics(request);
+
+                       List<Datapoint> dataPoints = result.getDatapoints();
+
+                       if (dataPoints != null && dataPoints.size() > 0) {
+                               count = dataPoints.get(0).getSum().intValue();
+                       }
+
+               } catch (AmazonClientException e) {
+                       log.error(
+                                       "Could not get request count statistics 
of load balancer "
+                                                       + loadBalancerName, e);
+               }
+
+               return count;
+       }
+
+       /**
+        * Retrieves total number of responses generated by all instances 
attached
+        * to the load balancer during the time interval in the past.
+        * 
+        * @param loadBalancerName
+        * @param region
+        * @param timeInterval
+        *            in seconds which must be multiple of 60
+        * @return number of responses generated
+        */
+       public int getAllResponsesCount(String loadBalancerName, String region,
+                       int timeInterval) {
+               int total = 0;
+
+               Date currentTime = new DateTime(DateTimeZone.UTC).toDate();
+               Date pastTime = new DateTime(DateTimeZone.UTC).minusSeconds(
+                               timeInterval).toDate();
+
+               total += getResponseCountForMetric(loadBalancerName, region,
+                               Constants.HTTP_RESPONSE_2XX, pastTime, 
currentTime,
+                               timeInterval);
+               total += getResponseCountForMetric(loadBalancerName, region,
+                               Constants.HTTP_RESPONSE_3XX, pastTime, 
currentTime,
+                               timeInterval);
+               total += getResponseCountForMetric(loadBalancerName, region,
+                               Constants.HTTP_RESPONSE_4XX, pastTime, 
currentTime,
+                               timeInterval);
+               total += getResponseCountForMetric(loadBalancerName, region,
+                               Constants.HTTP_RESPONSE_5XX, pastTime, 
currentTime,
+                               timeInterval);
+
+               return total;
+       }
+
+       /**
+        * Retrieves the number of responses generated for a particular response
+        * code like 2XX, 3XX, 4XX, 5XX
+        * 
+        * @param loadBalancerName
+        * @param region
+        * @param metricName
+        *            which is one among HTTPCode_Backend_2XX or
+        *            HTTPCode_Backend_3XX or HTTPCode_Backend_4XX or
+        *            HTTPCode_Backend_5XX
+        * @param startTime
+        *            of the window to be scanned
+        * @param endTime
+        *            of the window to be scanned
+        * @param timeInterval
+        *            in seconds
+        * @return number for response for this metric
+        */
+       public int getResponseCountForMetric(String loadBalancerName,
+                       String region, String metricName, Date startTime, Date 
endTime,
+                       int timeInterval) {
+               int count = 0;
+
+               try {
+                       GetMetricStatisticsRequest request = new 
GetMetricStatisticsRequest();
+                       request.setMetricName(metricName);
+                       
request.setNamespace(Constants.CLOUD_WATCH_NAMESPACE_NAME);
+
+                       request.setStartTime(startTime);
+                       request.setEndTime(endTime);
+
+                       request.setPeriod(timeInterval);
+
+                       HashSet<String> statistics = new HashSet<String>();
+                       statistics.add(Constants.SUM_STATISTICS_NAME);
+                       request.setStatistics(statistics);
+
+                       HashSet<Dimension> dimensions = new 
HashSet<Dimension>();
+                       Dimension loadBalancerDimension = new Dimension();
+                       loadBalancerDimension
+                                       
.setName(Constants.LOAD_BALANCER_DIMENTION_NAME);
+                       loadBalancerDimension.setValue(loadBalancerName);
+                       dimensions.add(loadBalancerDimension);
+                       request.setDimensions(dimensions);
+
+                       cloudWatchClient.setEndpoint(String.format(
+                                       
Constants.CLOUD_WATCH_ENDPOINT_URL_FORMAT, region));
+
+                       GetMetricStatisticsResult result = cloudWatchClient
+                                       .getMetricStatistics(request);
+
+                       List<Datapoint> dataPoints = result.getDatapoints();
+
+                       if (dataPoints != null && dataPoints.size() > 0) {
+                               count = dataPoints.get(0).getSum().intValue();
+                       }
+
+               } catch (AmazonClientException e) {
+                       log.error("Could not get the statistics for metric " + 
metricName
+                                       + " of load balancer " + 
loadBalancerName, e);
+               }
+
+               return count;
+       }
+
+       /**
+        * Returns the Listeners required for the service. Listeners are derived
+        * from the proxy port, port and protocol values of the service.
+        * 
+        * @param service
+        * @return list of listeners required for the service
+        */
+       public List<Listener> getRequiredListeners(Member member) {
+               List<Listener> listeners = new ArrayList<Listener>();
+
+               Collection<Port> ports = member.getPorts();
+
+               for (Port port : ports) {
+                       int instancePort = port.getValue();
+                       int proxyPort = port.getProxy();
+                       String protocol = port.getProtocol().toUpperCase();
+                       String instanceProtocol = protocol;
+
+                       Listener listener = new Listener(protocol, proxyPort, 
instancePort);
+                       listener.setInstanceProtocol(instanceProtocol);
+
+                       listeners.add(listener);
+               }
+
+               return listeners;
+       }
+
+       /**
+        * Constructs name of the load balancer to be associated with the 
cluster
+        * 
+        * @param clusterId
+        * @return name of the load balancer
+        * @throws LoadBalancerExtensionException
+        */
+       public String generateLoadBalancerName()
+                       throws LoadBalancerExtensionException {
+               String name = null;
+
+               name = lbPrefix + getNextLBSequence();
+
+               if (name.length() > Constants.LOAD_BALANCER_NAME_MAX_LENGTH)
+                       throw new LoadBalancerExtensionException(
+                                       "Load balanacer name length (32 
characters) exceeded");
+
+               return name;
+       }
+
+       /**
+        * Extract instance id in IaaS side from member instance name
+        * 
+        * @param memberInstanceName
+        * @return instance id in IaaS
+        */
+       public String getAWSInstanceName(String memberInstanceName) {
+               if (memberInstanceName.contains("/")) {
+                       return memberInstanceName
+                                       
.substring(memberInstanceName.indexOf("/") + 1);
+               } else {
+                       return memberInstanceName;
+               }
+       }
+
+       /**
+        * Extract IaaS region from member instance name
+        * 
+        * @param memberInstanceName
+        * @return IaaS region to which member belongs
+        */
+       public String getAWSRegion(String memberInstanceName) {
+               if (memberInstanceName.contains("/")) {
+                       return memberInstanceName.substring(0,
+                                       memberInstanceName.indexOf("/"));
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Get availability zone from region
+        * 
+        * @param region
+        * @return Availability zone of IaaS
+        */
+       public String getAvailabilityZoneFromRegion(String region) {
+               if (region != null) {
+                       return region + "a";
+               } else
+                       return null;
+       }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
new file mode 100644
index 0000000..4621339
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java
@@ -0,0 +1,305 @@
+/*
+ * 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.stratos.aws.extension;
+
+import com.amazonaws.services.elasticloadbalancing.model.Instance;
+import com.amazonaws.services.elasticloadbalancing.model.Listener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.load.balancer.common.domain.Cluster;
+import org.apache.stratos.load.balancer.common.domain.Member;
+import org.apache.stratos.load.balancer.common.domain.Service;
+import org.apache.stratos.load.balancer.common.domain.Topology;
+import org.apache.stratos.load.balancer.extension.api.LoadBalancer;
+import 
org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class AWSLoadBalancer implements LoadBalancer {
+
+       private static final Log log = LogFactory.getLog(AWSLoadBalancer.class);
+
+       // A map <clusterId, load balancer info> to store load balancer 
information
+       // against the cluster id
+       private static ConcurrentHashMap<String, LoadBalancerInfo> 
clusterIdToLoadBalancerMap = new ConcurrentHashMap<String, LoadBalancerInfo>();
+
+       // Object used to invoke methods related to AWS API
+       private AWSHelper awsHelper;
+
+       public AWSLoadBalancer() throws LoadBalancerExtensionException {
+               awsHelper = new AWSHelper();
+       }
+
+       /*
+        * configure method iterates over topology and configures the AWS load
+        * balancers needed. Configuration may involve creating a new load 
balancer
+        * for a cluster, updating existing load balancers or deleting unwanted 
load
+        * balancers.
+        */
+       public boolean configure(Topology topology)
+                       throws LoadBalancerExtensionException {
+
+               log.info("AWS load balancer extension is being reconfigured.");
+
+               HashSet<String> activeClusters = new HashSet<String>();
+
+               for (Service service : topology.getServices()) {
+                       for (Cluster cluster : service.getClusters()) {
+                               // Check if a load balancer is created for this 
cluster
+                               if 
(clusterIdToLoadBalancerMap.containsKey(cluster
+                                               .getClusterId())) {
+                                       // A load balancer is already present 
for this cluster
+                                       // Get the load balancer and update it.
+
+                                       if (log.isDebugEnabled()) {
+                                               log.debug("Load balancer for 
cluster "
+                                                               + 
cluster.getClusterId()
+                                                               + " is already 
present.");
+                                       }
+
+                                       LoadBalancerInfo loadBalancerInfo = 
clusterIdToLoadBalancerMap
+                                                       
.get(cluster.getClusterId());
+
+                                       String loadBalancerName = 
loadBalancerInfo.getName();
+                                       String region = 
loadBalancerInfo.getRegion();
+
+                                       // Get all the instances attached
+                                       // Attach newly added instances to load 
balancer
+
+                                       // attachedInstances list is useful in 
finding out what
+                                       // all new instances which
+                                       // should be attached to this load 
balancer.
+                                       List<Instance> attachedInstances = 
awsHelper
+                                                       
.getAttachedInstances(loadBalancerName, region);
+
+                                       // clusterMembers stores all the 
members of a cluster.
+                                       Collection<Member> clusterMembers = 
cluster.getMembers();
+
+                                       if (clusterMembers.size() > 0) {
+                                               
activeClusters.add(cluster.getClusterId());
+
+                                               List<Instance> 
instancesToAddToLoadBalancer = new ArrayList<Instance>();
+
+                                               for (Member member : 
clusterMembers) {
+                                                       // if instance id of 
member is not in
+                                                       // attachedInstances
+                                                       // add this to 
instancesToAddToLoadBalancer
+                                                       Instance instance = new 
Instance(
+                                                                       
awsHelper.getAWSInstanceName(member
+                                                                               
        .getInstanceId()));
+
+                                                       if (attachedInstances 
== null
+                                                                       || 
!attachedInstances.contains(instance)) {
+                                                               
instancesToAddToLoadBalancer.add(instance);
+
+                                                               if 
(log.isDebugEnabled()) {
+                                                                       
log.debug("Instance "
+                                                                               
        + awsHelper
+                                                                               
                        .getAWSInstanceName(member
+                                                                               
                                        .getInstanceId())
+                                                                               
        + " needs to be registered to load balancer "
+                                                                               
        + loadBalancerName);
+                                                               }
+
+                                                       }
+                                               }
+
+                                               if 
(instancesToAddToLoadBalancer.size() > 0)
+                                                       
awsHelper.registerInstancesToLoadBalancer(
+                                                                       
loadBalancerName,
+                                                                       
instancesToAddToLoadBalancer, region);
+                                       }
+
+                               } else {
+                                       // Create a new load balancer for this 
cluster
+                                       Collection<Member> clusterMembers = 
cluster.getMembers();
+
+                                       if (clusterMembers.size() > 0) {
+                                               // a unique load balancer name 
with user-defined
+                                               // prefix and a sequence number.
+                                               String loadBalancerName = 
awsHelper
+                                                               
.generateLoadBalancerName();
+
+                                               String region = 
awsHelper.getAWSRegion(clusterMembers
+                                                               
.iterator().next().getInstanceId());
+
+                                               // list of AWS listeners 
obtained using port
+                                               // mappings of one of the 
members of the cluster.
+                                               List<Listener> 
listenersForThisCluster = awsHelper
+                                                               
.getRequiredListeners(clusterMembers.iterator()
+                                                                               
.next());
+
+                                               // DNS name of load balancer 
which was created.
+                                               // This is used in the domain 
mapping of this
+                                               // cluster.
+                                               String loadBalancerDNSName = 
awsHelper
+                                                               
.createLoadBalancer(loadBalancerName,
+                                                                               
listenersForThisCluster, region);
+
+                                               // Add the inbound rule the 
security group of the load
+                                               // balancer
+                                               // For each listener, add a new 
rule with load
+                                               // balancer port as allowed 
protocol in the security
+                                               // group.
+                                               for (Listener listener : 
listenersForThisCluster) {
+                                                       int port = 
listener.getLoadBalancerPort();
+
+                                                       for (String protocol : 
awsHelper
+                                                                       
.getAllowedProtocolsForLBSecurityGroup()) {
+                                                               awsHelper
+                                                                               
.addInboundRuleToSecurityGroup(
+                                                                               
                awsHelper.getSecurityGroupId(
+                                                                               
                                awsHelper
+                                                                               
                                                .getLbSecurityGroupName(),
+                                                                               
                                region), region,
+                                                                               
                protocol, port);
+                                                       }
+                                               }
+
+                                               log.info("Load balancer '" + 
loadBalancerDNSName
+                                                               + "' created 
for cluster '"
+                                                               + 
cluster.getClusterId());
+
+                                               // Register instances in the 
cluster to load balancer
+                                               List<Instance> instances = new 
ArrayList<Instance>();
+
+                                               for (Member member : 
clusterMembers) {
+                                                       String instanceId = 
member.getInstanceId();
+
+                                                       if 
(log.isDebugEnabled()) {
+                                                               
log.debug("Instance "
+                                                                               
+ awsHelper
+                                                                               
                .getAWSInstanceName(instanceId)
+                                                                               
+ " needs to be registered to load balancer "
+                                                                               
+ loadBalancerName);
+                                                       }
+
+                                                       Instance instance = new 
Instance();
+                                                       
instance.setInstanceId(awsHelper
+                                                                       
.getAWSInstanceName(instanceId));
+
+                                                       instances.add(instance);
+                                               }
+
+                                               
awsHelper.registerInstancesToLoadBalancer(
+                                                               
loadBalancerName, instances, region);
+
+                                               LoadBalancerInfo 
loadBalancerInfo = new LoadBalancerInfo(
+                                                               
loadBalancerName, region);
+
+                                               
clusterIdToLoadBalancerMap.put(cluster.getClusterId(),
+                                                               
loadBalancerInfo);
+                                               
activeClusters.add(cluster.getClusterId());
+                                       }
+                               }
+                       }
+               }
+
+               // Find out clusters which were present earlier but are not now.
+               List<String> clustersToRemoveFromMap = new ArrayList<String>();
+
+               for (String clusterId : clusterIdToLoadBalancerMap.keySet()) {
+                       if (!activeClusters.contains(clusterId)) {
+                               clustersToRemoveFromMap.add(clusterId);
+
+                               if (log.isDebugEnabled()) {
+                                       log.debug("Load balancer for cluster " 
+ clusterId
+                                                       + " needs to be 
removed.");
+                               }
+
+                       }
+               }
+
+               // Delete load balancers associated with these clusters.
+               for (String clusterId : clustersToRemoveFromMap) {
+                       // Remove load balancer for this cluster.
+                       awsHelper.deleteLoadBalancer(
+                                       
clusterIdToLoadBalancerMap.get(clusterId).getName(),
+                                       
clusterIdToLoadBalancerMap.get(clusterId).getRegion());
+                       clusterIdToLoadBalancerMap.remove(clusterId);
+               }
+
+               activeClusters.clear();
+               log.info("AWS load balancer extension was reconfigured as per 
the topology.");
+               return true;
+       }
+
+       /*
+        * start method is called after extension if configured first time. Does
+        * nothing but logs the message.
+        */
+       public void start() throws LoadBalancerExtensionException {
+
+               log.info("AWS load balancer extension started.");
+       }
+
+       /*
+        * reload method is called every time after extension if configured. 
Does
+        * nothing but logs the message.
+        */
+       public void reload() throws LoadBalancerExtensionException {
+               // Check what is appropriate to do here.
+               log.info("AWS load balancer extension reloaded.");
+       }
+
+       /*
+        * stop method deletes load balancers for all clusters in the topology.
+        */
+       public void stop() throws LoadBalancerExtensionException {
+               // Remove all load balancers
+               for (LoadBalancerInfo loadBalancerInfo : 
clusterIdToLoadBalancerMap
+                               .values()) {
+                       // Remove load balancer
+                       awsHelper.deleteLoadBalancer(loadBalancerInfo.getName(),
+                                       loadBalancerInfo.getRegion());
+               }
+       }
+
+       public static ConcurrentHashMap<String, LoadBalancerInfo> 
getClusterIdToLoadBalancerMap() {
+               return clusterIdToLoadBalancerMap;
+       }
+}
+
+/**
+ * Used to store load balancer name and the region in which it is created. This
+ * helps in finding region while calling API methods to modify/delete a load
+ * balancer.
+ */
+class LoadBalancerInfo {
+       private String name;
+       private String region;
+
+       public LoadBalancerInfo(String name, String region) {
+               this.name = name;
+               this.region = region;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public String getRegion() {
+               return region;
+       }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSStatisticsReader.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSStatisticsReader.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSStatisticsReader.java
new file mode 100644
index 0000000..55aca3d
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSStatisticsReader.java
@@ -0,0 +1,89 @@
+/*
+ * 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.stratos.aws.extension;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.constants.StratosConstants;
+import 
org.apache.stratos.load.balancer.common.statistics.LoadBalancerStatisticsReader;
+import org.apache.stratos.load.balancer.common.topology.TopologyProvider;
+import 
org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * AWS statistics reader.
+ */
+public class AWSStatisticsReader implements LoadBalancerStatisticsReader {
+
+       private static final Log log = 
LogFactory.getLog(AWSStatisticsReader.class);
+
+       private TopologyProvider topologyProvider;
+       private String clusterInstanceId;
+
+       private AWSHelper awsHelper;
+
+       public AWSStatisticsReader(TopologyProvider topologyProvider)
+                       throws LoadBalancerExtensionException {
+               this.topologyProvider = topologyProvider;
+               this.clusterInstanceId = System.getProperty(
+                               StratosConstants.CLUSTER_INSTANCE_ID,
+                               StratosConstants.NOT_DEFINED);
+
+               awsHelper = new AWSHelper();
+       }
+
+       @Override
+       public String getClusterInstanceId() {
+               return clusterInstanceId;
+       }
+
+       @Override
+       public int getInFlightRequestCount(String clusterId) {
+
+               int inFlightRequestCount = 0;
+
+               ConcurrentHashMap<String, LoadBalancerInfo> 
clusterIdToLoadBalancerMap = AWSLoadBalancer
+                               .getClusterIdToLoadBalancerMap();
+
+               // Check if load balancer info is available for this cluster.
+               // If yes, then find difference between total requests made to 
the load balancer and 
+               // total responses generated by instances attached to it.
+               if (clusterIdToLoadBalancerMap.containsKey(clusterId)) {
+                       LoadBalancerInfo loadBalancerInfo = 
clusterIdToLoadBalancerMap
+                                       .get(clusterId);
+
+                       String loadBalancerName = loadBalancerInfo.getName();
+                       String region = loadBalancerInfo.getRegion();
+
+                       // In flight request count = total requests - total 
responses
+                       inFlightRequestCount = 
awsHelper.getRequestCount(loadBalancerName,
+                                       region, 
awsHelper.getStatisticsInterval())
+                                       - 
awsHelper.getAllResponsesCount(loadBalancerName, region,
+                                                       
awsHelper.getStatisticsInterval());
+
+                       if (inFlightRequestCount < 0)
+                               inFlightRequestCount = 0;
+
+               }
+
+               return inFlightRequestCount;
+       }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
new file mode 100644
index 0000000..30ada5c
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java
@@ -0,0 +1,56 @@
+/*
+ * 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.stratos.aws.extension;
+
+/**
+ * AWS proxy extension constants.
+ */
+public class Constants {
+       public static final String CEP_STATS_PUBLISHER_ENABLED = 
"cep.stats.publisher.enabled";
+       public static final String THRIFT_RECEIVER_IP = "thrift.receiver.ip";
+       public static final String THRIFT_RECEIVER_PORT = 
"thrift.receiver.port";
+       public static final String NETWORK_PARTITION_ID = 
"network.partition.id";
+       public static final String CLUSTER_ID = "cluster.id";
+       public static final String SERVICE_NAME = "service.name";
+       public static final String AWS_PROPERTIES_FILE = "aws.properties.file";
+       public static final String AWS_ACCESS_KEY = "access-key";
+       public static final String AWS_SECRET_KEY = "secret-key";
+       public static final String LB_PREFIX = "load-balancer-prefix";
+       public static final String LOAD_BALANCER_SECURITY_GROUP_NAME = 
"load-balancer-security-group-name";
+       public static final String LOAD_BALANCER_SECURITY_GROUP_DESCRIPTION = 
"Security group for load balancers created for Apache Stratos.";
+       public static final String ELB_ENDPOINT_URL_FORMAT = 
"elasticloadbalancing.%s.amazonaws.com";
+       public static final String EC2_ENDPOINT_URL_FORMAT = 
"ec2.%s.amazonaws.com";
+       public static final String CLOUD_WATCH_ENDPOINT_URL_FORMAT = 
"monitoring.%s.amazonaws.com";
+       public static final String ALLOWED_CIDR_IP_KEY = "allowed-cidr-ip";
+       public static final String ALLOWED_PROTOCOLS = "allowed-protocols";
+       public static final int LOAD_BALANCER_NAME_MAX_LENGTH = 32;
+       public static final int LOAD_BALANCER_PREFIX_MAX_LENGTH = 25;
+       public static final int SECURITY_GROUP_NAME_MAX_LENGTH = 255;
+       public static final String REQUEST_COUNT_METRIC_NAME = "RequestCount";
+       public static final String CLOUD_WATCH_NAMESPACE_NAME = "AWS/ELB";
+       public static final String SUM_STATISTICS_NAME = "Sum";
+       public static final String LOAD_BALANCER_DIMENTION_NAME = 
"LoadBalancerName";
+       public static final String HTTP_RESPONSE_2XX = "HTTPCode_Backend_2XX";
+       public static final String HTTP_RESPONSE_3XX = "HTTPCode_Backend_3XX";
+       public static final String HTTP_RESPONSE_4XX = "HTTPCode_Backend_4XX";
+       public static final String HTTP_RESPONSE_5XX = "HTTPCode_Backend_5XX";
+       public static final String STATISTICS_INTERVAL = "statistics-interval";
+       public static final int STATISTICS_INTERVAL_MULTIPLE_OF = 60;
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/c59529a8/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Main.java
----------------------------------------------------------------------
diff --git 
a/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Main.java
 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Main.java
new file mode 100644
index 0000000..73fa971
--- /dev/null
+++ 
b/extensions/load-balancer/aws-extension/src/main/java/org/apache/stratos/aws/extension/Main.java
@@ -0,0 +1,90 @@
+/*
+ * 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.stratos.aws.extension;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.stratos.common.threading.StratosThreadPool;
+import org.apache.stratos.load.balancer.common.topology.TopologyProvider;
+import org.apache.stratos.load.balancer.extension.api.LoadBalancerExtension;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * AWS extension main class.
+ */
+
+public class Main {
+       private static final Log log = LogFactory.getLog(Main.class);
+       private static ExecutorService executorService;
+
+       public static void main(String[] args) {
+
+               LoadBalancerExtension extension = null;
+               try {
+                       // Configure log4j properties
+                       PropertyConfigurator.configure(System
+                                       
.getProperty("log4j.properties.file.path"));
+
+                       if (log.isInfoEnabled()) {
+                               log.info("AWS extension started");
+                       }
+
+                       executorService = StratosThreadPool.getExecutorService(
+                                       "aws.extension.thread.pool", 10);
+                       // Validate runtime parameters
+                       AWSExtensionContext.getInstance().validate();
+                       TopologyProvider topologyProvider = new 
TopologyProvider();
+                       AWSStatisticsReader statisticsReader = 
AWSExtensionContext
+                                       
.getInstance().isCEPStatsPublisherEnabled() ? new AWSStatisticsReader(
+                                       topologyProvider) : null;
+                       extension = new LoadBalancerExtension(new 
AWSLoadBalancer(),
+                                       statisticsReader, topologyProvider);
+                       extension.setExecutorService(executorService);
+                       extension.execute();
+
+                       // Add shutdown hook
+                       final Thread mainThread = Thread.currentThread();
+                       final LoadBalancerExtension finalExtension = extension;
+                       Runtime.getRuntime().addShutdownHook(new Thread() {
+                               public void run() {
+                                       try {
+                                               if (finalExtension != null) {
+                                                       log.info("Shutting aws 
extension...");
+                                                       finalExtension.stop();
+                                               }
+                                               mainThread.join();
+                                       } catch (Exception e) {
+                                               log.error(e);
+                                       }
+                               }
+                       });
+               } catch (Exception e) {
+                       if (log.isErrorEnabled()) {
+                               log.error(e);
+                       }
+                       if (extension != null) {
+                               log.info("Shutting aws extension...");
+                               extension.stop();
+                       }
+               }
+       }
+}

Reply via email to