stratos-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ga...@apache.org
Subject [2/2] stratos git commit: Add the aws lb extension
Date Fri, 09 Oct 2015 15:07:37 GMT
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 <gayang@wso2.com>
Authored: Fri Oct 9 20:31:03 2015 +0530
Committer: gayangunarathne <gayang@wso2.com>
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();
+			}
+		}
+	}
+}


Mime
View raw message