You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2013/11/17 06:08:01 UTC
git commit: Implemented haproxy statistics reporting feature
Updated Branches:
refs/heads/master 1dba19acc -> 5d8ab42f9
Implemented haproxy statistics reporting feature
Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/5d8ab42f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/5d8ab42f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/5d8ab42f
Branch: refs/heads/master
Commit: 5d8ab42f9034d69421a552510b4b730cd3f28972
Parents: 1dba19a
Author: Imesh Gunaratne <im...@apache.org>
Authored: Sun Nov 17 10:37:41 2013 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sun Nov 17 10:37:41 2013 +0530
----------------------------------------------------------------------
.../load-balancer/haproxy-extension/INSTALL.txt | 23 ++++
.../load-balancer/haproxy-extension/README.txt | 26 +++++
.../haproxy-extension/src/main/assembly/bin.xml | 10 +-
.../src/main/bin/haproxy-extension.sh | 21 ++--
.../stratos/haproxy/extension/CommandUtil.java | 66 ++++++++++++
.../stratos/haproxy/extension/HAProxy.java | 62 ++++-------
.../haproxy/extension/HAProxyConfigWriter.java | 55 +++++-----
.../haproxy/extension/HAProxyContext.java | 104 +++++++++++++++++++
.../haproxy/extension/HAProxyStatsReader.java | 63 +++++++++++
.../apache/stratos/haproxy/extension/Main.java | 35 ++-----
.../src/main/resources/log4j.properties | 37 -------
.../src/main/scripts/get-weight.sh | 23 ++++
.../src/main/templates/haproxy.cfg.template | 2 +-
13 files changed, 380 insertions(+), 147 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/INSTALL.txt
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/INSTALL.txt b/extensions/load-balancer/haproxy-extension/INSTALL.txt
new file mode 100644
index 0000000..ef9e3dc
--- /dev/null
+++ b/extensions/load-balancer/haproxy-extension/INSTALL.txt
@@ -0,0 +1,23 @@
+================================================================================
+ Installing Apache Stratos HAProxy Extension 4.0.0-SNAPSHOT
+================================================================================
+
+
+Apache Stratos HAProxy Extension could be run in an unix environment. Please follow the
+below steps to proceed with the installation:
+
+1. Download and extract HAProxy binary distribution to a desired location: <HAPROXY-HOME>.
+
+2. Extract apache-stratos-haproxy-extension-4.0.0-SNAPSHOT-bin.zip to a desired location: <HAPROXY-EXTENSION-HOME>.
+
+3. Open <HAPROXY-EXTENSION-HOME>/bin/haproxy-extension.sh in a text editor and update following system properties:
+
+ -Dexecutable.file.path=<HAPROXY-HOME>/haproxy # HAProxy executable file path
+ -Dconf.file.path=/tmp/haproxy.cfg # HAProxy configuration file path
+ -Dstats.socket.file.path=/tmp/haproxy-stats.socket # HAProxy statistics socket file path
+ -Dthrift.receiver.ip=localhost # CEP IP Address
+ -Dthrift.receiver.port=7615 # CEP Port
+
+
+Thank you for using Apache Stratos!
+Apache Stratos Team
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/README.txt
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/README.txt b/extensions/load-balancer/haproxy-extension/README.txt
new file mode 100644
index 0000000..6131bff
--- /dev/null
+++ b/extensions/load-balancer/haproxy-extension/README.txt
@@ -0,0 +1,26 @@
+================================================================================
+ Apache Stratos HAProxy Extension 4.0.0-SNAPSHOT
+================================================================================
+
+
+Apache Stratos (incubating) HAProxy extension is a load balancer extension for HAProxy.
+It is an executable program which could manage the life-cycle of a HAProxy instance
+according to topology updates received from Stratos Cloud Controller via the message broker.
+
+Work Flow:
+1. Wait for the complete topology event message to initialize the topology.
+2. Configure and start an instance of HAProxy.
+3. Listen to topology update messages.
+4. Reload HAProxy instance with the new topology configuration.
+5. Periodically publish statistics to Complex Event Processor (CEP).
+
+Please refer INSTALL.txt for information on the installation process.
+
+
+Thanks to Vaadin for HAProxyController implementation:
+https://vaadin.com/license
+http://dev.vaadin.com/browser/svn/incubator/Arvue/ArvueMaster/src/org/vaadin/arvue/arvuemaster/HAProxyController.java
+
+
+Thank you for using Apache Stratos!
+Apache Stratos Team
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml
----------------------------------------------------------------------
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 c21b4b0..34c1db8 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml
+++ b/extensions/load-balancer/haproxy-extension/src/main/assembly/bin.xml
@@ -59,13 +59,21 @@
</includes>
</fileSet>
<fileSet>
+ <directory>${project.basedir}/src/main/scripts</directory>
+ <outputDirectory>/scripts</outputDirectory>
+ <fileMode>0755</fileMode>
+ <includes>
+ <include>get-weight.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<fileMode>0600</fileMode>
<includes>
<include>README*</include>
<include>LICENSE*</include>
- <include>NOTICE*</include>
+ <include>INSTALL*</include>
</includes>
</fileSet>
</fileSets>
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/bin/haproxy-extension.sh
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/bin/haproxy-extension.sh b/extensions/load-balancer/haproxy-extension/src/main/bin/haproxy-extension.sh
index be1f91e..bc19205 100755
--- a/extensions/load-balancer/haproxy-extension/src/main/bin/haproxy-extension.sh
+++ b/extensions/load-balancer/haproxy-extension/src/main/bin/haproxy-extension.sh
@@ -21,20 +21,23 @@
# --------------------------------------------------------------
echo "Starting haproxy extension..."
-lib_path=./../lib/
-class_path=`echo ../lib/*.jar | tr ' ' ':'`
-properties="-Djndi.properties.dir=./../conf
- -Dexecutable.file.path=/Users/imesh/dist/haproxy/haproxy-1.4.24/haproxy
- -Dtemplates.path=./../templates
+script_path=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)`"`
+lib_path=${script_path}/../lib/
+class_path=`echo ${lib_path}/*.jar | tr ' ' ':'`
+properties="-Djndi.properties.dir=${script_path}/../conf
+ -Dexecutable.file.path=haproxy
+ -Dtemplates.path=${script_path}/../templates
-Dtemplates.name=haproxy.cfg.template
+ -Dscripts.path=${script_path}/../scripts
-Dconf.file.path=/tmp/haproxy.cfg
- -Dlog4j.properties.file.path=./../conf/log4j.properties
- -Djavax.net.ssl.trustStore=./../security/client-truststore.jks
+ -Dstats.socket.file.path=/tmp/haproxy-stats.socket
+ -Dlog4j.properties.file.path=${script_path}/../conf/log4j.properties
+ -Djavax.net.ssl.trustStore=${script_path}/../security/client-truststore.jks
-Djavax.net.ssl.trustStorePassword=wso2carbon
-Dthrift.receiver.ip=localhost
-Dthrift.receiver.port=7615"
-# Uncomment below line and add $debug next to $properties to enable remote debugging
+# Uncomment below line to enable remote debugging
#debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
-java -cp "$class_path" $properties org.apache.stratos.haproxy.extension.Main -Dp1=sample_value $*
+java -cp "${class_path}" ${properties} ${debug} org.apache.stratos.haproxy.extension.Main -Dp1=sample_value $*
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/CommandUtil.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/CommandUtil.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/CommandUtil.java
new file mode 100644
index 0000000..7adea28
--- /dev/null
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/CommandUtil.java
@@ -0,0 +1,66 @@
+/*
+ * 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.haproxy.extension;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * A utility class for executing shell commands.
+ */
+public class CommandUtil {
+ private static final Log log = LogFactory.getLog(CommandUtil.class);
+ private static final String NEW_LINE = System.getProperty("line.separator");
+
+ public static String executeCommand(String command) throws IOException {
+ String line;
+ Runtime r = Runtime.getRuntime();
+ if (log.isDebugEnabled()) {
+ log.debug("command = " + command);
+ }
+ Process p = r.exec(command);
+
+ StringBuilder output = new StringBuilder();
+ BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ while ((line = in.readLine()) != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("output = " + line);
+ }
+ output.append(line + NEW_LINE);
+ }
+ StringBuilder errors = new StringBuilder();
+ BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
+ while ((line = error.readLine()) != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("error = " + line);
+ }
+ errors.append(line + NEW_LINE);
+ }
+ if (errors.length() > 0) {
+ throw new RuntimeException("Command execution failed: " + NEW_LINE + errors.toString());
+ }
+
+ return output.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxy.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxy.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxy.java
index dac52af..aca4ac9 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxy.java
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxy.java
@@ -19,21 +19,19 @@
package org.apache.stratos.haproxy.extension;
-import java.io.*;
-import java.util.Vector;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.load.balancer.extension.api.LoadBalancer;
import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException;
import org.apache.stratos.messaging.domain.topology.Topology;
-import org.apache.stratos.load.balancer.extension.api.LoadBalancer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.Vector;
/**
* HAProxy load balancer life-cycle implementation.
- * <p/>
- * Thanks to Vaadin for HAProxyController implementation:
- * https://vaadin.com/license
- * http://dev.vaadin.com/browser/svn/incubator/Arvue/ArvueMaster/src/org/vaadin/arvue/arvuemaster/HAProxyController.java
*/
public class HAProxy implements LoadBalancer {
private static final Log log = LogFactory.getLog(HAProxy.class);
@@ -44,39 +42,15 @@ public class HAProxy implements LoadBalancer {
private String templatePath;
private String templateName;
private String confFilePath;
+ private String statsSocketFilePath;
- public HAProxy(String executableFilePath, String templatePath, String templateName, String confFilePath) {
- this.executableFilePath = executableFilePath;
- this.templatePath = templatePath;
- this.templateName = templateName;
- this.confFilePath = confFilePath;
+ public HAProxy() {
+ this.executableFilePath = HAProxyContext.getInstance().getExecutableFilePath();
+ this.templatePath = HAProxyContext.getInstance().getTemplatePath();
+ this.templateName = HAProxyContext.getInstance().getTemplateName();
+ this.confFilePath = HAProxyContext.getInstance().getConfFilePath();
this.processIdFilePath = confFilePath.replace(".cfg", ".pid");
- }
-
- private void executeCommand(String command) throws IOException {
- String line;
- Runtime r = Runtime.getRuntime();
- if (log.isDebugEnabled()) {
- log.debug("command = " + command);
- }
- Process p = r.exec(command);
- BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
- while ((line = in.readLine()) != null) {
- if (log.isInfoEnabled()) {
- log.info(line);
- }
- }
- StringBuilder sb = new StringBuilder();
- BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
- while ((line = error.readLine()) != null) {
- if (log.isInfoEnabled()) {
- log.info(line);
- sb.append(line + NEW_LINE);
- }
- }
- if (sb.length() > 0) {
- throw new RuntimeException("Command execution failed: " + NEW_LINE + sb.toString());
- }
+ this.statsSocketFilePath = HAProxyContext.getInstance().getStatsSocketFilePath();
}
private void reloadConfiguration() throws LoadBalancerExtensionException {
@@ -96,7 +70,7 @@ public class HAProxy implements LoadBalancer {
// Execute hot configuration deployment
String command = executableFilePath + " -f " + confFilePath + " -p " + processIdFilePath + " -sf " + pid;
- executeCommand(command);
+ CommandUtil.executeCommand(command);
if (log.isInfoEnabled()) {
log.info("Configuration done");
}
@@ -120,7 +94,7 @@ public class HAProxy implements LoadBalancer {
log.info("Configuring haproxy instance...");
}
- HAProxyConfigWriter writer = new HAProxyConfigWriter(templatePath, templateName, confFilePath);
+ HAProxyConfigWriter writer = new HAProxyConfigWriter(templatePath, templateName, confFilePath, statsSocketFilePath);
writer.write(topology);
if (log.isInfoEnabled()) {
@@ -145,7 +119,7 @@ public class HAProxy implements LoadBalancer {
// Start haproxy and write pid to processIdFilePath
try {
String command = executableFilePath + " -f " + confFilePath + " -p " + processIdFilePath;
- executeCommand(command);
+ CommandUtil.executeCommand(command);
if (log.isInfoEnabled()) {
log.info("haproxy started");
}
@@ -171,13 +145,13 @@ public class HAProxy implements LoadBalancer {
// Kill all haproxy processes
for (String pid : pids) {
String command = "kill -s 9 " + pid;
- executeCommand(command);
+ CommandUtil.executeCommand(command);
if (log.isInfoEnabled()) {
log.info(String.format("haproxy stopped [pid] %s", pid));
}
}
} catch (Exception e) {
- if(log.isErrorEnabled()) {
+ if (log.isErrorEnabled()) {
log.error("Could not stop haproxy");
}
throw new LoadBalancerExtensionException(e);
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyConfigWriter.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyConfigWriter.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyConfigWriter.java
index 5e6f69a..d282a76 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyConfigWriter.java
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyConfigWriter.java
@@ -21,7 +21,6 @@ package org.apache.stratos.haproxy.extension;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException;
import org.apache.stratos.messaging.domain.topology.*;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
@@ -35,11 +34,6 @@ import java.io.StringWriter;
/**
* HAProxy load balancer configuration writer.
- *
- * Thanks to Vaadin for HAProxyController implementation:
- * https://vaadin.com/license
- * http://dev.vaadin.com/browser/svn/incubator/Arvue/ArvueMaster/src/org/vaadin/arvue/arvuemaster/HAProxyController.java
-
*/
public class HAProxyConfigWriter {
private static final Log log = LogFactory.getLog(Main.class);
@@ -48,39 +42,45 @@ public class HAProxyConfigWriter {
private String templatePath;
private String templateName;
private String confFilePath;
+ private String statsSocketFilePath;
- public HAProxyConfigWriter(String templatePath, String templateName, String confFilePath) {
+ public HAProxyConfigWriter(String templatePath, String templateName, String confFilePath, String statsSocketFilePath) {
this.templatePath = templatePath;
this.templateName = templateName;
this.confFilePath = confFilePath;
+ this.statsSocketFilePath = statsSocketFilePath;
}
public void write(Topology topology) {
-
- StringBuilder sb = new StringBuilder();
-
- for(Service service : topology.getServices()) {
- for(Cluster cluster : service.getClusters()) {
- if((service.getPorts() == null) || (service.getPorts().size() == 0)) {
+ // Prepare global parameters
+ StringBuilder globalParameters = new StringBuilder();
+ globalParameters.append("stats socket ");
+ globalParameters.append(statsSocketFilePath);
+
+ // Prepare frontend-backend collection
+ StringBuilder frontendBackendCollection = new StringBuilder();
+ for (Service service : topology.getServices()) {
+ for (Cluster cluster : service.getClusters()) {
+ if ((service.getPorts() == null) || (service.getPorts().size() == 0)) {
throw new RuntimeException(String.format("No ports found in service: %s", service.getServiceName()));
}
- for(Port port : service.getPorts()) {
+ for (Port port : service.getPorts()) {
- String frontEndId = cluster.getClusterId() + "-proxy-" + port.getProxy();
- String backEndId = frontEndId + "-members";
+ String frontendId = cluster.getClusterId() + "-proxy-" + port.getProxy();
+ String backendId = frontendId + "-members";
- sb.append("frontend ").append(frontEndId).append(NEW_LINE);
- sb.append("\tbind ").append(cluster.getHostName()).append(":").append(port.getProxy()).append(NEW_LINE);
- sb.append("\tdefault_backend ").append(backEndId).append(NEW_LINE);
- sb.append(NEW_LINE);
- sb.append("backend ").append(backEndId).append(NEW_LINE);
+ frontendBackendCollection.append("frontend ").append(frontendId).append(NEW_LINE);
+ frontendBackendCollection.append("\tbind ").append(cluster.getHostName()).append(":").append(port.getProxy()).append(NEW_LINE);
+ frontendBackendCollection.append("\tdefault_backend ").append(backendId).append(NEW_LINE);
+ frontendBackendCollection.append(NEW_LINE);
+ frontendBackendCollection.append("backend ").append(backendId).append(NEW_LINE);
for (Member member : cluster.getMembers()) {
- sb.append("\tserver ").append(member.getMemberId()).append(" ")
- .append(member.getMemberIp()).append(":").append(port.getValue()).append(NEW_LINE);
+ frontendBackendCollection.append("\tserver ").append(member.getMemberId()).append(" ")
+ .append(member.getMemberIp()).append(":").append(port.getValue()).append(NEW_LINE);
}
- sb.append(NEW_LINE);
+ frontendBackendCollection.append(NEW_LINE);
}
}
}
@@ -95,7 +95,8 @@ public class HAProxyConfigWriter {
// Insert strings into the template
VelocityContext context = new VelocityContext();
- context.put("frontend_backend_collection", sb.toString());
+ context.put("global_parameters", globalParameters.toString());
+ context.put("frontend_backend_collection", frontendBackendCollection.toString());
// Create a new string from the template
StringWriter stringWriter = new StringWriter();
@@ -108,11 +109,11 @@ public class HAProxyConfigWriter {
writer.write(configuration);
writer.close();
- if(log.isInfoEnabled()) {
+ if (log.isInfoEnabled()) {
log.info(String.format("Configuration written to file: %s", confFilePath));
}
} catch (IOException e) {
- if(log.isErrorEnabled()) {
+ if (log.isErrorEnabled()) {
log.error(String.format("Could not write configuration file: %s", confFilePath));
}
throw new RuntimeException(e);
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyContext.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyContext.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyContext.java
new file mode 100644
index 0000000..c1c34a8
--- /dev/null
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyContext.java
@@ -0,0 +1,104 @@
+/*
+ * 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.haproxy.extension;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * HAProxy context to read and store system properties.
+ */
+public class HAProxyContext {
+ private static final Log log = LogFactory.getLog(HAProxyContext.class);
+ private static volatile HAProxyContext context;
+
+ private String executableFilePath;
+ private String processIdFilePath;
+ private String templatePath;
+ private String templateName;
+ private String scriptsPath;
+ private String confFilePath;
+ private String statsSocketFilePath;
+
+ private HAProxyContext() {
+ this.executableFilePath = System.getProperty("executable.file.path");
+ this.templatePath = System.getProperty("templates.path");
+ this.templateName = System.getProperty("templates.name");
+ this.scriptsPath = System.getProperty("scripts.path");
+ this.confFilePath = System.getProperty("conf.file.path");
+ this.statsSocketFilePath = System.getProperty("stats.socket.file.path");
+
+ if (log.isDebugEnabled()) {
+ log.debug("executable.file.path = " + executableFilePath);
+ log.debug("templates.path = " + templatePath);
+ log.debug("templates.name = " + templateName);
+ log.debug("scripts.path = " + scriptsPath);
+ log.debug("conf.file.path = " + confFilePath);
+ log.debug("stats.socket.file.path = " + statsSocketFilePath);
+ }
+ }
+
+ public static HAProxyContext getInstance() {
+ if (context == null) {
+ synchronized (HAProxyContext.class) {
+ if (context == null) {
+ context = new HAProxyContext();
+ }
+ }
+ }
+ return context;
+ }
+
+ public void validate() {
+ if ((StringUtils.isEmpty(executableFilePath)) || (StringUtils.isEmpty(templatePath)) || (StringUtils.isEmpty(templateName)) ||
+ (StringUtils.isEmpty(scriptsPath)) || (StringUtils.isEmpty(confFilePath)) || (StringUtils.isEmpty(statsSocketFilePath))) {
+ throw new RuntimeException("Required system properties were not found: executable.file.path, templates.path, templates.name, scripts.path, conf.file.path, stats.socket.file.path");
+ }
+ }
+
+ public String getExecutableFilePath() {
+ return executableFilePath;
+ }
+
+ public String getProcessIdFilePath() {
+ return processIdFilePath;
+ }
+
+ public String getTemplatePath() {
+ return templatePath;
+ }
+
+ public String getTemplateName() {
+ return templateName;
+ }
+
+ public String getScriptsPath() {
+ return scriptsPath;
+ }
+
+ public String getConfFilePath() {
+ return confFilePath;
+ }
+
+ public String getStatsSocketFilePath() {
+ return statsSocketFilePath;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyStatsReader.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyStatsReader.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyStatsReader.java
index d76cc0b..57c6bc0 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyStatsReader.java
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/HAProxyStatsReader.java
@@ -19,15 +19,78 @@
package org.apache.stratos.haproxy.extension;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.stratos.load.balancer.extension.api.LoadBalancerStatsReader;
+import org.apache.stratos.messaging.domain.topology.Cluster;
+import org.apache.stratos.messaging.domain.topology.Member;
+import org.apache.stratos.messaging.domain.topology.Port;
+import org.apache.stratos.messaging.domain.topology.Service;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
+
+import java.io.IOException;
/**
* HAProxy statistics reader.
*/
public class HAProxyStatsReader implements LoadBalancerStatsReader {
+ private static final Log log = LogFactory.getLog(HAProxyStatsReader.class);
+
+ private String scriptsPath;
+ private String statsSocketFilePath;
+
+ public HAProxyStatsReader() {
+ this.scriptsPath = HAProxyContext.getInstance().getScriptsPath();
+ this.statsSocketFilePath = HAProxyContext.getInstance().getStatsSocketFilePath();
+ }
@Override
public int getInFlightRequestCount(String clusterId) {
+ String frontendId, backendId, command, output;
+ String[] array;
+ int totalWeight, weight;
+
+ for (Service service : TopologyManager.getTopology().getServices()) {
+ for (Cluster cluster : service.getClusters()) {
+ if (cluster.getClusterId().equals(clusterId)) {
+ totalWeight = 0;
+ if ((service.getPorts() == null) || (service.getPorts().size() == 0)) {
+ throw new RuntimeException(String.format("No ports found in service: %s", service.getServiceName()));
+ }
+
+ for (Port port : service.getPorts()) {
+ frontendId = cluster.getClusterId() + "-proxy-" + port.getProxy();
+ backendId = frontendId + "-members";
+
+ for (Member member : cluster.getMembers()) {
+ // echo "get weight <backend>/<server>" | socat stdio <stats-socket>
+ command = String.format("%s/get-weight.sh %s %s %s", scriptsPath, backendId, member.getMemberId(), statsSocketFilePath);
+ try {
+ output = CommandUtil.executeCommand(command);
+ if ((output != null) && (output.length() > 0)) {
+ array = output.split(" ");
+ if ((array != null) && (array.length > 0)) {
+ weight = Integer.parseInt(array[0]);
+ if (log.isDebugEnabled()) {
+ log.debug(String.format("Member weight found: [cluster] %s [member] %s [weight] %d", member.getClusterId(), member.getMemberId(), weight));
+ }
+ totalWeight += weight;
+ }
+ }
+ } catch (IOException e) {
+ if (log.isErrorEnabled()) {
+ log.error(e);
+ }
+ }
+ }
+ }
+ if (log.isInfoEnabled()) {
+ log.info(String.format("Cluster weight found: [cluster] %s [weight] %d", cluster.getClusterId(), totalWeight));
+ }
+ return totalWeight;
+ }
+ }
+ }
return 0;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/Main.java
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/Main.java b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/Main.java
index fea9c2a..2cf1044 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/Main.java
+++ b/extensions/load-balancer/haproxy-extension/src/main/java/org/apache/stratos/haproxy/extension/Main.java
@@ -19,7 +19,6 @@
package org.apache.stratos.haproxy.extension;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.PropertyConfigurator;
@@ -38,40 +37,20 @@ public class Main {
// Configure log4j properties
PropertyConfigurator.configure(System.getProperty("log4j.properties.file.path"));
- if(log.isInfoEnabled()) {
+ if (log.isInfoEnabled()) {
log.info("HAProxy extension started");
}
- String executableFilePath = System.getProperty("executable.file.path");
- String templatePath = System.getProperty("templates.path");
- String templateName = System.getProperty("templates.name");
- String confFilePath = System.getProperty("conf.file.path");
-
- if(log.isDebugEnabled()) {
- log.debug("executable.file.path = " + executableFilePath);
- log.debug("templates.path = " + templatePath);
- log.debug("templates.name = " + templateName);
- log.debug("conf.file.path = " + confFilePath);
- }
-
- if((StringUtils.isEmpty(executableFilePath)) || (StringUtils.isEmpty(templatePath)) || (StringUtils.isEmpty(templateName)) || (StringUtils.isEmpty(confFilePath))) {
- if(log.isErrorEnabled()) {
- log.error("System properties are not valid. Expected: executable.file.path, templates.path, templates.name, conf.file.path");
- }
- return;
- }
-
- HAProxy haProxy = new HAProxy(executableFilePath, templatePath, templateName, confFilePath);
- HAProxyStatsReader statsReader = new HAProxyStatsReader();
- extension = new LoadBalancerExtension(haProxy, statsReader);
+ // Validate rumtime parameters
+ HAProxyContext.getInstance().validate();
+ extension = new LoadBalancerExtension(new HAProxy(), new HAProxyStatsReader());
Thread thread = new Thread(extension);
thread.start();
- }
- catch (Exception e) {
- if(log.isErrorEnabled()) {
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
log.error(e);
}
- if(extension != null) {
+ if (extension != null) {
extension.terminate();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/resources/log4j.properties b/extensions/load-balancer/haproxy-extension/src/main/resources/log4j.properties
deleted file mode 100644
index 7d8a934..0000000
--- a/extensions/load-balancer/haproxy-extension/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-# 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=log/haproxy-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.haproxy.extension=TRACE
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/scripts/get-weight.sh
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/scripts/get-weight.sh b/extensions/load-balancer/haproxy-extension/src/main/scripts/get-weight.sh
new file mode 100644
index 0000000..cef3a1f
--- /dev/null
+++ b/extensions/load-balancer/haproxy-extension/src/main/scripts/get-weight.sh
@@ -0,0 +1,23 @@
+#!/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 "get weight $1/$2" | socat stdio $3
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/5d8ab42f/extensions/load-balancer/haproxy-extension/src/main/templates/haproxy.cfg.template
----------------------------------------------------------------------
diff --git a/extensions/load-balancer/haproxy-extension/src/main/templates/haproxy.cfg.template b/extensions/load-balancer/haproxy-extension/src/main/templates/haproxy.cfg.template
index 240f64a..c58ce87 100644
--- a/extensions/load-balancer/haproxy-extension/src/main/templates/haproxy.cfg.template
+++ b/extensions/load-balancer/haproxy-extension/src/main/templates/haproxy.cfg.template
@@ -1,7 +1,7 @@
global
daemon
maxconn 256
- stats socket /tmp/haproxy_stats
+ $global_parameters
defaults
mode http