diff --git a/components/org.apache.stratos.cartridge.agent/src/test/java/org/apache/stratos/cartridge/agent/test/JavaCartridgeAgentTest.java b/components/org.apache.stratos.cartridge.agent/src/test/java/org/apache/stratos/cartridge/agent/test/JavaCartridgeAgentTest.java index b286066385..3eaea14d86 100644 --- a/components/org.apache.stratos.cartridge.agent/src/test/java/org/apache/stratos/cartridge/agent/test/JavaCartridgeAgentTest.java +++ b/components/org.apache.stratos.cartridge.agent/src/test/java/org/apache/stratos/cartridge/agent/test/JavaCartridgeAgentTest.java @@ -77,6 +77,7 @@ public class JavaCartridgeAgentTest { private static final String PARTITION_ID = "partition-1"; private static final String TENANT_ID = "-1234"; private static final String SERVICE_NAME = "php"; + private static final String INSTANCE_ID = "instance-1"; public static final String AGENT_NAME = "apache-stratos-cartridge-agent-4.1.2-SNAPSHOT"; private static HashMap executorList; private static ArrayList serverSocketList; @@ -327,7 +328,7 @@ public void run() { // Publish member initialized event log.info("Publishing member initialized event..."); MemberInitializedEvent memberInitializedEvent = new MemberInitializedEvent( - SERVICE_NAME, CLUSTER_ID, CLUSTER_INSTANCE_ID, MEMBER_ID, NETWORK_PARTITION_ID, PARTITION_ID + SERVICE_NAME, CLUSTER_ID, CLUSTER_INSTANCE_ID, MEMBER_ID, NETWORK_PARTITION_ID, PARTITION_ID, INSTANCE_ID ); publishEvent(memberInitializedEvent); log.info("Member initialized event published"); diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/publisher/TopologyEventPublisher.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/publisher/TopologyEventPublisher.java index 7225a61f8a..b55d3a2b62 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/publisher/TopologyEventPublisher.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/publisher/TopologyEventPublisher.java @@ -171,7 +171,8 @@ public static void sendMemberInitializedEvent(MemberContext memberContext) { memberContext.getClusterInstanceId(), memberContext.getMemberId(), memberContext.getNetworkPartitionId(), - memberContext.getPartition().getId()); + memberContext.getPartition().getId(), + memberContext.getInstanceId()); memberInitializedEvent.setDefaultPrivateIP(memberContext.getDefaultPrivateIP()); if (memberContext.getPrivateIPs() != null) { diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java index a11c5bf2dd..f01b3d1b1f 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/messaging/topology/TopologyBuilder.java @@ -444,6 +444,7 @@ public static void handleMemberInitializedEvent(MemberContext memberContext) { if (memberContext.getPublicIPs() != null) { member.setMemberPublicIPs(Arrays.asList(memberContext.getPublicIPs())); } + member.setInstanceId(memberContext.getInstanceId()); // try update lifecycle state if (!member.isStateTransitionValid(MemberStatus.Initialized)) { 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 953dabd980..2019c76654 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 @@ -32,6 +32,8 @@ public class Member { private String clusterId; private String memberId; private String hostName; + //instance id provided by IaaS in order to use in GCE load balancer + private String instanceId; private Map portMap; public Member(String serviceName, String clusterId, String memberId, String hostName) { @@ -86,4 +88,12 @@ public Collection getPorts() { public String getServiceName() { return serviceName; } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } } diff --git a/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/event/receivers/LoadBalancerCommonTopologyEventReceiver.java b/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/event/receivers/LoadBalancerCommonTopologyEventReceiver.java index 0feaab3466..9f658115c4 100644 --- a/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/event/receivers/LoadBalancerCommonTopologyEventReceiver.java +++ b/components/org.apache.stratos.load.balancer.common/src/main/java/org/apache/stratos/load/balancer/common/event/receivers/LoadBalancerCommonTopologyEventReceiver.java @@ -440,6 +440,9 @@ private org.apache.stratos.load.balancer.common.domain.Member transformMember(Me member.addPort(transformPort(port)); } } + if (messagingMember.getInstanceId() != null) { + member.setInstanceId(messagingMember.getInstanceId()); + } return member; } } diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Member.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Member.java index 2242075681..0ca6deb88c 100644 --- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Member.java +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Member.java @@ -60,6 +60,8 @@ public class Member implements Serializable, LifeCycleStateTransitionBehavior memberStateManager; private LoadBalancingIPType loadBalancingIPType; + //instance id provided by IaaS(In order to use in GCE Load balancer) + private String instanceId; public Member(String serviceName, String clusterId, String memberId, String clusterInstanceId, String networkPartitionId, String partitionId, LoadBalancingIPType loadBalancingIPType, @@ -209,6 +211,14 @@ public LoadBalancingIPType getLoadBalancingIPType() { return loadBalancingIPType; } + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + @Override public String toString() { return "Member [serviceName=" + getServiceName() diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/MemberInitializedEvent.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/MemberInitializedEvent.java index edf64e307e..45adcc55ae 100644 --- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/MemberInitializedEvent.java +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/MemberInitializedEvent.java @@ -36,6 +36,8 @@ public class MemberInitializedEvent extends TopologyEvent implements Serializabl private final String networkPartitionId; private final String partitionId; private final String memberId; + //instance Id provided by IaaS + private final String instanceId; private List memberPublicIPs; private String defaultPublicIP; @@ -44,13 +46,14 @@ public class MemberInitializedEvent extends TopologyEvent implements Serializabl private Properties properties; public MemberInitializedEvent(String serviceName, String clusterId, String clusterInstanceId, String memberId, - String networkPartitionId, String partitionId) { + String networkPartitionId, String partitionId, String instanceId) { this.serviceName = serviceName; this.clusterId = clusterId; this.clusterInstanceId = clusterInstanceId; this.memberId = memberId; this.networkPartitionId = networkPartitionId; this.partitionId = partitionId; + this.instanceId = instanceId; } public String getServiceName() { @@ -116,4 +119,8 @@ public List getMemberPrivateIPs() { public void setMemberPrivateIPs(List memberPrivateIPs) { this.memberPrivateIPs = memberPrivateIPs; } + + public String getInstanceId() { + return instanceId; + } } diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/MemberInitializedMessageProcessor.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/MemberInitializedMessageProcessor.java index 57d06808b6..0bd064a279 100644 --- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/MemberInitializedMessageProcessor.java +++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/MemberInitializedMessageProcessor.java @@ -140,6 +140,7 @@ private boolean doProcess(MemberInitializedEvent event, Topology topology) { member.setMemberPublicIPs(event.getMemberPublicIPs()); member.setDefaultPrivateIP(event.getDefaultPrivateIP()); member.setMemberPrivateIPs(event.getMemberPrivateIPs()); + member.setInstanceId(event.getInstanceId()); if (log.isInfoEnabled()) { log.info(String.format("Member initialized: [service] %s [cluster] %s [member] %s", diff --git a/components/org.apache.stratos.python.cartridge.agent/src/test/java/org/apache/stratos/python.cartridge.agent/test/PythonCartridgeAgentTest.java b/components/org.apache.stratos.python.cartridge.agent/src/test/java/org/apache/stratos/python.cartridge.agent/test/PythonCartridgeAgentTest.java index ea62d977a1..c37eb2bc92 100644 --- a/components/org.apache.stratos.python.cartridge.agent/src/test/java/org/apache/stratos/python.cartridge.agent/test/PythonCartridgeAgentTest.java +++ b/components/org.apache.stratos.python.cartridge.agent/src/test/java/org/apache/stratos/python.cartridge.agent/test/PythonCartridgeAgentTest.java @@ -74,6 +74,7 @@ public class PythonCartridgeAgentTest { private static final String TENANT_ID = "-1234"; private static final String SERVICE_NAME = "php"; public static final String SOURCE_PATH = "/tmp/stratos-pca-test-app-path/"; + private static final String INSTANCE_ID = "instance-1"; private static List serverSocketList; private static Map executorList; @@ -282,8 +283,7 @@ public void run() { // Publish member initialized event log.info("Publishing member initialized event..."); MemberInitializedEvent memberInitializedEvent = new MemberInitializedEvent( - SERVICE_NAME, CLUSTER_ID, CLUSTER_INSTANCE_ID, MEMBER_ID, NETWORK_PARTITION_ID, - PARTITION_ID + SERVICE_NAME, CLUSTER_ID, CLUSTER_INSTANCE_ID, MEMBER_ID, NETWORK_PARTITION_ID, PARTITION_ID, INSTANCE_ID ); publishEvent(memberInitializedEvent); log.info("Member initialized event published"); diff --git a/extensions/load-balancer/gce-extension/INSTALL.md b/extensions/load-balancer/gce-extension/INSTALL.md new file mode 100644 index 0000000000..2876197c66 --- /dev/null +++ b/extensions/load-balancer/gce-extension/INSTALL.md @@ -0,0 +1,36 @@ + # + # Licensed to the Apache Software Foundation (ASF) under one + # or more contributor license agreements. See the NOTICE file + # distributed with this work for additional information + # regarding copyright ownership. The ASF licenses this file + # to you under the Apache License, Version 2.0 (the + # "License"); you may not use this file except in compliance + # with the License. You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, + # software distributed under the License is distributed on an + # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + # KIND, either express or implied. See the License for the + # specific language governing permissions and limitations + # under the License. + # + +# Installing Apache Stratos GCE Extension + +Apache Stratos GCE Extension could be used for integrating GCE load balancer with Apache Stratos. Please follow +below steps to proceed with a quick installation: + +1. Extract org.apache.stratos.gce.extension-.zip to a desired location: . + +2. Open /conf/gce-configuration file in text editor and update GCE credentials. + +3. Open /conf/jndi.properties file in a text editor and update message broker information: + ``` + java.naming.provider.url=tcp://localhost:61616 + ``` +4. Run /bin/gce-extension.sh as the root user. + +For a detailed installation refer following link: +https://docs.google.com/document/d/1a2ZptPScpjuavfpxVu1R1GC7R95jjzHo3L372zL2bRY/edit diff --git a/extensions/load-balancer/gce-extension/README.md b/extensions/load-balancer/gce-extension/README.md new file mode 100644 index 0000000000..8b55f2a921 --- /dev/null +++ b/extensions/load-balancer/gce-extension/README.md @@ -0,0 +1,19 @@ +# Apache Stratos GCE Extension + +Apache Stratos GCE extension is a load balancer extension for Google Compute Engine Load balancer. +It is an executable program which can manage Google Compute Engine Load balancing according to the topology, +composite application model and tenant application signups information received from Stratos via +the message broker. + +## How it works +1. Wait for the complete topology event message to initialize the topology. +2. Configure and create relevant forwarding rules, target pools and health checks in GCE. +3. Listen to topology, application, application signup events. +4. Reconfigure the load balancer with the new topology configuration. + +## Installation +Please refer INSTALL.md for information on a quick installation process. + +Please refer bellow document for information on a detailed installation process. + +https://docs.google.com/document/d/1a2ZptPScpjuavfpxVu1R1GC7R95jjzHo3L372zL2bRY/edit \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/pom.xml b/extensions/load-balancer/gce-extension/pom.xml new file mode 100644 index 0000000000..7f03ebfc4a --- /dev/null +++ b/extensions/load-balancer/gce-extension/pom.xml @@ -0,0 +1,140 @@ + + + + + 4.0.0 + + + org.apache.stratos + stratos-load-balancer-extensions + 4.1.1-SNAPSHOT + + + org.apache.stratos.gce.extension + Apache Stratos - GCE Extension + Apache Stratos GCE Extension for Load Balancing + + + + org.slf4j + slf4j-log4j12 + 1.7.5 + + + org.apache.stratos + org.apache.stratos.common + ${project.version} + + + org.apache.stratos + org.apache.stratos.messaging + ${project.version} + + + org.apache.stratos + org.apache.stratos.load.balancer.extension.api + ${project.version} + + + commons-io + commons-io + 2.0 + + + org.apache.velocity + velocity + 1.7 + + + org.wso2.andes.wso2 + andes-client + 0.13.wso2v8 + + + com.google.http-client + google-http-client-jackson2 + ${project.http.version} + + + com.google.oauth-client + google-oauth-client-jetty + ${project.oauth.version} + + + com.google.apis + google-api-services-compute + v1-rev27-1.19.0 + + + org.apache.stratos + org.apache.stratos.cloud.controller + ${project.version} + + + org.apache.ws.commons.axiom.wso2 + axiom + 1.2.11.wso2v4 + + + + + 1.19.0 + 1.19.0 + + + + + + maven-assembly-plugin + + + src/main/assembly/bin.xml + + + 420 + 493 + 493 + + false + + + + package + + attached + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + org.apache.stratos.gce.extension.Main + + + + + + + \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/assembly/bin.xml b/extensions/load-balancer/gce-extension/src/main/assembly/bin.xml new file mode 100644 index 0000000000..8e9afacb1a --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/assembly/bin.xml @@ -0,0 +1,70 @@ + + + + bin + + zip + + + + ${project.basedir}/src/main/bin + /bin + 0755 + + gce-extension.sh + + + + ${project.basedir}/src/main/conf + /conf + 0600 + + jndi.properties + log4j.properties + thrift-client-config.xml + gce-configuration.xml + + + + ${project.basedir}/src/main/security + /security + 0600 + + client-truststore.jks + + + + + + /lib + + *:icu4j* + *:jaxen* + *:jboss-transaction-api* + *:wrapper* + *:xom* + + true + runtime + + + \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/bin/gce-extension.sh b/extensions/load-balancer/gce-extension/src/main/bin/gce-extension.sh new file mode 100644 index 0000000000..2e9f4fbf61 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/bin/gce-extension.sh @@ -0,0 +1,40 @@ +#!/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 gce load balancer 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 + -Dstats.socket.file.path=/tmp/haproxy-stats.socket + -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 + -Dlog4j.properties.file.path=${script_path}/../conf/log4j.properties" + +# Uncomment below line to enable remote debugging +#debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5006" + +java -cp "${class_path}" ${properties} ${debug} org.apache.stratos.gce.extension.Main $* \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/conf/gce-configuration.xml b/extensions/load-balancer/gce-extension/src/main/conf/gce-configuration.xml new file mode 100644 index 0000000000..f638b38f6d --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/conf/gce-configuration.xml @@ -0,0 +1,31 @@ + + + + + 127.0.0.1 + 7615 + + + + MyFirstProject + gold-access-xxxx + europe-west1 + path-to-key-file/keyfile.p12 + xxxxxxxxxxxxx.gserviceaccount.com + default + + + + / + 80 + 2 + 5 + 2 + 2 + + + 10000 + lb + https://www.googleapis.com/compute/v1/projects/ + + \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/conf/jndi.properties b/extensions/load-balancer/gce-extension/src/main/conf/jndi.properties new file mode 100644 index 0000000000..21d74207b9 --- /dev/null +++ b/extensions/load-balancer/gce-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 diff --git a/extensions/load-balancer/gce-extension/src/main/conf/log4j.properties b/extensions/load-balancer/gce-extension/src/main/conf/log4j.properties new file mode 100644 index 0000000000..40f9c47efb --- /dev/null +++ b/extensions/load-balancer/gce-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/gce-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.gce.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 diff --git a/extensions/load-balancer/gce-extension/src/main/conf/thrift-client-config.xml b/extensions/load-balancer/gce-extension/src/main/conf/thrift-client-config.xml new file mode 100644 index 0000000000..5cacada428 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/conf/thrift-client-config.xml @@ -0,0 +1,27 @@ + + + + + + admin + admin + localhost + 7611 + \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCELoadBalancer.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCELoadBalancer.java new file mode 100644 index 0000000000..e31af5a4b4 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCELoadBalancer.java @@ -0,0 +1,411 @@ +/* + * 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.gce.extension; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.gce.extension.config.Constants; +import org.apache.stratos.gce.extension.config.GCEClusterConfigurationHolder; +import org.apache.stratos.gce.extension.config.GCEContext; +import org.apache.stratos.gce.extension.util.GCEOperations; +import org.apache.stratos.load.balancer.common.domain.*; +import org.apache.stratos.load.balancer.extension.api.LoadBalancer; +import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.*; + +/** + * All the methods in Stratos load balancer API have been implemented in this class + */ +public class GCELoadBalancer implements LoadBalancer { + + private static final Log log = LogFactory.getLog(GCELoadBalancer.class); + private GCEOperations gceOperations; + /** + * One configuration object per cluster will be created + * One cluster has one target pool,one forwarding rule and a health check + * This hash map is used to hold cluster IDs and corresponding configuration + */ + private Map clusterToLoadBalancerConfigurationMap; + + public GCELoadBalancer() throws IOException, GeneralSecurityException { + gceOperations = new GCEOperations(); + clusterToLoadBalancerConfigurationMap = new HashMap(); + } + + /** + * Listen to latest topology and update load balancer configuration + * + * @param topology latest topology to be configured + * @return - true - if the load balancer was successfully configured. else false + * @throws LoadBalancerExtensionException + */ + @Override + public boolean configure(Topology topology) throws LoadBalancerExtensionException { + log.info("Complete topology received. Configuring Load balancer..."); + + //this list is used to hold the current clusters available in topology and which has at least one member. + List activeClusterIdList = new ArrayList(); + + for (Service service : topology.getServices()) { + for (Cluster cluster : service.getClusters()) { //for each cluster + + //check whether this cluster has a load balancer configuration or not + if (clusterToLoadBalancerConfigurationMap.containsKey(cluster.getClusterId())) { + + if (log.isDebugEnabled()) { + log.debug("Reconfiguring the existing cluster: " + cluster.getClusterId() + "..."); + } + + //It already has a entry in clusterToLoadBalancerConfigurationMap. + //Take it and update it as the given topology. + GCEClusterConfigurationHolder gceClusterConfigurationHolder = clusterToLoadBalancerConfigurationMap. + get(cluster.getClusterId()); + + //if the cluster contains at least one member + if (!cluster.getMembers().isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("Cluster " + cluster.getClusterId() + " has one or more members"); + } + activeClusterIdList.add(cluster.getClusterId()); + if (log.isDebugEnabled()) { + log.debug("Cluster " + cluster.getClusterId() + " was added to active cluster id list"); + } + + //detect member changes and update + //check for newly created members + List membersToBeAddedToTargetPool = new ArrayList(); + for (Member member : cluster.getMembers()) { + + if (member.getInstanceId() != null && !gceClusterConfigurationHolder.getMemberList(). + contains(member.getInstanceId())) { + if (log.isDebugEnabled()) { + log.debug("New member found: " + member.getInstanceId()); + } + membersToBeAddedToTargetPool.add(member.getInstanceId()); + } + } + + if (!membersToBeAddedToTargetPool.isEmpty()) { //we have new members + log.info("New members in cluster" + cluster.getClusterId() + " found. Adding new members " + + "to cluster..."); + + //add them to configuration holder + for (String memberId : membersToBeAddedToTargetPool) { + gceClusterConfigurationHolder.addMember(memberId); + + } + + //add them to target pool too + gceOperations.addInstancesToTargetPool(membersToBeAddedToTargetPool, + gceClusterConfigurationHolder.getTargetPoolName()); + } + + //check for terminated members and remove them from cluster + List membersToBeRemovedFromTargetPool = new ArrayList(); + for (String memberId : gceClusterConfigurationHolder.getMemberList()) { //for all members in Map + boolean found = false; + for (Member member : cluster.getMembers()) { //for all members in cluster + if (member.getInstanceId().equals(memberId)) { + found = true; + break; + } + } + if (!found) { + //add member id to membersToBeRemovedFromTargetPool in order remove member from map + if (log.isDebugEnabled()) { + log.debug("Terminated member found: " + memberId); + } + membersToBeRemovedFromTargetPool.add(memberId); + } + } + + if (!membersToBeRemovedFromTargetPool.isEmpty()) { //found terminated members + log.info("Terminated members found in cluster " + cluster.getClusterId() + ". Removing them..."); + + //remove them from configuration holder + for (String memberId : membersToBeRemovedFromTargetPool) { + gceClusterConfigurationHolder.removeMember(memberId); + + } + + //remove them from GCE too + gceOperations.removeInstancesFromTargetPool(membersToBeRemovedFromTargetPool, + gceClusterConfigurationHolder.getTargetPoolName()); + } + } + } else { + //doesn't have a GCEClusterConfigurationHolder object. So crate a new one and add to hash map + log.info("Found a new cluster: " + cluster.getClusterId()); + + if (cluster.getMembers().isEmpty()) { + log.info("Cluster " + cluster.getClusterId() + " does not have any members. So not configuring"); + } else { + activeClusterIdList.add(cluster.getClusterId()); + List instancesList = new ArrayList(); + List ipList = new ArrayList(); + for (Member member : cluster.getMembers()) { + + //add instance to instance list + if (member.getInstanceId() != null) { + if (log.isDebugEnabled()) { + log.debug("Adding member " + member.getMemberId() + " to instance list since the" + + "member id is not null"); + } + instancesList.add(member.getInstanceId()); + } else { + if (log.isDebugEnabled()) { + log.debug("Instance ID is null for " + member.getMemberId() + " so not adding to" + + "the instance list"); + } + } + + //add forwarding rules(Ports to be forwarded) + for (Object port : member.getPorts()) { + int portValue = ((Port) port).getValue(); + if (!ipList.contains(portValue)) { //if port is not in list + //put the forwarding rule to list + if (log.isDebugEnabled()) { + log.debug("Port found: " + portValue); + } + ipList.add(portValue); + } + } + } + + GCEClusterConfigurationHolder gceClusterConfigurationHolder = new GCEClusterConfigurationHolder( + cluster.getClusterId(), instancesList, ipList); + + //set target pool name + String targetPoolName = targetPoolNameCreator(cluster.getClusterId()); + gceClusterConfigurationHolder.setTargetPoolName(targetPoolName); + + //set forwarding rule name + String forwardingRuleName = forwardingRuleNameCreator(cluster.getClusterId()); + gceClusterConfigurationHolder.setForwardingRuleName(forwardingRuleName); + + //set health check names + if (!ipList.isEmpty()) { + Collections.sort(ipList); + for (int port : ipList) { + String healthCheckName = healthCheckNameCreator(cluster.getClusterId(), port); + gceClusterConfigurationHolder.addHealthCheck(port, healthCheckName); + } + } else { + //the ip list is empty. So creating the default health check name + String healthCheckName = healthCheckNameCreator(cluster.getClusterId(), + Integer.parseInt(GCEContext.getInstance().getHealthCheckPort())); + gceClusterConfigurationHolder.addHealthCheck(Integer.parseInt(GCEContext. + getInstance().getHealthCheckPort()), healthCheckName); + } + + clusterToLoadBalancerConfigurationMap.put(cluster.getClusterId(), gceClusterConfigurationHolder); + createConfigurationForCluster(cluster.getClusterId()); + } + } + } + } + + //if any cluster is removed from the topology or if any cluster does not have at least one member, + //remove those clusters from map and remove the configuration from GCE too + List clustersToBeRemoved = new ArrayList(); + for (String clusterId : clusterToLoadBalancerConfigurationMap.keySet()) { + if (!activeClusterIdList.contains(clusterId)) { + log.info("Removing the configuration for cluster " + clusterId + "..."); + clustersToBeRemoved.add(clusterId); + } + } + for (String clusterId : clustersToBeRemoved) { + deleteConfigurationForCluster(clusterId); //remove from GCE + clusterToLoadBalancerConfigurationMap.remove(clusterId); //remove from local map + } + activeClusterIdList.clear(); + log.info("Load balancer was configured as given topology"); + return true; + } + + /** + * This method is used to delete all forwarding rules, target pools and health checks + * in IaaS side according to new topology + */ + private void deleteConfigurationForCluster(String clusterId) throws LoadBalancerExtensionException { + + log.info("Deleting configuration for cluster " + clusterId + "..."); + GCEClusterConfigurationHolder gceClusterConfigurationHolder = clusterToLoadBalancerConfigurationMap.get(clusterId); + //delete forwarding rule + gceOperations.deleteForwardingRule(gceClusterConfigurationHolder.getForwardingRuleName()); + //delete target pool from GCE + gceOperations.deleteTargetPool(gceClusterConfigurationHolder.getTargetPoolName()); + + //delete health checks from GCE + Collection healthCheckNames = gceClusterConfigurationHolder.getHealthCheckNames(); + for (String healthCheckName : healthCheckNames) { + gceOperations.deleteHealthCheck(healthCheckName); + } + log.info("Deleted configuration for cluster " + clusterId); + } + + /** + * This method is used to create target pools, forwarding rule and a health check related to a cluster + * in IaaS side according to new topology + */ + private void createConfigurationForCluster(String clusterId) throws LoadBalancerExtensionException { + + log.info("Creating configuration for cluster " + clusterId + "..."); + + GCEClusterConfigurationHolder gceClusterConfigurationHolder = clusterToLoadBalancerConfigurationMap.get(clusterId); + + List ipList = gceClusterConfigurationHolder.getIpList(); + + //create a port range String + String portRange; + + //if the ip list is empty + if (ipList.isEmpty()) { + log.warn("Ip list is null"); + //set all default port range + portRange = Constants.DEFAULT_PORT_RANGE; + } + //else if ip list has only one value + else if (ipList.size() == 1) { + portRange = Integer.toString(ipList.get(0)) + "-" + Integer.toString(ipList.get(0)); + } + //else we have more than 1 value + else { + //first we need to take the port range. So arrange ipList in ascending order + Collections.sort(ipList); + //take the first one and last one + portRange = Integer.toString(ipList.get(0)) + "-" + Integer.toString(ipList.get(ipList.size() - 1)); + } + + if (log.isDebugEnabled()) { + log.debug("Port range set as: " + portRange); + } + + //create all health checks + Map healthCheckMap = gceClusterConfigurationHolder.getHealthCheckMap(); + Iterator iterator = healthCheckMap.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry portMapNamePair = (Map.Entry) iterator.next(); + gceOperations.createHealthCheck((Integer) portMapNamePair.getKey(), (String) portMapNamePair.getValue()); + } + + //crate a target pool in GCE + gceOperations.createTargetPool(gceClusterConfigurationHolder.getTargetPoolName(), + gceClusterConfigurationHolder.getHealthCheckNames()); + + //add instances to target pool + gceOperations.addInstancesToTargetPool(gceClusterConfigurationHolder.getMemberList(), + gceClusterConfigurationHolder.getTargetPoolName()); + + //create the forwarding rule + gceOperations.createForwardingRule(gceClusterConfigurationHolder.getForwardingRuleName(), + gceClusterConfigurationHolder.getTargetPoolName(), Constants.PROTOCOL, portRange); + log.info("Created configuration for cluster" + clusterId); + } + + @Override + public void start() throws LoadBalancerExtensionException { + //Configuration has completed + log.info("GCE Load balancer instance started"); + } + + @Override + public void stop() throws LoadBalancerExtensionException { + + log.info("GCE Load Balancer is stopping..."); + + //iterate through hash map and remove all + Iterator iterator = clusterToLoadBalancerConfigurationMap.entrySet().iterator(); + while (iterator.hasNext()) { //for each configuration + Map.Entry clusterIDLoadBalancerConfigurationPair = (Map.Entry) iterator.next(); + deleteConfigurationForCluster((String) clusterIDLoadBalancerConfigurationPair.getKey()); + } + + log.info("GCE Load balancer stopped"); + } + + /** + * @throws LoadBalancerExtensionException + */ + @Override + public void reload() throws LoadBalancerExtensionException { + //nothing to do here + } + + /** + * Create a valid target pool name + * + * @param clusterId - Id of the cluster + * @return - a proper name for target pool + */ + private String targetPoolNameCreator(String clusterId) { + //create a valid target pool name by using cluster ID + //remove spaces, make all to lower case, replace all "." --> "-" + //add name prefix + String targetPoolName = GCEContext.getInstance().getNamePrefix().toLowerCase() + "-" + + clusterId.trim().toLowerCase().replace(".", "-"); + //length should be les than 62 characters + if (targetPoolName.length() >= Constants.MAX_NAME_LENGTH) { + targetPoolName = targetPoolName.substring(0, Constants.MAX_NAME_LENGTH); + } + return targetPoolName; + } + + /** + * Create a valid forwarding rule name + * + * @param clusterId - Id of the cluster + * @return - a proper name for forwarding rule + */ + private String forwardingRuleNameCreator(String clusterId) { + String forwardingRuleName = GCEContext.getInstance().getNamePrefix().toLowerCase() + "-" + + clusterId.trim().toLowerCase().replace(".", "-"); + + //length should be les than 62 characters + if (forwardingRuleName.length() >= Constants.MAX_NAME_LENGTH) { + forwardingRuleName = forwardingRuleName.substring(0, Constants.MAX_NAME_LENGTH); + } + return forwardingRuleName; + } + + /** + * create a valid health check name + * + * @param clusterId - id of the cluster + * @return - a proper name for health check + */ + private String healthCheckNameCreator(String clusterId, int port) { + String healthCheckName = GCEContext.getInstance().getNamePrefix().toLowerCase() + "-" + + clusterId.trim().toLowerCase().replace(".", "-"); + + //length should be less than 62 characters + //keep 6 characters to add the port at the end + if (healthCheckName.length() >= Constants.MAX_NAME_LENGTH) { + healthCheckName = healthCheckName.substring(0, Constants.MAX_NAME_LENGTH - 6); + } + + //add the port number at the end + healthCheckName = healthCheckName.concat("-" + Integer.toString(port)); + return healthCheckName; + } +} \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCEStatisticsReader.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCEStatisticsReader.java new file mode 100644 index 0000000000..649148465a --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/GCEStatisticsReader.java @@ -0,0 +1,51 @@ +/* + * 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.gce.extension; + + +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; + +/** + * GCE extension statistics reader class. + */ +public class GCEStatisticsReader implements LoadBalancerStatisticsReader { + + private TopologyProvider topologyProvider; + private String clusterInstanceId; + + public GCEStatisticsReader(TopologyProvider topologyProvider) { + this.topologyProvider = topologyProvider; + this.clusterInstanceId = System.getProperty(StratosConstants. + CLUSTER_INSTANCE_ID, StratosConstants.NOT_DEFINED); + } + + @Override + public String getClusterInstanceId() { + return clusterInstanceId; + } + + @Override + public int getInFlightRequestCount(String clusterId) { + // That is not possible to read the request count via the GCE API at the moment + return 0; + } +} \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/Main.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/Main.java new file mode 100644 index 0000000000..66937c0a34 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/Main.java @@ -0,0 +1,112 @@ +/* + * 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.gce.extension; + +import org.apache.axiom.om.OMElement; +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.common.util.AxiomXpathParserUtil; +import org.apache.stratos.gce.extension.config.Constants; +import org.apache.stratos.gce.extension.config.GCEContext; +import org.apache.stratos.gce.extension.config.parser.GCEConfigParser; +import org.apache.stratos.load.balancer.common.topology.TopologyProvider; +import org.apache.stratos.load.balancer.extension.api.LoadBalancerExtension; + +import java.io.File; +import java.util.concurrent.ExecutorService; + +/** + * GCE 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 { + + //read configuration from gce-configuration.xml and store configuration in GCEConfigurationHolder class + File configFile = new File(getFilePathOfConfigFile(Constants.CONFIG_FILE_NAME)); + OMElement documentElement = AxiomXpathParserUtil.parse(configFile); + GCEConfigParser.parse(documentElement); + + // Configure log4j properties + PropertyConfigurator.configure(System.getProperty("log4j.properties.file.path")); + if (log.isInfoEnabled()) { + log.info("GCE extension started"); + } + + // Add shutdown hook + final Thread mainThread = Thread.currentThread(); + final LoadBalancerExtension finalExtension = extension; + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + try { + if (finalExtension != null) { + log.info("GCE instance is stopping..."); + finalExtension.stop(); + } + mainThread.join(); + } catch (Exception e) { + log.error(e); + } + } + }); + + executorService = StratosThreadPool.getExecutorService("gce.extension.thread.pool", 10); + + // Validate runtime parameters + TopologyProvider topologyProvider = new TopologyProvider(); + + //If user has enabled the cep stats publisher, create a stat publisher object. Else null + GCEStatisticsReader statisticsReader = GCEContext.getInstance().isCEPStatsPublisherEnabled() ? + new GCEStatisticsReader(topologyProvider) : null; + extension = new LoadBalancerExtension(new GCELoadBalancer(), statisticsReader, topologyProvider); + extension.setExecutorService(executorService); + extension.execute(); + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error(e); + } + if (extension != null) { + log.info("Shutting GCE instance..."); + extension.stop(); + } + } + } + + /** + * get the full path of a given file which is located in conf folder + * + * @param fileName - name of file name + * @return - full path of given file + */ + private static String getFilePathOfConfigFile(String fileName) { + String workingDirectory = System.getProperty("user.dir"); + return workingDirectory + File.separator + ".." + File.separator + Constants.CONFIG_FOLDER_NAME + File.separator + fileName; + } +} \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/Constants.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/Constants.java new file mode 100644 index 0000000000..f919546264 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/Constants.java @@ -0,0 +1,71 @@ +/* + * 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.gce.extension.config; + +/** + * GCE extension constants. + */ +public class Constants { + public static final String CONFIG_FILE_NAME = "gce-configuration.xml"; + public static final String CONFIG_FOLDER_NAME = "conf"; + + //CEP configuration + public static final String CEP_STATS_PUBLISHER_ELEMENT = "cepStatsPublisher"; + public static final String CEP_STATS_PUBLISHER_ENABLED = "enable"; + public static final String THRIFT_RECEIVER_IP = "thriftReceiverIp"; + public static final String THRIFT_RECEIVER_PORT = "thriftReceiverPort"; + + //IaaS provider configuration + public static final String IAAS_PROPERTIES_ELEMENT = "iaasProperties"; + public static final String PROJECT_NAME = "projectName"; + public static final String PROJECT_ID = "projectId"; + public static final String REGION_NAME = "regionName"; + public static final String KEY_FILE_PATH = "keyFilePath"; + public static final String GCE_ACCOUNT_ID = "gceAccountId"; + public static final String NETWORK_NAME = "networkName"; + + //health check configuration + public static final String HEALTH_CHECK_PROPERTIES_ELEMENT = "healthCheckProperties"; + public static final String HEALTH_CHECK_REQUEST_PATH = "healthCheckRequestPath"; + public static final String HEALTH_CHECK_PORT = "healthCheckPort"; //the default health check port + public static final String HEALTH_CHECK_INTERVAL_SEC = "healthCheckIntervalSec"; + public static final String HEALTH_CHECK_TIME_OUT_SEC = "healthCheckTimeoutSec"; + public static final String HEALTH_CHECK_UNHEALTHY_THRESHOLD = "healthCheckUnhealthyThreshold"; + public static final String HEALTH_CHECK_HEALTHY_THRESHOLD = "healthCheckHealthyThreshold"; + + //other properties + public static final String OPERATION_TIMEOUT = "operationTimeout"; + public static final String NAME_PREFIX = "namePrefix"; + public static final String GCE_API_URL="gceApiUrl"; + + + //PROTOCOL should be TCP or UDP + public static final String PROTOCOL = "TCP"; + //set all ports to be opened if the application does not have any port defined + public static final String DEFAULT_PORT_RANGE="1-65535"; + //maximum length the name which allowed by GCE API + public static final int MAX_NAME_LENGTH = 62; + + //the forward slash character + public static final String FORWARD_SLASH="/"; + //strings + public static final String ZONES_STR="zones"; + public static final String INSTANCES_STR="instances"; +} diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEClusterConfigurationHolder.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEClusterConfigurationHolder.java new file mode 100644 index 0000000000..aeefd2cf43 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEClusterConfigurationHolder.java @@ -0,0 +1,102 @@ +/* + * 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.gce.extension.config; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Since GCE have separate target pools and forwarding rules, we need + * a class to concatenate target pools and forwarding rules which belongs to + * one cluster in stratos. + * This class is used to hold the configuration for a load balancer + * Each cluster will have one object from this class + */ +public class GCEClusterConfigurationHolder { + + //A cluster should have set of members + private List memberList; + //A cluster can have one IPs to be forwarded + private List ipList; + //cluster ID from stratos side + private String clusterID; + private String forwardingRuleName; + private String targetPoolName; + //a map to hold the health check names and corresponding port values + private Map healthCheckMap; + + public GCEClusterConfigurationHolder(String clusterID, List memberList, + List ipList) { + this.clusterID = clusterID; + this.memberList = memberList; + this.ipList = ipList; + healthCheckMap = new HashMap(); + } + + public List getIpList() { + return ipList; + } + + public String getForwardingRuleName() { + return forwardingRuleName; + } + + public void setForwardingRuleName(String forwardingRuleName) { + this.forwardingRuleName = forwardingRuleName; + } + + public List getMemberList() { + return memberList; + } + + public String getClusterID() { + return clusterID; + } + + public String getTargetPoolName() { + return targetPoolName; + } + + public void setTargetPoolName(String targetPoolName) { + this.targetPoolName = targetPoolName; + } + + public Map getHealthCheckMap() { + return healthCheckMap; + } + + public Collection getHealthCheckNames() { + return healthCheckMap.values(); + } + + public void addHealthCheck(int port, String healthCheckName) { + this.healthCheckMap.put(port, healthCheckName); + } + + public void addMember(String memberId) { + this.memberList.add(memberId); + } + + public void removeMember(String memberId) { + this.memberList.remove(memberId); + } +} \ No newline at end of file diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEContext.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEContext.java new file mode 100644 index 0000000000..b166bf454e --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/GCEContext.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.stratos.gce.extension.config; + +import org.apache.commons.lang.StringUtils; +import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException; + +/** + * This class is used to store configuration properties for gce-extension + */ +public class GCEContext { + private static volatile GCEContext context; + + //cep stat publisher properties + private boolean cepStatsPublisherEnabled; + private String thriftReceiverIp; + private String thriftReceiverPort; + + //IaaS properties + private String projectName; + private String projectID; + private String regionName; + private String keyFilePath; + private String gceAccountID; + private String networkName; + + //health check properties + private String healthCheckRequestPath; + private String healthCheckPort; // the default health check port + private String healthCheckTimeOutSec; + private String healthCheckIntervalSec; + private String healthCheckUnhealthyThreshold; + private String healthCheckHealthyThreshold; + private String gceApiUrl; + + //other properties + private String namePrefix; + private String operationTimeout; + + //private constructor + private GCEContext() { + } + + public static GCEContext getInstance() { + if (context == null) { + synchronized (GCEContext.class) { + if (context == null) { + context = new GCEContext(); + } + } + } + return context; + } + + public void validate() throws LoadBalancerExtensionException { + validateProperty(Boolean.toString(cepStatsPublisherEnabled)); + validateProperty(namePrefix); + validateProperty(projectName); + validateProperty(projectID); + validateProperty(regionName); + validateProperty(keyFilePath); + validateProperty(gceAccountID); + validateProperty(healthCheckRequestPath); + validateProperty(healthCheckPort); + validateProperty(healthCheckTimeOutSec); + validateProperty(healthCheckIntervalSec); + validateProperty(healthCheckHealthyThreshold); + validateProperty(healthCheckHealthyThreshold); + validateProperty(networkName); + validateProperty(operationTimeout); + validateProperty(gceApiUrl); + + if (cepStatsPublisherEnabled) { + validateProperty(Constants.THRIFT_RECEIVER_IP); + validateProperty(Constants.THRIFT_RECEIVER_PORT); + } + } + + private void validateProperty(String propertyName) throws LoadBalancerExtensionException { + if (StringUtils.isEmpty(propertyName)) { + throw new LoadBalancerExtensionException("Property was not found: " + propertyName); + } + } + + public String getHealthCheckIntervalSec() { + return healthCheckIntervalSec; + } + + public void setHealthCheckIntervalSec(String healthCheckIntervalSec) { + this.healthCheckIntervalSec = healthCheckIntervalSec; + } + + public boolean isCEPStatsPublisherEnabled() { + return cepStatsPublisherEnabled; + } + + public String getNamePrefix() { + return namePrefix; + } + + public void setNamePrefix(String namePrefix) { + this.namePrefix = namePrefix; + } + + public String getProjectName() { + return projectName; + } + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + public String getProjectID() { + return projectID; + } + + public void setProjectID(String projectID) { + this.projectID = projectID; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public String getKeyFilePath() { + return keyFilePath; + } + + public void setKeyFilePath(String keyFilePath) { + this.keyFilePath = keyFilePath; + } + + public String getGceAccountID() { + return gceAccountID; + } + + public void setGceAccountID(String gceAccountID) { + this.gceAccountID = gceAccountID; + } + + public String getHealthCheckRequestPath() { + return healthCheckRequestPath; + } + + public void setHealthCheckRequestPath(String healthCheckRequestPath) { + this.healthCheckRequestPath = healthCheckRequestPath; + } + + public String getHealthCheckHealthyThreshold() { + return healthCheckHealthyThreshold; + } + + public void setHealthCheckHealthyThreshold(String healthCheckHealthyThreshold) { + this.healthCheckHealthyThreshold = healthCheckHealthyThreshold; + } + + public String getHealthCheckPort() { + return healthCheckPort; + } + + public void setHealthCheckPort(String healthCheckPort) { + this.healthCheckPort = healthCheckPort; + } + + public String getHealthCheckTimeOutSec() { + return healthCheckTimeOutSec; + } + + public void setHealthCheckTimeOutSec(String healthCheckTimeOutSec) { + this.healthCheckTimeOutSec = healthCheckTimeOutSec; + } + + public String getHealthCheckUnhealthyThreshold() { + return healthCheckUnhealthyThreshold; + } + + public void setHealthCheckUnhealthyThreshold(String healthCheckUnhealthyThreshold) { + this.healthCheckUnhealthyThreshold = healthCheckUnhealthyThreshold; + } + + public String getNetworkName() { + return networkName; + } + + public void setNetworkName(String networkName) { + this.networkName = networkName; + } + + public String getOperationTimeout() { + return operationTimeout; + } + + public void setOperationTimeout(String operationTimeout) { + this.operationTimeout = operationTimeout; + } + + public void setCepStatsPublisherEnabled(boolean cepStatsPublisherEnabled) { + this.cepStatsPublisherEnabled = cepStatsPublisherEnabled; + } + + public void setThriftReceiverIp(String thriftReceiverIp) { + this.thriftReceiverIp = thriftReceiverIp; + } + + public void setThriftReceiverPort(String thriftReceiverPort) { + this.thriftReceiverPort = thriftReceiverPort; + } + + public String getGceApiUrl() { return gceApiUrl; } + + public void setGceApiUrl(String gceApiUrl) { this.gceApiUrl = gceApiUrl; } +} diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/parser/GCEConfigParser.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/parser/GCEConfigParser.java new file mode 100644 index 0000000000..d235316467 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/config/parser/GCEConfigParser.java @@ -0,0 +1,269 @@ +package org.apache.stratos.gce.extension.config.parser; + +/* + * 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. + */ + +import org.apache.axiom.om.OMElement; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.common.exception.MalformedConfigurationFileException; +import org.apache.stratos.common.util.AxiomXpathParserUtil; +import org.apache.stratos.gce.extension.config.Constants; +import org.apache.stratos.gce.extension.config.GCEContext; +import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException; + +import javax.xml.namespace.QName; + +/** + * parse the gce-configuration.xml + */ +public class GCEConfigParser { + private static final Log log = LogFactory.getLog(GCEConfigParser.class); + private static GCEContext gceContext; + + /** + * Parse the gce-configuration.xml file when the extension is starting up. + * + * @param documentElement axiom document element. + * @throws MalformedConfigurationFileException + */ + public static void parse(OMElement documentElement) throws LoadBalancerExtensionException { + + if (log.isDebugEnabled()) { + log.debug("Parsing the configuration xml file "); + } + + //get cep info + OMElement cepInfoElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, + Constants.CEP_STATS_PUBLISHER_ELEMENT); + extractCepConfiguration(cepInfoElement); + + //get GCE IaaS info + OMElement gceIaasInfoElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, + Constants.IAAS_PROPERTIES_ELEMENT); + extractGceIaasInformation(gceIaasInfoElement); + + //get heath check info + OMElement healthCheckPropertiesElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, + Constants.HEALTH_CHECK_PROPERTIES_ELEMENT); + extractHealthCheckProperties(healthCheckPropertiesElement); + + //extract other properties + extractOtherProperties(documentElement); + + //validate all extracted properties - just a null check + if (log.isDebugEnabled()) { + log.debug("Validating the properties read from configuration xml file"); + } + gceContext.validate(); + } + + /** + * Extract cep ip and port and store in gceContext object + * + * @param cepInfoElement - OMElement which is containing the cep information + */ + private static void extractCepConfiguration(OMElement cepInfoElement) { + //Check whether the cep stat publisher enabled or not + QName qName = new QName(Constants.CEP_STATS_PUBLISHER_ENABLED); + String enabled = cepInfoElement.getAttributeValue(qName); + + gceContext = GCEContext.getInstance(); + gceContext.setCepStatsPublisherEnabled(Boolean.parseBoolean(enabled)); + + //if stat publisher is enabled + if (Boolean.parseBoolean(enabled)) { + //extract rest configuration of cep + + OMElement thriftReceiverIpElement = AxiomXpathParserUtil.getFirstChildElement(cepInfoElement, + Constants.THRIFT_RECEIVER_IP); + OMElement thriftReceiverPortElement = AxiomXpathParserUtil.getFirstChildElement(cepInfoElement, + Constants.THRIFT_RECEIVER_PORT); + + if (thriftReceiverIpElement != null) { + //set extracted ip to gceContext object + gceContext.setThriftReceiverIp(thriftReceiverIpElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Thrift receiver IP: " + thriftReceiverIpElement.getText()); + } + } + + if (thriftReceiverPortElement != null) { + //set extracted port to gceContext object + gceContext.setThriftReceiverPort(thriftReceiverPortElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Thrift receiver port: " + thriftReceiverPortElement.getText()); + } + } + } + } + + /** + * extract Iaas properties from given OMElement and store it in gceContext object + * + * @param gceIaasInfoElement - OMElement which contains Iaas properties + */ + private static void extractGceIaasInformation(OMElement gceIaasInfoElement) { + OMElement projectNameElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.PROJECT_NAME); + OMElement projectIdElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.PROJECT_ID); + OMElement regionNameElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.REGION_NAME); + OMElement keyFilePathElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.KEY_FILE_PATH); + OMElement gceAccountIdElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.GCE_ACCOUNT_ID); + OMElement networkNameElement = AxiomXpathParserUtil.getFirstChildElement(gceIaasInfoElement, Constants.NETWORK_NAME); + + //set extracted properties to gceContext object + if (projectNameElement != null) { + gceContext.setProjectName(projectNameElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Project Name: " + projectNameElement.getText()); + } + } + + if (projectIdElement != null) { + gceContext.setProjectID(projectIdElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Project ID: " + projectIdElement.getText()); + } + } + + if (regionNameElement != null) { + gceContext.setRegionName(regionNameElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Region Name: " + regionNameElement.getText()); + } + } + + if (keyFilePathElement != null) { + gceContext.setKeyFilePath(keyFilePathElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Key file path: " + keyFilePathElement.getText()); + } + } + + if (gceAccountIdElement != null) { + gceContext.setGceAccountID(gceAccountIdElement.getText()); + if (log.isDebugEnabled()) { + log.debug("GCE Account ID: " + gceAccountIdElement.getText()); + } + } + if (networkNameElement != null) { + gceContext.setNetworkName(networkNameElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Network Name: " + networkNameElement.getText()); + } + } + } + + /** + * extract health check properties from given OMElement and store it in gceContext object + * + * @param healthCheckPropertiesElement - OMElement which contains health check properties + */ + private static void extractHealthCheckProperties(OMElement healthCheckPropertiesElement) { + OMElement healthCheckRequestPathElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_REQUEST_PATH); + OMElement healthCheckPortElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_PORT); + OMElement healthCheckTimeoutSecElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_TIME_OUT_SEC); + OMElement healthCheckUnhealthyThresholdElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_UNHEALTHY_THRESHOLD); + OMElement heathCheckIntervalSecElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_INTERVAL_SEC); + OMElement healthCheckHealthyThresholdElement = AxiomXpathParserUtil.getFirstChildElement(healthCheckPropertiesElement, + Constants.HEALTH_CHECK_HEALTHY_THRESHOLD); + + //set extracted properties to gceContext object + if (healthCheckRequestPathElement != null) { + gceContext.setHealthCheckRequestPath(healthCheckRequestPathElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check request path: " + healthCheckRequestPathElement.getText()); + } + } + + if (healthCheckPortElement != null) { + gceContext.setHealthCheckPort(healthCheckPortElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check port: " + healthCheckPortElement.getText()); + } + } + + if (healthCheckTimeoutSecElement != null) { + gceContext.setHealthCheckTimeOutSec(healthCheckTimeoutSecElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check timeout sec: " + healthCheckTimeoutSecElement.getText()); + } + } + + if (healthCheckUnhealthyThresholdElement != null) { + gceContext.setHealthCheckUnhealthyThreshold(healthCheckUnhealthyThresholdElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check unhealthy threshold: " + healthCheckUnhealthyThresholdElement.getText()); + } + } + + if (heathCheckIntervalSecElement != null) { + gceContext.setHealthCheckIntervalSec(heathCheckIntervalSecElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check interval sec: " + heathCheckIntervalSecElement.getText()); + } + } + + if (healthCheckHealthyThresholdElement != null) { + gceContext.setHealthCheckHealthyThreshold(healthCheckHealthyThresholdElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Health check healthy threshold: " + healthCheckHealthyThresholdElement.getText()); + } + } + } + + /** + * extract all other properties which is not extracted from above methods and store in gceContext object + * + * @param documentElement - OMElement which contains other properties + */ + private static void extractOtherProperties(OMElement documentElement) { + OMElement operationTimeoutElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, Constants. + OPERATION_TIMEOUT); + OMElement namePrefixElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, Constants.NAME_PREFIX); + OMElement gceApiUrlElement = AxiomXpathParserUtil.getFirstChildElement(documentElement, Constants.GCE_API_URL); + + //set extracted properties to gceContext object + if (operationTimeoutElement != null) { + gceContext.setOperationTimeout(operationTimeoutElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Operation timeout: " + operationTimeoutElement.getText()); + } + } + + if (namePrefixElement != null) { + gceContext.setNamePrefix(namePrefixElement.getText()); + if (log.isDebugEnabled()) { + log.debug("Name prefix: " + namePrefixElement.getText()); + } + } + + if (gceApiUrlElement != null) { + gceContext.setGceApiUrl(gceApiUrlElement.getText()); + if (log.isDebugEnabled()) { + log.debug("GCE API URL: " + gceApiUrlElement.getText()); + } + } + } +} diff --git a/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/util/GCEOperations.java b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/util/GCEOperations.java new file mode 100644 index 0000000000..8f05be6d08 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/java/org/apache/stratos/gce/extension/util/GCEOperations.java @@ -0,0 +1,599 @@ +/* + * 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.gce.extension.util; + +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.compute.Compute; +import com.google.api.services.compute.ComputeScopes; +import com.google.api.services.compute.model.*; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.gce.extension.config.Constants; +import org.apache.stratos.gce.extension.config.GCEContext; +import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException; + +import java.io.File; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * All the GCE API calls will be done using this class + */ +public class GCEOperations { + private static final Log log = LogFactory.getLog(GCEOperations.class); + + //project related + private static final String PROJECT_NAME = GCEContext.getInstance().getProjectName(); + private static final String PROJECT_ID = GCEContext.getInstance().getProjectID(); + private static final String REGION_NAME = GCEContext.getInstance().getRegionName(); + + //auth + private static final String KEY_FILE_PATH = GCEContext.getInstance().getKeyFilePath(); + private static final String ACCOUNT_ID = GCEContext.getInstance().getGceAccountID(); + + //health check + private static final String HEALTH_CHECK_REQUEST_PATH = GCEContext.getInstance().getHealthCheckRequestPath(); + private static final String HEALTH_CHECK_TIME_OUT_SEC = GCEContext.getInstance().getHealthCheckTimeOutSec(); + private static final String HEALTH_CHECK_INTERVAL_SEC = GCEContext.getInstance().getHealthCheckIntervalSec(); + private static final String HEALTH_CHECK_UNHEALTHY_THRESHOLD = GCEContext.getInstance().getHealthCheckUnhealthyThreshold(); + private static final String HEALTH_CHECK_HEALTHY_THRESHOLD = GCEContext.getInstance().getHealthCheckHealthyThreshold(); + + //a timeout for operation completion + private static final int OPERATION_TIMEOUT = Integer.parseInt(GCEContext.getInstance().getOperationTimeout()); + static Compute compute; + + //the url of the GCE API + private static final String GCE_API_URL = GCEContext.getInstance().getGceApiUrl(); + + /** + * Constructor for GCE Operations Class + */ + public GCEOperations() throws IOException, GeneralSecurityException { + buildComputeEngineObject(); + } + + /** + * Authorize and build compute engine object + */ + private void buildComputeEngineObject() throws IOException, GeneralSecurityException { + + try { + + if (log.isDebugEnabled()) { + log.debug("Authorizing and building the compute engine object"); + } + + HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); + JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); + + GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport) + .setJsonFactory(jsonFactory) + .setServiceAccountId(ACCOUNT_ID) + .setServiceAccountScopes(Collections.singleton(ComputeScopes.COMPUTE)) + .setServiceAccountPrivateKeyFromP12File(new File(KEY_FILE_PATH)) + .build(); + + // Create compute engine object + compute = new Compute.Builder( + httpTransport, jsonFactory, null).setApplicationName(PROJECT_NAME) + .setHttpRequestInitializer(credential).build(); + if (log.isDebugEnabled()) { + log.debug("Successfully built the compute engine object"); + } + } catch (GeneralSecurityException e) { + //Security exception occurred. Cant proceed further + log.error("Could not authenticate and build compute object", e); + throw new GeneralSecurityException(e); + } catch (IOException e) { + //IO exception occurred. Cant proceed further + log.error("Could not authenticate and build compute object", e); + throw new IOException(e); + } + } + + /** + * Get list of instances in given project and zone which matches the given filter + * + * @param zoneName - name of the zone + * @param filter - a condition to filter the instances + * @return instanceList - list of instances(members in Stratos side) + */ + public static InstanceList getInstanceList(String zoneName, String filter) { + Compute.Instances.List instances; + try { + instances = compute.instances(). + list(PROJECT_ID, zoneName).setFilter(filter); + InstanceList instanceList = instances.execute(); + if (instanceList.getItems() == null) { + log.warn("No instances found for filter " + filter + " and zone " + zoneName); + return null; + } else { + return instanceList; + } + } catch (IOException e) { + log.error("Could not get instance list from GCE ", e); + return null; + } + } + + /** + * Get instance resource URL from given instance name + * + * @param instanceId - Id of the instance provided by IaaS + * @return - Resource URL of the instance in IaaS + */ + public static String getInstanceURLFromId(String instanceId) { + + String instanceURL; + String zoneName = getZoneNameFromInstanceId(instanceId); + String filter = "name eq " + getInstanceNameFromInstanceId(instanceId); + //check whether the given instance is available + InstanceList instanceList = getInstanceList(zoneName, filter); + if (instanceList == null) { + log.warn("No matching instance found for filter " + filter); + return null; + } + for (Instance instance : instanceList.getItems()) { + String instanceIdInIaaS = zoneName + "/" + instance.getName(); + if (instanceIdInIaaS.equals(instanceId)) { + //instance is available + //getInstance URL + instanceURL = instance.getSelfLink(); + return instanceURL; + } + } + log.warn("No matching instance found for filter " + filter); + return null; + } + + /** + * Get a given health check resource URL + * + * @param healthCheckName - name of the health check in IaaS + * @return - Resource URL of health check in IaaS side + */ + public static String getHealthCheckURLFromName(String healthCheckName) { + + String healthCheckURL; + + //check whether the given instance is available + HttpHealthCheckList healthCheckList; + healthCheckList = getHealthCheckList(); + if (healthCheckList == null) { + log.warn("Could not found health check " + healthCheckName + " because the health check list is null"); + return null; + } + for (HttpHealthCheck httpHealthCheck : healthCheckList.getItems()) { + if (httpHealthCheck.getName().equals(healthCheckName)) { + //instance is available + //getInstance URL + healthCheckURL = httpHealthCheck.getSelfLink(); + return healthCheckURL; + } + } + log.warn("Could not found the health check " + healthCheckName); + return null; + } + + /** + * Get list of health checks + * + * @return - list of health checks + */ + private static HttpHealthCheckList getHealthCheckList() { + + Compute.HttpHealthChecks.List healthChecks; + try { + healthChecks = compute.httpHealthChecks().list(PROJECT_ID); + HttpHealthCheckList healthCheckList = healthChecks.execute(); + if (healthCheckList.getItems() == null) { + log.info("No health check found for specified project"); + return null; + } else { + return healthCheckList; + } + } catch (IOException e) { + log.error("Could not get health check list from GCE", e); + return null; + } + } + + /** + * Manually create the self link for an instance. This method is useful when the instance is deleted from IaaS + * + * @return - the self link of the instance + */ + private static String createInstanceSelfLink(String instanceId) { + + return GCE_API_URL + PROJECT_ID + + Constants.FORWARD_SLASH + Constants.ZONES_STR + Constants.FORWARD_SLASH + + getZoneNameFromInstanceId(instanceId) + Constants.FORWARD_SLASH + Constants.INSTANCES_STR + + Constants.FORWARD_SLASH + getInstanceNameFromInstanceId(instanceId); + } + + /** + * Creating a new target pool in IaaS + * + * @param targetPoolName - name of the target pool in IaaS + * @param healthCheckNames - names of the health check in IaaS + */ + public void createTargetPool(String targetPoolName, Collection healthCheckNames) { + + log.info("Creating target pool: " + targetPoolName); + TargetPool targetPool = new TargetPool(); + targetPool.setName(targetPoolName); + List httpHealthChecks = new ArrayList(); + + //add all health checks to httpHealthChecks ArrayList + for (String healthCheckName : healthCheckNames) { + httpHealthChecks.add(getHealthCheckURLFromName(healthCheckName)); + } + targetPool.setHealthChecks(httpHealthChecks); + + try { + Operation operation = + compute.targetPools().insert(PROJECT_ID, REGION_NAME, targetPool).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Target pool " + targetPoolName + " was created"); + } catch (Exception e) { + log.error("Could not create target pool: " + targetPoolName, e); + } + } + + /** + * Deleting an exiting target pool in IaaS + * + * @param targetPoolName - Name of the target pool in IaaS + */ + public void deleteTargetPool(String targetPoolName) { + log.info("Deleting target pool: " + targetPoolName); + try { + Operation operation = compute.targetPools().delete(PROJECT_ID, REGION_NAME, targetPoolName).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Target pool: " + targetPoolName + " was deleted"); + } catch (Exception e) { + log.error("Could not delete target pool " + targetPoolName, e); + } + } + + /** + * create forwarding rule by using given target pool and protocol + * + * @param forwardingRuleName - name of the forwarding rule in IaaS to be created + * @param targetPoolName - name of the target pool in IaaS which is already created + * @param protocol - The protocol which is used to forward traffic. Should be either TCP or UDP + */ + + public void createForwardingRule(String forwardingRuleName, String targetPoolName, String protocol, + String portRange) { + + log.info("Creating a forwarding rule: " + forwardingRuleName); + //Need to get target pool resource URL + TargetPool targetPool = getTargetPool(targetPoolName); + String targetPoolURL = targetPool.getSelfLink(); + ForwardingRule forwardingRule = new ForwardingRule(); + forwardingRule.setName(forwardingRuleName); + forwardingRule.setTarget(targetPoolURL); + forwardingRule.setIPProtocol(protocol); + forwardingRule.setPortRange(portRange); + try { + Operation operation = compute.forwardingRules().insert(PROJECT_ID, REGION_NAME, forwardingRule).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Forwarding rule: " + forwardingRuleName + " was created"); + } catch (Exception e) { + log.error("Could not create a forwarding rule " + forwardingRuleName, e); + } + } + + /** + * Deleting a existing forwarding rule in IaaS + * + * @param forwardingRuleName - Forwarding rule name in IaaS + */ + public void deleteForwardingRule(String forwardingRuleName) { + log.info("Deleting forwarding rule: " + forwardingRuleName); + try { + Operation operation = compute.forwardingRules(). + delete(PROJECT_ID, REGION_NAME, forwardingRuleName).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Forwarding rule " + forwardingRuleName + " was deleted"); + } catch (Exception e) { + log.error("Could not delete forwarding rule " + forwardingRuleName, e); + } + } + + /** + * Check whether the given target pool is already exists in the given project and region. + * Target pools are unique for regions, not for zones + * + * @param targetPoolName - target pool name in IaaS + */ + public boolean isTargetPoolExists(String targetPoolName) { + + try { + Compute.TargetPools.List targetPools = compute.targetPools(). + list(PROJECT_ID, REGION_NAME); + TargetPoolList targetPoolList = targetPools.execute(); + for (TargetPool targetPool : targetPoolList.getItems()) { + if (targetPool.getName().equals(targetPoolName)) { + if (log.isDebugEnabled()) { + log.debug("Target pool " + targetPoolName + " exists"); + } + return true; + } + } + } catch (IOException e) { + log.error("Could not check whether the target pool " + targetPoolName + " exists or not ", e); + } + if (log.isDebugEnabled()) { + log.debug("Target pool " + targetPoolName + " does not exist"); + } + return false; + } + + /** + * Get a target pool already created in GCE + * + * @param targetPoolName - target pool name in IaaS + * @return - target pool object + */ + public TargetPool getTargetPool(String targetPoolName) { + + try { + if (isTargetPoolExists(targetPoolName)) { + return compute.targetPools().get(PROJECT_ID, REGION_NAME, targetPoolName).execute(); + } else { + if (log.isDebugEnabled()) { + log.debug("Requested Target Pool " + targetPoolName + " Is not Available"); + } + } + return null; + } catch (IOException e) { + log.error("Could not get target pool " + targetPoolName, e); + } + return null; + } + + /** + * Remove given set of instances from target pool + * + * @param targetPoolName - target pool name from IaaS + * @param instancesIdsList - List of instances to be removed from target pool + */ + public void removeInstancesFromTargetPool(List instancesIdsList, String targetPoolName) { + + log.info("Removing instances from target pool: " + targetPoolName); + if (instancesIdsList.isEmpty()) { + log.warn("Cannot remove instances to target pool. Because instancesNamesList is empty."); + return; + } + + List instanceReferenceList = new ArrayList(); + + //add instance to instance reference list, it is required to use the instance URL + for (String instanceId : instancesIdsList) { //for all instances + String instanceUrl = createInstanceSelfLink(instanceId); + instanceReferenceList.add(new InstanceReference(). + setInstance(instanceUrl)); + if (log.isDebugEnabled()) { + log.debug("Instance " + instanceId + " was added to instance reference list"); + } + } + + //create target pools add instance request and set instance to it + TargetPoolsRemoveInstanceRequest targetPoolsRemoveInstanceRequest = new + TargetPoolsRemoveInstanceRequest(); + if (instanceReferenceList.isEmpty()) { + log.warn("Could not remove instances from target pool " + targetPoolName + " because instance reference " + + "list is null"); + return; + } + targetPoolsRemoveInstanceRequest.setInstances(instanceReferenceList); + + try { + //execute + Operation operation = compute.targetPools().removeInstance(PROJECT_ID, REGION_NAME, + targetPoolName, targetPoolsRemoveInstanceRequest).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Instances are removed from target pool: " + targetPoolName); + } catch (Exception e) { + log.error("Could not remove instances from target pool " + targetPoolName, e); + } + } + + /** + * Add a given list of instances to a target pool + * + * @param instancesIdsList - list of instance Ids + * @param targetPoolName - target pool name in IaaS + */ + public void addInstancesToTargetPool(List instancesIdsList, String targetPoolName) { + + log.info("Adding instances to target pool: " + targetPoolName); + + if (instancesIdsList.isEmpty()) { + log.warn("Cannot add instances to target pool. InstancesNamesList is empty."); + return; + } + + List instanceReferenceList = new ArrayList(); + + //add instance to instance reference list, we should use the instance URL + for (String instanceId : instancesIdsList) { //for all instances + String instanceUrl = getInstanceURLFromId(instanceId); + if (instanceUrl != null) { + instanceReferenceList.add(new InstanceReference(). + setInstance(instanceUrl)); + if (log.isDebugEnabled()) { + log.debug("Instance " + instanceId + " was added to instance reference list"); + } + } + + } + + //create target pools add instance request and set instance to it + TargetPoolsAddInstanceRequest targetPoolsAddInstanceRequest = new + TargetPoolsAddInstanceRequest(); + if (instanceReferenceList.isEmpty()) { + log.warn("Could not add instances to target pool " + targetPoolName + " because instance reference list is null"); + return; + } + + targetPoolsAddInstanceRequest.setInstances(instanceReferenceList); + + try { + //execute + Operation operation = compute.targetPools().addInstance(PROJECT_ID, REGION_NAME, + targetPoolName, targetPoolsAddInstanceRequest).execute(); + waitForRegionOperationCompletion(operation.getName()); + log.info("Added instances to target pool: " + targetPoolName); + } catch (Exception e) { + log.error("Could not add instance to target pool" + targetPoolName, e); + } + } + + /** + * Create a health check in IaaS + * + * @param healthCheckName - name of the health check to be created + */ + public void createHealthCheck(int port, String healthCheckName) { + + log.info("Creating health check: " + healthCheckName); + + HttpHealthCheck httpHealthCheck = new HttpHealthCheck(); + httpHealthCheck.setName(healthCheckName); + httpHealthCheck.setRequestPath(HEALTH_CHECK_REQUEST_PATH); + httpHealthCheck.setPort(port); + httpHealthCheck.setTimeoutSec(Integer.parseInt(HEALTH_CHECK_TIME_OUT_SEC)); + httpHealthCheck.setCheckIntervalSec(Integer.parseInt(HEALTH_CHECK_INTERVAL_SEC)); + httpHealthCheck.setUnhealthyThreshold(Integer.parseInt(HEALTH_CHECK_UNHEALTHY_THRESHOLD)); + httpHealthCheck.setHealthyThreshold(Integer.parseInt(HEALTH_CHECK_HEALTHY_THRESHOLD)); + try { + Operation operation = compute.httpHealthChecks().insert(PROJECT_ID, httpHealthCheck).execute(); + waitForGlobalOperationCompletion(operation.getName()); + log.info("Health check " + healthCheckName + " was created"); + } catch (Exception e) { + log.error("Could not create health check " + healthCheckName, e); + } + } + + public void deleteHealthCheck(String healthCheckName) { + log.info("Deleting Health Check: " + healthCheckName); + try { + Operation operation = compute.httpHealthChecks().delete(PROJECT_ID, healthCheckName).execute(); + waitForGlobalOperationCompletion(operation.getName()); + log.info("Health check: " + healthCheckName + " was deleted"); + } catch (Exception e) { + log.error("Could not get delete health check " + healthCheckName, e); + } + } + + /** + * Wait for a global operation completion. If the operation is related to whole project + * that is a global operation + * + * @param operationName - name of the operation in IaaS + */ + private void waitForGlobalOperationCompletion(String operationName) throws LoadBalancerExtensionException { + try { + if (log.isDebugEnabled()) { + log.debug("Waiting for operation " + operationName + " completion"); + } + //initially sleep for two seconds + Thread.sleep(2000); + int timeout = 0; + while (true) { + Operation operation = compute.globalOperations().get(PROJECT_ID, operationName).execute(); + if (("DONE").equals(operation.getStatus())) { + if (log.isDebugEnabled()) { + log.debug("Operation " + operationName + " completed successfully"); + } + return; + } + + if (timeout >= OPERATION_TIMEOUT) { + log.warn("Timeout reached for operation " + operationName + ". Existing.."); + return; + } + //sleep one second + Thread.sleep(1000); + timeout += 1000; + } + } catch (Exception e) { + log.error("Could not wait for global operation completion " + operationName, e); + throw new LoadBalancerExtensionException(e); + } + } + + /** + * Wait for a region operation completion. If the operation is related to a region that is a + * region operation + * + * @param operationName - name of the region operation + */ + + private void waitForRegionOperationCompletion(String operationName) throws LoadBalancerExtensionException { + try { + //initially wait for two seconds + Thread.sleep(2000); + int timeout = 0; + while (true) { + Operation operation = compute.regionOperations().get(PROJECT_ID, REGION_NAME, operationName).execute(); + + if (("DONE").equals(operation.getStatus())) { + if (log.isDebugEnabled()) { + log.debug("Operation " + operationName + " completed successfully"); + } + return; + } + if (timeout >= OPERATION_TIMEOUT) { + log.warn("Timeout reached for operation " + operationName + ". Existing.."); + return; + } + //wait for one second + Thread.sleep(1000); + timeout += 1000; + } + } catch (Exception e) { + log.error("Could not wait for region operation completion " + operationName, e); + throw new LoadBalancerExtensionException(e); + } + } + + private static String getZoneNameFromInstanceId(String instanceId) { + int lastIndexOfSlash = instanceId.lastIndexOf("/"); + return instanceId.substring(0, lastIndexOfSlash); + } + + private static String getInstanceNameFromInstanceId(String instanceId) { + int lastIndexOfSlash = instanceId.lastIndexOf("/"); + return instanceId.substring(lastIndexOfSlash + 1); + } +} + diff --git a/extensions/load-balancer/gce-extension/src/main/license/LICENSE b/extensions/load-balancer/gce-extension/src/main/license/LICENSE new file mode 100644 index 0000000000..7f14067dc8 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/license/LICENSE @@ -0,0 +1,481 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. +=================================================================================== + +=================================================================================== +The Apache Stratos distribution includes a number of run time dependencies with +separate copyright notices and license terms. Your use of the Apache Stratos code +is subject to the terms and conditions of the following licenses. +=================================================================================== + +=============================================================================== +The following components come under Apache Software License 2.0 +=============================================================================== + +org.wso2.carbon.base-4.2.0.jar +org.wso2.carbon.bootstrap-4.2.0.jar +org.wso2.carbon.core-4.2.0.jar +org.wso2.carbon.core.common-4.2.0.jar +org.wso2.carbon.databridge.agent.thrift-4.2 +org.wso2.carbon.databridge.commons-4.2. +org.wso2.carbon.databridge.commons.thrif +org.wso2.carbon.logging-4.2.0.jar +org.wso2.carbon.ndatasource.common-4.2. +org.wso2.carbon.ndatasource.rdbms-4.2.0.j +org.wso2.carbon.queuing-4.2.0.jar +org.wso2.carbon.registry.api-4.2.0.jar +org.wso2.carbon.registry.core-4.2.0.jar +org.wso2.carbon.registry.xboot-4.2.0.jar +org.wso2.carbon.securevault-4.2.0.jar +org.wso2.carbon.user.api-4.2.0.jar +org.wso2.carbon.user.core-4.2.0.jar +org.wso2.carbon.user.mgt-4.2.0.jar +org.wso2.carbon.user.mgt.common-4.2.0.ja +org.wso2.carbon.utils-4.2.0.jar +org.wso2.securevault-1.0.0-wso2v2.jar +abdera-1.0.0.wso2v3.jar +andes-client-0.13.wso2v8.jar +annotations-1.3.2.jar +ant-1.7.0.jar +ant-launcher-1.7.0.jar +axiom-1.2.11.wso2v4.jar +axiom-api-1.2.11.jar +axiom-impl-1.2.11.jar +axis2-1.6.1.wso2v10.jar +commons-cli-1.0.jar +commons-codec-1.2.jar +commons-collections-3.2.0.wso2v +commons-collections-3.2.1.jar +commons-dbcp-1.4.0.wso2v1.jar +commons-fileupload-1.2.0.wso2v1 +commons-fileupload-1.2.jar +commons-httpclient-3.1.0.wso2v2. +commons-httpclient-3.1.jar +commons-io-2.0.0.wso2v2.jar +commons-io-2.0.jar +commons-lang-2.4.jar +commons-lang-2.6.0.wso2v1.jar +commons-lang3-3.1.jar +commons-logging-1.1.1.jar +commons-pool-1.5.6.jar +commons-pool-1.5.6.wso2v1.jar +compass-2.0.1.wso2v2.jar +geronimo-activation_1.1_spec-1.0.2.jar +geronimo-javamail_1.4_spec-1.6.jar +geronimo-jms_1.1_spec-1.1.jar +geronimo-stax-api_1.0_spec-1.0.1.jar +gson-2.2.4.jar +hazelcast-3.0.1.jar +hazelcast-3.0.1.wso2v1.jar +httpclient-4.1.1-wso2v1.jar +httpclient-4.2.5.jar +httpcore-4.1.0-wso2v1.jar +httpcore-4.2.4.jar +javax.cache.wso2-4.2.0.jar +java-xmlbuilder-0.6.jar +javax.servlet-3.0.0.v201112011016.jar +jdbc-pool-7.0.34.wso2v1.jar +jdom-1.0.jar +tomcat-catalina-ha-7.0.34.jar +tomcat-ha-7.0.34.wso2v1.jar +tomcat-jdbc-7.0.34.jar +tomcat-juli-7.0.34.jar +tomcat-tribes-7.0.34.jar +tomcat-util-7.0.34.jar +velocity-1.7.jar +json-2.0.0.wso2v1.jar +libthrift-0.7.wso2v1.jar +libthrift-0.9.1.jar +log4j-1.2.17.jar +neethi-2.0.4.wso2v4.jar +not-yet-commons-ssl-0.3.9.jar +opencsv-1.8.wso2v1.jar +org.apache.log4j-1.2.13.v200706111418.jar +org.apache.stratos.common-4.1.0.jar +org.apache.stratos.load.balancer.common-4.1.0.jar +org.apache.stratos.load.balancer.extension.api-4.1.0.jar +org.apache.stratos.messaging-4.1.0.jar +poi-3.9.jar +poi-ooxml-3.9.0.wso2v1.jar +poi-ooxml-3.9.jar +poi-ooxml-schemas-3.9.jar +poi-scratchpad-3.9.0.wso2v1.jar +poi-scratchpad-3.9.jar +smack-3.0.4.wso2v1.jar +smackx-3.0.4.wso2v1.jar +stax-api-1.0.1.jar +tomcat-annotations-api-7.0.34.jar +tomcat-api-7.0.34.jar +tomcat-catalina-7.0.34.jar + + +=============================================================================== +The following components come under Public Domain License +=============================================================================== + +For base64-2.3.8.jar + +=============================================================================== +The following components come under BouncyCastle License +=============================================================================== + +For bcprov-jdk15-132.jar + +Copyright (c) 2000 - 2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +=============================================================================== +The following components are Licensed under BSD license +=============================================================================== + +For dom4j-1.6.1.jar, +jline-0.9.94.jar, +jsch-0.1.49.jar +jaxen-1.1.1.jar + +Copyright (c) 2010 Terence Parr +All rights reserved. + +[The BSD License] + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of JiBX nor the names of its contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================== +The following components are licensed under EPL +=============================================================================== + +For junit-3.8.1.jar, +org.eclipse.equinox.http.helper-1.1.0.wso2v1.jar, +org.eclipse.osgi-3.8.1.v20120830-144521.jar, +org.eclipse.osgi.services-3.3.100.v20120522-1822.jar + +Eclipse Public License - v 1.0 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and +b) in the case of each subsequent Contributor: +i) changes to the Program, and +ii) additions to the Program; +where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. +"Contributor" means any person or entity that distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. + +"Program" means the Contributions distributed in accordance with this Agreement. + +"Recipient" means anyone who receives the Program under this Agreement, including all Contributors. + +2. GRANT OF RIGHTS + +a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. +b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. +c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. +d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. +3. REQUIREMENTS + +A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of this Agreement; and +b) its license agreement: +i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; +ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; +iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and +iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. +When the Program is made available in source code form: + +a) it must be made available under this Agreement; and +b) a copy of this Agreement must be included with each copy of the Program. +Contributors may not remove or alter any copyright notices contained within the Program. + +Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. + + +=============================================================================== +The following components are licensed under MIT license +=============================================================================== + +For slf4j-1.5.10.wso2v1.jar, +slf4j-api-1.7.5.jar, +slf4j-log4j12-1.7.5.jar + +The MIT License (MIT) + +Copyright (c) 2004-2013 QOS.ch + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + diff --git a/extensions/load-balancer/gce-extension/src/main/notice/NOTICE b/extensions/load-balancer/gce-extension/src/main/notice/NOTICE new file mode 100644 index 0000000000..254608b3e0 --- /dev/null +++ b/extensions/load-balancer/gce-extension/src/main/notice/NOTICE @@ -0,0 +1,395 @@ +Apache Software +Copyright 2015 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +================================================================================ +Apache Abdera Notice: + +Portions of Abdera were orginally developed by +International Business Machines Corporation and are +licensed to the Apache Software Foundation under the +"Software Grant and Corporate Contribution License Agreement", +informally known as the "Abdera CLA". + +This software's test suite contains data files derived from the +Universal Feed Parser, Copyright (c) 2002-2005, Mark Pilgrim. + +This software's extensions module contains a JSON writer for Atom XML +that utilizes a JSON parser, Copyright (c) 2002, json.org. The code was +licensed using Apache License by the author Douglas Crockford and made +available at http://json.org/java/apache.zip We have included portions +of the code in the extensions module. + +=============================================================================== +Apache Ant Notice: + +The task is based on code Copyright (c) 2002, Landmark +Graphics Corp that has been kindly donated to the Apache Software +Foundation. + +================================================================================ +Apache Axiom Notice: + +Portions Copyright 2006 International Business Machines Corp. + +================================================================================ +Apache Axis2 Notice: + +Portions Copyright 2006 International Business Machines Corp. +Portions Copyright 2005-2007 WSO2, Inc. + +This product also includes schemas and specification developed by: +- the W3C consortium (http://www.w3c.org) + +This product also includes WS-* schemas developed by International +Business Machines Corporation, Microsoft Corporation, BEA Systems, +TIBCO Software, SAP AG, Sonic Software, and VeriSign + +This product also includes a WSDL developed by salesforce.com +- Copyright 1999-2006 salesforce.com, inc. + +Portions of the included xmlbeans library were originally based on the following: +- software copyright (c) 2000-2003, BEA Systems, . + +================================================================================ +Apache Commons-Lang Notice: + +This product includes software from the Spring Framework, +under the Apache License 2.0 (see: StringUtils.containsWhitespace()) + +================================================================================ +Apache Commons-Pool Notice: + +The LinkedBlockingDeque implementation is based on an implementation written by +Doug Lea with assistance from members of JCP JSR-166 Expert Group and released +to the public domain, as explained at +http://creativecommons.org/licenses/publicdomain + +================================================================================ +Apache Commons-httpclient Notice: + +This project contains annotations derived from JCIP-ANNOTATIONS +Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net + +=============================================================================== +Apache Tomcat Notice: + +The Windows Installer is built with the Nullsoft +Scriptable Install System (NSIS), which is +open source software. The original software and +related information is available at +http://nsis.sourceforge.net. + +Java compilation software for JSP pages is provided by Eclipse, +which is open source software. The original software and +related information is available at +http://www.eclipse.org. + +For the bayeux implementation +The org.apache.cometd.bayeux API is derivative work originating at the Dojo Foundation +* Copyright 2007-2008 Guy Molinari +* Copyright 2007-2008 Filip Hanik +* Copyright 2007 Dojo Foundation +* Copyright 2007 Mort Bay Consulting Pty. Ltd. + +The original XML Schemas for Java EE Deployment Descriptors: + - javaee_5.xsd + - javaee_web_services_1_2.xsd + - javaee_web_services_client_1_2.xsd + - javaee_6.xsd + - javaee_web_services_1_3.xsd + - javaee_web_services_client_1_3.xsd + - jsp_2_2.xsd + - web-app_3_0.xsd + - web-common_3_0.xsd + - web-fragment_3_0.xsd + - javaee_7.xsd + - javaee_web_services_1_4.xsd + - javaee_web_services_client_1_4.xsd + - jsp_2_3.xsd + - web-app_3_1.xsd + - web-common_3_1.xsd + - web-fragment_3_1.xsd + +may be obtained from: +http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html + +================================================================================ +Apache Geranimo Notice: + +Apache Geronimo +Copyright 2003-2011 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +Portions of the Web Console were orginally developed by International +Business Machines Corporation and are licensed to the Apache Software +Foundation under the "Software Grant and Corporate Contribution +License Agreement", informally known as the "IBM Console CLA". + +Portions of the ASN1 codec implementation in +framework/modules/geronimo-crypto/ were developed by the Bouncy Castle +project (http://www.bouncycastle.org/). + +Copyright (c) 2000-2005 +The Legion Of The Bouncy Castle (http://www.bouncycastle.org) + +ORB Portions of this software were developed at IONA Technologies. + +Object Management Group (OMG) classes used by the orb. +The original classes are available from www.org.omg. + +The RMI over IIOP implementation were developed at Trifork Technologies. + +Copyright 2004-2009 Tranql project committers +This product includes software developed at +Tranql (http://tranql.codehaus.org/). + +This product includes software developed by the Protocol Buffers +project (http://code.google.com/apis/protocolbuffers). + +This product includes also software developed by : + - the W3C consortium (http://www.w3c.org) , + - the SAX project (http://www.saxproject.org) + +The task is based on code Copyright (c) 2002, Landmark +Graphics Corp that has been kindly donated to the Apache Software +Foundation. + +Portions of this software were originally based on the following: + - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. + - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. + - voluntary contributions made by Paul Eng on behalf of the + Apache Software Foundation that were originally developed at iClick, Inc., + software copyright (c) 1999. + + +Portions Copyright 2006 International Business Machines Corp. +Portions Copyright 2005-2007 WSO2, Inc. + +This product also includes schemas and specification developed by: +- the W3C consortium (http://www.w3c.org) + +This product also includes WS-* schemas developed by International +Business Machines Corporation, Microsoft Corporation, BEA Systems, +TIBCO Software, SAP AG, Sonic Software, and VeriSign + +This product also includes a WSDL developed by salesforce.com +- Copyright 1999-2006 salesforce.com, inc. + +Portions of the included xmlbeans library were originally based on the following: +- software copyright (c) 2000-2003, BEA Systems, . + +This product also includes schemas and specification developed by: + - the W3C consortium (http://www.w3c.org) + (http://www.w3.org/XML/1998/namespace) + +This product also includes WS-* schemas developed by International + Business Machines Corporation, Microsoft Corporation, BEA Systems, + TIBCO Software, SAP AG, Sonic Software, and VeriSign + (http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd) + (http://schemas.xmlsoap.org/ws/2004/08/addressing/) + (http://schemas.xmlsoap.org/wsdl/http) + (http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm.xsd) + (http://www.w3.org/2005/08/addressing/ws-addr.xsd) + +Portions of Derby were originally developed by +International Business Machines Corporation and are +licensed to the Apache Software Foundation under the +"Software Grant and Corporate Contribution License Agreement", +informally known as the "Derby CLA". +The following copyright notice(s) were affixed to portions of the code +with which this file is now or was at one time distributed +and are placed here unaltered. + +(C) Copyright 1997,2004 International Business Machines Corporation. All rights reserved. + +(C) Copyright IBM Corp. 2003. + +The portion of the functionTests under 'nist' was originally +developed by the National Institute of Standards and Technology (NIST), +an agency of the United States Department of Commerce, and adapted by +International Business Machines Corporation in accordance with the NIST +Software Acknowledgment and Redistribution document at +http://www.itl.nist.gov/div897/ctg/sql_form.htm + +* OpenJPA includes software written by Miroslav Nachev. + +* OpenJPA uses test code written by Charles Tillman. + +XMLSec was originally based on software copyright (c) 2001, Institute for +Data Communications Systems, . + +The development of XMLSec was partly funded by the European +Commission in the project in the ISIS Programme. + +This product also includes software developed by : + + - IBM Corporation (http://www.ibm.com), + WSDL4J was the initial code contribution for the Apache Woden + project and some of the WSDL4J design and code has been reused. + - The W3C Consortium (http://www.w3c.org), + Common W3C XML Schema and DTD files are packaged with Apache Woden. + +Portions Copyright 2006 International Business Machines Corp. + +Portions of this software were originally based on the following: + - software copyright (c) 2000-2003, BEA Systems, . + +Aside from contributions to the Apache XMLBeans project, this +software also includes: + + - one or more source files from the Apache Xerces-J and Apache Axis + products, Copyright (c) 1999-2003 Apache Software Foundation + + - W3C XML Schema documents Copyright 2001-2003 (c) World Wide Web + Consortium (Massachusetts Institute of Technology, European Research + Consortium for Informatics and Mathematics, Keio University) + + - resolver.jar from Apache Xml Commons project, + Copyright (c) 2001-2003 Apache Software Foundation + + - Piccolo XML Parser for Java from http://piccolo.sourceforge.net/, + Copyright 2002 Yuval Oren under the terms of the Apache Software License 2.0 + + - JSR-173 Streaming API for XML from http://sourceforge.net/projects/xmlpullparser/, + Copyright 2005 BEA under the terms of the Apache Software License 2.0 + +This product includes software developed by the Simple XML Compiler (SXC) +project (http://sxc.codehaus.org/project-info.html) + +This product includes software developed for the JAXB Reference +Implementation project. (https://jaxb.dev.java.net/). Apache Geronimo elects +to include this software in this distribution under the CDDL license. + +This product includes software developed for SOAP with Attachments +API for Java (SAAJ). The software is available from the GlassFish project +(https://saaj.dev.java.net/). Apache Geronimo elects to include this +software in this distribution under the CDDL license. + +This product includes software developed for Java API for XML Web Services +project (JAX-WS) (https://jax-ws.dev.java.net/). Apache Geronimo elects +to include this software in this distribution under the CDDL license. + +This product includes software developed for the Java Server Pages Tag +Library project (https://jstl.dev.java.net/). Apache Geronimo elects +to include this software in this distribution under the CDDL license. + +This product includes schema files developed for the Glassfish Java EE +reference implementation (http://java.sun.com/xml/ns/j2ee/). +Apache Geronimo elects to include this software in this distribution +under the CDDL license. You can obtain a copy of the License at: + https://glassfish.dev.java.net/public/CDDL+GPL.html +The source code is available at: + https://glassfish.dev.java.net/source/browse/glassfish/ + +The following schemas are included: + +---------------------------------- + application-client_1_4.xsd + application_1_4.xsd + connector_1_5.xsd + datatypes.dtd + ejb-jar_2_1.xsd + j2ee_1_4.xsd + j2ee_jaxrpc_mapping_1_1.xsd + j2ee_web_services_1_1.xsd + j2ee_web_services_client_1_1.xsd + jsp_2_0.xsd + web-app_2_4.xsd + web-jsptaglibrary_2_0.xsd + application-client_5.xsd + application_5.xsd + ejb-jar_3_0.xsd + handler-chain.xsd + javaee_5.xsd + javaee_web_services_1_2.xsd + javaee_web_services_client_1_2.xsd + jsp_2_1.xsd + persistence_1_0.xsd + web-app_2_5.xsd + web-facelettaglibrary_2_0.xsd + web-facesconfig_2_0.xsd + web-partialresponse_2_0.xsd + web-jsptaglibrary_2_1.xsd + application_6.xsd + application-client_6.xsd + connector_1_6.xsd + ejb-jar_3_1.xsd + javaee_6.xsd + javaee_web_services_1_3.xsd + javaee_web_services_client_1_3.xsd + jsp_2_2.xsd + persistence_2_0.xsd + web-app_3_0.xsd + web-common_3_0.xsd + web-fragment_3_0.xsd +-------------------------------- + +This product includes software developed at +the OSGi Alliance (http://www.osgi.org/). + + This product includes software developed at + OPS4J (http://www.ops4j.org/). +------------------------------------------------------------------------------- + +The product contains the software developed in javassist.org (http://www.javassist.org) +which is released under both the Mozilla Public License +(http://www.mozilla.org/MPL/MPL-1.1.html) and the GNU Lesser General Public +License (http://www.gnu.org/licenses/lgpl-2.1.html). + +The Apache Geronimo project elects to distribute this software under the terms of +the Mozilla Public License. + +------------------------------------------------------------------------------- + +The product contains the software developed in json.org which released under the following license. + +http://www.json.org/license.html + +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +================================================================================ +Apache Httpclient Notice: + +This project contains annotations derived from JCIP-ANNOTATIONS +Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net + +================================================================================ +Apache Httpcore Notice: + +This project contains annotations derived from JCIP-ANNOTATIONS +Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net + +=============================================================================== +Apache POI Notice: + +This product contains the DOM4J library (http://www.dom4j.org). +Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved. + +This product contains parts that were originally based on software from BEA. +Copyright (c) 2000-2003, BEA Systems, . + +This product contains W3C XML Schema documents. Copyright 2001-2003 (c) +World Wide Web Consortium (Massachusetts Institute of Technology, European +Research Consortium for Informatics and Mathematics, Keio University) + +This product contains the Piccolo XML Parser for Java +(http://piccolo.sourceforge.net/). Copyright 2002 Yuval Oren. + +This product contains the chunks_parse_cmds.tbl file from the vsdump program. +Copyright (C) 2006-2007 Valek Filippov (frob@df.ru) + + + diff --git a/extensions/load-balancer/gce-extension/src/main/security/client-truststore.jks b/extensions/load-balancer/gce-extension/src/main/security/client-truststore.jks new file mode 100644 index 0000000000..be441f378e Binary files /dev/null and b/extensions/load-balancer/gce-extension/src/main/security/client-truststore.jks differ diff --git a/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml b/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml index 5bfa02edc6..9975d757df 100644 --- a/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml +++ b/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml @@ -78,7 +78,7 @@ INSTALL* - + ${project.basedir}/src/main/license / 0600 @@ -92,7 +92,7 @@ /lib - + *:icu4j* *:jaxen* *:jboss-transaction-api* diff --git a/extensions/load-balancer/pom.xml b/extensions/load-balancer/pom.xml index cb4bf56cce..291f4929f7 100644 --- a/extensions/load-balancer/pom.xml +++ b/extensions/load-balancer/pom.xml @@ -36,6 +36,7 @@ haproxy-extension nginx-extension + gce-extension lvs-extension