JBoss Native SVN: r1635 - in sandbox/aloha: java/org/jboss/aloha and 1 other directory.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-29 03:40:36 -0400 (Thu, 29 May 2008)
New Revision: 1635
Added:
sandbox/aloha/examples/org/jboss/aloha/MessageExample.java
Modified:
sandbox/aloha/java/org/jboss/aloha/HttpConnection.java
Log:
Add Message Example. Can be run by ant run -Dexample=MessageExample
Added: sandbox/aloha/examples/org/jboss/aloha/MessageExample.java
===================================================================
--- sandbox/aloha/examples/org/jboss/aloha/MessageExample.java (rev 0)
+++ sandbox/aloha/examples/org/jboss/aloha/MessageExample.java 2008-05-29 07:40:36 UTC (rev 1635)
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+public class MessageExample
+{
+
+ public MessageExample()
+ {
+ }
+
+ public static void main(String [] args) {
+ try {
+
+ ConnectionFactory cf = new ConnectionFactory(HttpConnection.class);
+ Connection c;
+
+ cf.setPort(8000);
+ c = cf.getConnection();
+ Message m = new Message(Command.Info, "*/*;*");
+ c.sendMessage(m);
+ System.out.println("**** Response " + c.getResponseCode());
+ System.out.println("**** Message >>");
+ System.out.println(c.getResponse());
+ System.out.println("**** << Message");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
Property changes on: sandbox/aloha/examples/org/jboss/aloha/MessageExample.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: sandbox/aloha/java/org/jboss/aloha/HttpConnection.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/HttpConnection.java 2008-05-29 06:51:33 UTC (rev 1634)
+++ sandbox/aloha/java/org/jboss/aloha/HttpConnection.java 2008-05-29 07:40:36 UTC (rev 1635)
@@ -185,9 +185,9 @@
sb.append(':');
sb.append(getPort());
}
+ sb.append(getManagerUrl());
sb.append('/');
sb.append(path);
- sb.append(getManagerUrl());
return sb.toString();
}
16 years, 7 months
JBoss Native SVN: r1634 - sandbox/aloha/test/org/jboss/aloha.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-29 02:51:33 -0400 (Thu, 29 May 2008)
New Revision: 1634
Added:
sandbox/aloha/test/org/jboss/aloha/TestMessage.java
Modified:
sandbox/aloha/test/org/jboss/aloha/TestAll.java
Log:
Add TestMessage
Modified: sandbox/aloha/test/org/jboss/aloha/TestAll.java
===================================================================
--- sandbox/aloha/test/org/jboss/aloha/TestAll.java 2008-05-29 06:50:34 UTC (rev 1633)
+++ sandbox/aloha/test/org/jboss/aloha/TestAll.java 2008-05-29 06:51:33 UTC (rev 1634)
@@ -42,6 +42,7 @@
// Fundamentals
suite.addTest(TestParameter.suite());
suite.addTest(TestResponseBodyParser.suite());
+ suite.addTest(TestMessage.suite());
return suite;
}
Added: sandbox/aloha/test/org/jboss/aloha/TestMessage.java
===================================================================
--- sandbox/aloha/test/org/jboss/aloha/TestMessage.java (rev 0)
+++ sandbox/aloha/test/org/jboss/aloha/TestMessage.java 2008-05-29 06:51:33 UTC (rev 1634)
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import junit.framework.*;
+
+/**
+ * Message Test.
+ *
+ */
+public class TestMessage extends TestCase
+{
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(TestMessage.class);
+ return suite;
+ }
+
+ public void testInit()
+ throws Exception
+ {
+ ConnectionFactory f;
+ Connection c;
+ f = new ConnectionFactory(HttpConnection.class);
+ c = f.getConnection();
+ assertEquals("Class ", c.getClass(), HttpConnection.class);
+ }
+
+
+}
Property changes on: sandbox/aloha/test/org/jboss/aloha/TestMessage.java
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months
JBoss Native SVN: r1633 - sandbox/aloha/java/org/jboss/aloha.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-29 02:50:34 -0400 (Thu, 29 May 2008)
New Revision: 1633
Added:
sandbox/aloha/java/org/jboss/aloha/Connection.java
sandbox/aloha/java/org/jboss/aloha/ConnectionFactory.java
sandbox/aloha/java/org/jboss/aloha/HttpConnection.java
Removed:
sandbox/aloha/java/org/jboss/aloha/HttpMessage.java
sandbox/aloha/java/org/jboss/aloha/MessageFactory.java
Modified:
sandbox/aloha/java/org/jboss/aloha/GenericResource.java
sandbox/aloha/java/org/jboss/aloha/Message.java
sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java
Log:
Rename some classes
Added: sandbox/aloha/java/org/jboss/aloha/Connection.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Connection.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Connection.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.jboss.aloha.util.*;
+
+/**
+ * Represents the Connection to remote Web Server instance
+ * using MCMP protocol
+ *
+ * @author Mladen Turk
+ *
+ */
+public abstract class Connection
+{
+
+ private MessageProtocol protocol;
+
+ private String host;
+ private int port;
+ private String url;
+ protected int connectTimeout;
+ protected int readTimeout;
+ protected String authorization;
+
+ /**
+ * Creates an empty connection to ManagedServer
+ */
+ protected Connection()
+ {
+ }
+
+ public abstract void connect();
+ public abstract void disconnect();
+ public abstract int getResponseCode();
+ public abstract void sendMessage(Message message);
+ public abstract String getResponse();
+
+
+ public void setProtocol(String v)
+ throws IllegalArgumentException
+ {
+ protocol = MessageProtocol.valueOfIgnoreCase(v);
+ }
+
+ public void setProtocol(MessageProtocol v) { protocol = v;}
+
+ public MessageProtocol getProtocol() { return protocol; }
+
+
+ public void setHost(String v) { host = v; }
+ public String getHost() { return host; }
+
+ public void setPort(int v) { port = v; }
+ public int getPort() { return port; }
+
+ public void setManagerUrl(String v) { url = v; }
+ public String getManagerUrl() { return url; }
+
+ public void setConnectTimeout(int v) { connectTimeout = v; }
+ public int getConnectTimeout() { return connectTimeout; }
+
+ public void setReadTimeout(int v) { readTimeout = v; }
+ public int getReadTimeout() { return readTimeout; }
+
+ public String getAuthorization() { return authorization; }
+
+ /**
+ * Sets the Authorization credentials
+ */
+ public void setAuthorization(String authorization)
+ {
+ this.authorization = authorization;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Connection.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ConnectionFactory.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ConnectionFactory.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ConnectionFactory.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.jboss.aloha.util.*;
+
+/**
+ * ConnectionFactory
+ *
+ * @author Mladen Turk
+ *
+ */
+public class ConnectionFactory
+{
+ private MessageProtocol protocol = MessageProtocol.Http;
+ private String host = "localhost";
+ private int port = 0;
+ private String url = Default.MANAGER_URL;
+ protected int connectTimeout = Default.CONNECT_TIMEOUT;
+ protected int readTimeout = Default.READ_TIMEOUT;
+ protected String authorization = null;
+
+ private Class conClass;
+
+ public void setProtocol(MessageProtocol v) { protocol = v; }
+
+ public void setProtocol(String v)
+ throws IllegalArgumentException
+ {
+ protocol = MessageProtocol.valueOfIgnoreCase(v);
+ }
+
+ public MessageProtocol getProtocol() { return protocol; }
+
+
+ public void setHost(String v) { host = v; }
+ public String getHost() { return host; }
+
+ public void setPort(int v) { port = v; }
+ public int getPort() { return port; }
+
+ public void setManagerUrl(String v) { url = v; }
+ public String getManagerUrl() { return url; }
+
+ public void setConnectTimeout(int v) { connectTimeout = v; }
+ public int getConnectTimeout() { return connectTimeout; }
+
+ public void setReadTimeout(int v) { readTimeout = v; }
+ public int getReadTimeout() { return readTimeout; }
+
+ public String getAuthorization() { return authorization; }
+
+ /**
+ * Sets the Basic Authorization credentials
+ */
+ public void setBasicAuthorization(String username, String password)
+ {
+ if (username != null && password != null)
+ authorization = "Basic " + Base64.encode(username + ":" + password);
+ }
+
+ /**
+ * Sets the Authorization credentials
+ */
+ public void setAuthorization(String authorization)
+ {
+ this.authorization = authorization;
+ }
+
+ public ConnectionFactory(Class conClass)
+ {
+ this.conClass = conClass;
+ }
+
+ public Connection getConnection()
+ {
+ Connection con;
+ try {
+ con = (Connection)conClass.newInstance();
+ con.setProtocol(protocol);
+ con.setHost(host);
+ con.setPort(port);
+ con.setManagerUrl(url);
+ con.setConnectTimeout(connectTimeout);
+ con.setReadTimeout(readTimeout);
+ con.setAuthorization(authorization);
+
+ } catch (Exception e) {
+ con = null;
+ }
+ return con;
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ConnectionFactory.java
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: sandbox/aloha/java/org/jboss/aloha/GenericResource.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/GenericResource.java 2008-05-28 15:50:29 UTC (rev 1632)
+++ sandbox/aloha/java/org/jboss/aloha/GenericResource.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -56,7 +56,7 @@
public GenericResource(ManagedServer managedServer)
{
- this(managedServer, ResourceType.Unknown.toString());
+ this(managedServer, ResourceType.Unknown.name());
}
public GenericResource()
Added: sandbox/aloha/java/org/jboss/aloha/HttpConnection.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/HttpConnection.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/HttpConnection.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -0,0 +1,194 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
+
+import java.net.URL;
+import java.net.URLEncoder;
+import java.net.HttpURLConnection;
+
+import java.net.ProtocolException;
+import java.net.MalformedURLException;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the HTTP protocol Message to remote Web Server
+ * instance using MCMP protocol
+ *
+ * @author Mladen Turk
+ *
+ */
+public class HttpConnection extends Connection
+{
+ private static final String GET = "GET";
+ private static final String OK = "OK";
+ private static final String ERR_500 = "?Error: 502; Internal Server Error";
+ private static final String ERR_502 = "?Error: 502; Bad Gateway";
+ private static final String ERR_505 = "?Error: 505; HTTP Version not supported";
+ private static final String ERR_400 = "?Error: 400; Bad Request";
+ private static final String ERR_403 = "?Error: 403; Forbidded";
+ private static final String ERR_404 = "?Error: 404; Not Found";
+ private static final String ERR_405 = "?Error: 405; Method Not Allowed";
+ private int responseCode = 0;
+ private String responseDesc = "";
+ private String responseBody = null;
+
+
+ /**
+ * Creates an empty HttpConnection
+ */
+ protected HttpConnection()
+ {
+ }
+
+ public void connect()
+ {
+ // Nothing
+ }
+
+ public void disconnect()
+ {
+ // Nothing
+ }
+
+ /**
+ * Return HTTP response code
+ */
+ public int getResponseCode()
+ {
+ return responseCode;
+ }
+
+ public void sendMessage(Message message)
+ {
+ responseBody = getResponseBody(message);
+ }
+
+ public String getResponse()
+ {
+ return responseBody;
+ }
+
+ private String getResponseBody(Message message)
+ {
+ HttpURLConnection conn;
+ try {
+ URL url = new URL(getConnectionUrl(message.getCommand().name()));
+ conn = (HttpURLConnection)url.openConnection();
+ conn.setRequestMethod(GET);
+ } catch (MalformedURLException u) {
+ responseCode = HttpURLConnection.HTTP_BAD_REQUEST;
+ return ERR_400;
+ } catch (ProtocolException e) {
+ responseCode = HttpURLConnection.HTTP_BAD_METHOD;
+ return ERR_405;
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_FORBIDDEN;
+ return ERR_403;
+ }
+ conn.setAllowUserInteraction(false);
+ conn.setUseCaches(false);
+ conn.setDoInput(true);
+ conn.setDoOutput(false);
+ conn.setRequestProperty(Globals.SERVER_RESOURCE, message.getQuery());
+ if (authorization != null) {
+ // Add Authorization header
+ conn.setRequestProperty("Authorization", authorization);
+ }
+
+ try {
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(readTimeout);
+ conn.connect();
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_BAD_GATEWAY;
+ return ERR_502;
+ }
+ try {
+ responseCode = conn.getResponseCode();
+ responseDesc = conn.getResponseMessage();
+ } catch (IOException x) {
+ responseCode = HttpURLConnection.HTTP_VERSION;
+ conn.disconnect();
+ return ERR_505;
+ }
+
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ StringBuffer eb = new StringBuffer("?Error: ");
+ eb.append(responseCode);
+ eb.append("; ");
+ eb.append(responseDesc);
+ return eb.toString();
+ }
+
+ InputStream is;
+ try {
+ is = conn.getInputStream();
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
+ conn.disconnect();
+ return ERR_500;
+ }
+ StringBuffer s = new StringBuffer();
+ int rd;
+ byte [] bb = new byte[1024];
+ try {
+ while ((rd = is.read(bb)) > 0) {
+ s.append(new String(bb, 0, rd, Default.CHARSET));
+ if (rd < 1024)
+ break;
+ }
+ } catch (Exception e) {
+ // Ignore. Return what we've got so far.
+ }
+ String r = s.toString();
+ if (s.length() == 0)
+ return OK;
+ else
+ return r;
+ }
+
+ private String getConnectionUrl(String path)
+ {
+ StringBuffer sb = new StringBuffer(getProtocol().name().toLowerCase());
+ sb.append("://");
+ sb.append(getHost());
+ if (getPort() > 0) {
+ sb.append(':');
+ sb.append(getPort());
+ }
+ sb.append('/');
+ sb.append(path);
+ sb.append(getManagerUrl());
+ return sb.toString();
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/HttpConnection.java
___________________________________________________________________
Name: svn:eol-style
+ native
Deleted: sandbox/aloha/java/org/jboss/aloha/HttpMessage.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/HttpMessage.java 2008-05-28 15:50:29 UTC (rev 1632)
+++ sandbox/aloha/java/org/jboss/aloha/HttpMessage.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -1,163 +0,0 @@
-/*
- *
- * Copyright(c) 2008 Red Hat Middleware, LLC,
- * and individual contributors as indicated by the @authors tag.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-package org.jboss.aloha;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.InputStream;
-
-import java.net.URL;
-import java.net.URLEncoder;
-import java.net.HttpURLConnection;
-
-import java.net.ProtocolException;
-import java.net.MalformedURLException;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Represents the HTTP protocol Message to remote Web Server
- * instance using MCMP protocol
- *
- * @author Mladen Turk
- *
- */
-public class HttpMessage extends Message
-{
-
- private static final String GET = "GET";
- private static final String OK = "OK";
- private static final String ERR_500 = "?Error: 502; Internal Server Error";
- private static final String ERR_502 = "?Error: 502; Bad Gateway";
- private static final String ERR_505 = "?Error: 505; HTTP Version not supported";
- private static final String ERR_400 = "?Error: 400; Bad Request";
- private static final String ERR_403 = "?Error: 403; Forbidded";
- private static final String ERR_404 = "?Error: 404; Not Found";
- private static final String ERR_405 = "?Error: 405; Method Not Allowed";
- private int responseCode = 0;
- private String responseDesc = "";
-
- /**
- * Creates an empty Message
- */
- public HttpMessage()
- {
- }
-
- protected Message getInstance()
- {
- return this;
- }
-
- /**
- * Return HTTP response code
- */
- public int getResponseCode()
- {
- return responseCode;
- }
-
- public String getResponse(String query)
- {
- HttpURLConnection conn;
- try {
- URL url = new URL(getMessageUrl());
- conn = (HttpURLConnection)url.openConnection();
- conn.setRequestMethod(GET);
- } catch (MalformedURLException u) {
- responseCode = HttpURLConnection.HTTP_BAD_REQUEST;
- return ERR_400;
- } catch (ProtocolException e) {
- responseCode = HttpURLConnection.HTTP_BAD_METHOD;
- return ERR_405;
- } catch (IOException e) {
- responseCode = HttpURLConnection.HTTP_FORBIDDEN;
- return ERR_403;
- }
- conn.setAllowUserInteraction(false);
- conn.setUseCaches(false);
- conn.setDoInput(true);
- conn.setDoOutput(false);
- conn.setRequestProperty(Globals.SERVER_RESOURCE, query);
- if (authorization != null) {
- // Add Authorization header
- conn.setRequestProperty("Authorization", authorization);
- }
-
- try {
- conn.setConnectTimeout(connectTimeout);
- conn.setReadTimeout(readTimeout);
- conn.connect();
- } catch (IOException e) {
- responseCode = HttpURLConnection.HTTP_BAD_GATEWAY;
- return ERR_502;
- }
- try {
- responseCode = conn.getResponseCode();
- responseDesc = conn.getResponseMessage();
- } catch (IOException x) {
- responseCode = HttpURLConnection.HTTP_VERSION;
- conn.disconnect();
- return ERR_505;
- }
-
- if (responseCode != HttpURLConnection.HTTP_OK) {
- StringBuffer eb = new StringBuffer("?Error: ");
- eb.append(responseCode);
- eb.append("; ");
- eb.append(responseDesc);
- return eb.toString();
- }
-
- InputStream is;
- try {
- is = conn.getInputStream();
- } catch (IOException e) {
- responseCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
- conn.disconnect();
- return ERR_500;
- }
- StringBuffer s = new StringBuffer();
- int rd;
- byte [] bb = new byte[1024];
- try {
- while ((rd = is.read(bb)) > 0) {
- s.append(new String(bb, 0, rd, Default.CHARSET));
- if (rd < 1024)
- break;
- }
- } catch (Exception e) {
- // Ignore. Return what we've got so far.
- }
- String r = s.toString();
- if (s.length() == 0)
- return OK;
- else
- return r;
- }
-
-}
Modified: sandbox/aloha/java/org/jboss/aloha/Message.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Message.java 2008-05-28 15:50:29 UTC (rev 1632)
+++ sandbox/aloha/java/org/jboss/aloha/Message.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -35,91 +35,48 @@
* @author Mladen Turk
*
*/
-public abstract class Message
+public class Message
{
- private MessageProtocol protocol = MessageProtocol.Http;
- private Command cmd = Command.Info;
+ private Command cmd;
+ private String query;
+ private ResponseBodyParser parser = new ResponseBodyParser();
- private String host = "localhost";
- private int port = 0;
- private String url = Default.MANAGER_URL;
- protected int connectTimeout = Default.CONNECT_TIMEOUT;
- protected int readTimeout = Default.READ_TIMEOUT;
- protected String authorization = null;
-
/**
- * Creates an empty connection to ManagedServer
+ * Creates an Message
*/
+ public Message(Command cmd, String query)
+ {
+ this.cmd = cmd;
+ this.query = query;
+ }
+
public Message()
{
+ this(Command.Info, "*");
}
- protected abstract int getResponseCode();
- protected abstract String getResponse(String query);
- protected abstract Message getInstance();
+ public Message(String query)
+ {
+ this(Command.Info, query);
+ }
- public void setProtocol(MessageProtocol v) { protocol = v; }
-
- public void setProtocol(String v)
- throws IllegalArgumentException
- {
- protocol = MessageProtocol.valueOfIgnoreCase(v);
- }
-
- public MessageProtocol getProtocol() { return protocol; }
-
-
public void setCommand(Command v) { cmd = v; }
public Command getCommand() { return cmd; }
- public void setHost(String v) { host = v; }
- public String getHost() { return host; }
+ public void setQuery(String v) { query = v; }
+ public String getQuery() { return query; }
- public void setPort(int v) { port = v; }
- public int getPort() { return port; }
+ public ResponseBodyParser getParser() { return parser; }
- public void setManagerUrl(String v) { url = v; }
- public String getManagerUrl() { return url; }
-
- public void setConnectTimeout(int v) { connectTimeout = v; }
- public int getConnectTimeout() { return connectTimeout; }
-
- public void setReadTimeout(int v) { readTimeout = v; }
- public int getReadTimeout() { return readTimeout; }
-
- public String getAuthorization() { return authorization; }
-
- /**
- * Sets the Basic Authorization credentials
- */
- public void setAuthorization(String username, String password)
+ public String toString()
{
- if (username != null && password != null)
- authorization = "Basic " + Base64.encode(username + ":" + password);
+ return query;
}
- /**
- * Sets the Authorization credentials
- */
- public void setAuthorization(String authorization)
+ public void parse(String response)
{
- this.authorization = authorization;
+ parser.parse(response);
}
- public String getMessageUrl()
- {
- StringBuffer sb = new StringBuffer(protocol.name().toLowerCase());
- sb.append("://");
- sb.append(host);
- if (port > 0) {
- sb.append(':');
- sb.append(port);
- }
- sb.append(url);
- sb.append('/');
- sb.append(cmd.name());
- return sb.toString();
- }
-
}
Deleted: sandbox/aloha/java/org/jboss/aloha/MessageFactory.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/MessageFactory.java 2008-05-28 15:50:29 UTC (rev 1632)
+++ sandbox/aloha/java/org/jboss/aloha/MessageFactory.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -1,118 +0,0 @@
-/*
- *
- * Copyright(c) 2008 Red Hat Middleware, LLC,
- * and individual contributors as indicated by the @authors tag.
- * See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- */
-
-package org.jboss.aloha;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import org.jboss.aloha.util.*;
-
-/**
- * MessageFactory
- *
- * @author Mladen Turk
- *
- */
-public class MessageFactory
-{
-
- private MessageProtocol protocol = MessageProtocol.Http;
- private ResponseBodyParser parser = new ResponseBodyParser();
- private Message message;
- private String host = "localhost";
- private int port = 0;
- private String url = Default.MANAGER_URL;
- protected int connectTimeout = Default.CONNECT_TIMEOUT;
- protected int readTimeout = Default.READ_TIMEOUT;
- protected String authorization = null;
-
- /**
- * Creates an empty connection to ManagedServer
- */
- public MessageFactory(Message message)
- {
- this.message = message;
- }
-
- public void setProtocol(MessageProtocol v) { protocol = v; }
-
- public void setProtocol(String v)
- throws IllegalArgumentException
- {
- protocol = MessageProtocol.valueOfIgnoreCase(v);
- }
-
- public MessageProtocol getProtocol() { return protocol; }
-
-
- public void setHost(String v) { host = v; }
- public String getHost() { return host; }
-
- public void setPort(int v) { port = v; }
- public int getPort() { return port; }
-
- public void setManagerUrl(String v) { url = v; }
- public String getManagerUrl() { return url; }
-
- public void setConnectTimeout(int v) { connectTimeout = v; }
- public int getConnectTimeout() { return connectTimeout; }
-
- public void setReadTimeout(int v) { readTimeout = v; }
- public int getReadTimeout() { return readTimeout; }
-
- public String getAuthorization() { return authorization; }
-
- /**
- * Sets the Basic Authorization credentials
- */
- public void setAuthorization(String username, String password)
- {
- if (username != null && password != null)
- authorization = "Basic " + Base64.encode(username + ":" + password);
- }
-
- /**
- * Sets the Authorization credentials
- */
- public void setAuthorization(String authorization)
- {
- this.authorization = authorization;
- }
-
- public Message getMessage()
- {
- Message msg = message.getInstance();
-
- msg.setProtocol(protocol);
- msg.setHost(host);
- msg.setPort(port);
- msg.setManagerUrl(url);
- msg.setConnectTimeout(connectTimeout);
- msg.setReadTimeout(readTimeout);
- msg.setAuthorization(authorization);
-
- return msg;
- }
-
-}
Modified: sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java 2008-05-28 15:50:29 UTC (rev 1632)
+++ sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java 2008-05-29 06:50:34 UTC (rev 1633)
@@ -74,9 +74,9 @@
errorDescription = "No error";
responseType = ResponseType.Empty;
bodyLines.clear();
- grL.clear();
+ grL.clear();
}
-
+
public void parse(String body)
{
clear();
@@ -96,7 +96,7 @@
}
public ResponseBodyParser(String body)
- {
+ {
parse(body);
}
16 years, 7 months
JBoss Native SVN: r1632 - in sandbox/aloha: httpd and 2 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:50:29 -0400 (Wed, 28 May 2008)
New Revision: 1632
Added:
sandbox/aloha/httpd/
sandbox/aloha/httpd/modules/
sandbox/aloha/httpd/modules/manager/
sandbox/aloha/httpd/modules/manager/Makefile.in
sandbox/aloha/httpd/modules/manager/NMAKEmakefile
sandbox/aloha/httpd/modules/manager/NMAKEmanager
sandbox/aloha/httpd/modules/manager/config.m4
sandbox/aloha/httpd/modules/manager/mm_api.h
sandbox/aloha/httpd/modules/manager/mm_app.c
sandbox/aloha/httpd/modules/manager/mm_asmm.c
sandbox/aloha/httpd/modules/manager/mm_asmm.h
sandbox/aloha/httpd/modules/manager/mm_balancer.c
sandbox/aloha/httpd/modules/manager/mm_cookie.c
sandbox/aloha/httpd/modules/manager/mm_cookie.h
sandbox/aloha/httpd/modules/manager/mm_host.c
sandbox/aloha/httpd/modules/manager/mm_manager.c
sandbox/aloha/httpd/modules/manager/mm_member.c
sandbox/aloha/httpd/modules/manager/mm_module.c
sandbox/aloha/httpd/modules/manager/mm_node.c
sandbox/aloha/httpd/modules/manager/mm_pool.c
sandbox/aloha/httpd/modules/manager/mm_server.c
sandbox/aloha/httpd/modules/manager/mm_util.c
sandbox/aloha/httpd/modules/manager/modules.mk
Log:
Add httpd manager module
Added: sandbox/aloha/httpd/modules/manager/Makefile.in
===================================================================
--- sandbox/aloha/httpd/modules/manager/Makefile.in (rev 0)
+++ sandbox/aloha/httpd/modules/manager/Makefile.in 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,3 @@
+# a modules Makefile has no explicit targets -- they will be defined by
+# whatever modules are enabled. just grab special.mk to deal with this.
+include $(top_srcdir)/build/special.mk
Property changes on: sandbox/aloha/httpd/modules/manager/Makefile.in
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/NMAKEmakefile
===================================================================
--- sandbox/aloha/httpd/modules/manager/NMAKEmakefile (rev 0)
+++ sandbox/aloha/httpd/modules/manager/NMAKEmakefile 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,43 @@
+# Copyright 2001-2007 The Apache Software Foundation or its licensors, as
+# applicable.
+#
+# 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.
+#
+# ====================================================================
+#
+# NMAKEmakefile Master HTTPD Manager module makefile.
+#
+# Originally contributed by Mladen Turk <mturk redhat.com>
+#
+# ====================================================================
+#
+
+TARGET=DLL
+!IF !DEFINED(SRCDIR) || "$(SRCDIR)" == ""
+SRCDIR = .
+!ENDIF
+
+!include <..\..\NMAKEcommon.inc>
+!include <..\..\NMAKEhttpd.inc>
+
+MODULES = \
+ $(SRCDIR)\NMAKEmanager
+
+$(MODULES):
+ @$(MAKE) -nologo -f $@ PREFIX=$(PREFIX) install
+
+$(WORKDIR):
+ @$(MAKEWORKDIR)
+
+install: $(WORKDIR) $(MODULES)
+ @xcopy "$(WORKDIR)\*.so" "$(BUILDMOD)" /Y /Q 2>NUL
Property changes on: sandbox/aloha/httpd/modules/manager/NMAKEmakefile
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/NMAKEmanager
===================================================================
--- sandbox/aloha/httpd/modules/manager/NMAKEmanager (rev 0)
+++ sandbox/aloha/httpd/modules/manager/NMAKEmanager 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,81 @@
+# Copyright 2001-2007 The Apache Software Foundation or its licensors, as
+# applicable.
+#
+# 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.
+#
+# ====================================================================
+#
+# NMAKEmakefile cluster module makefile.
+#
+# Originally contributed by Mladen Turk <mturk redhat.com>
+#
+# ====================================================================
+#
+
+TARGET=DLL
+PROJECT = mod_manager
+
+!IF !DEFINED(SRCDIR) || "$(SRCDIR)" == ""
+SRCDIR = .
+!ENDIF
+
+!include <..\..\NMAKEcommon.inc>
+!include <..\..\NMAKEhttpd.inc>
+
+LDIRS = /libpath:"$(BUILDLIB)"
+LFLAGS = $(LFLAGS) user32.lib psapi.lib gdi32.lib shlwapi.lib wldap32.lib ole32.lib $(LIBAPR) $(LIBAPU) $(LIBHTTPD)
+CFLAGS = $(CFLAGS) -DMANAGER_DECLARE_EXPORT
+
+INCLUDES = -I$(SRCDIR) -I$(BUILDINC) -I../generators -I../ssl
+PDBFLAGS = -Fo$(WORKDIR)\ -Fd$(WORKDIR)\$(PROJECT)-src
+
+BUILDBIN = $(WORKDIR)\$(PROJECT).so
+BUILDPDB = $(WORKDIR)\$(PROJECT).pdb
+BUILDRES = $(WORKDIR)\$(PROJECT).res
+BUILDMFT = $(BUILDBIN).manifest
+
+RCFLAGS = $(RCFLAGS) /d BIN_NAME="$(PROJECT).so" /d LONG_NAME="manager_module for Apache"
+
+OBJDEPS = \
+ $(SRCDIR)\mm_asmm.h \
+ $(SRCDIR)\mm_cookie.h \
+ $(SRCDIR)\mm_api.h \
+ $(SRCDIR)\NMAKEmakefile
+
+OBJECTS = \
+ $(WORKDIR)\mm_util.obj \
+ $(WORKDIR)\mm_app.obj \
+ $(WORKDIR)\mm_asmm.obj \
+ $(WORKDIR)\mm_cookie.obj \
+ $(WORKDIR)\mm_balancer.obj \
+ $(WORKDIR)\mm_host.obj \
+ $(WORKDIR)\mm_manager.obj \
+ $(WORKDIR)\mm_member.obj \
+ $(WORKDIR)\mm_pool.obj \
+ $(WORKDIR)\mm_server.obj \
+ $(WORKDIR)\mm_module.obj
+
+{$(SRCDIR)}.c{$(WORKDIR)}.obj:
+ $(CC) $(CFLAGS) $(INCLUDES) $(PDBFLAGS) $<
+
+$(OBJECTS): $(OBJDEPS)
+
+$(BUILDRES): ..\..\build\win32\httpd.rc
+ $(RC) $(RCFLAGS) /i "$(BUILDINC)" /fo $(BUILDRES) ..\..\build\win32\httpd.rc
+
+$(BUILDBIN): $(OBJECTS) $(BUILDRES)
+ $(LINK) $(LFLAGS) $(OBJECTS) $(BUILDRES) $(LIBS) $(LDIRS) /pdb:$(BUILDPDB) /out:$(BUILDBIN)
+ IF EXIST $(BUILDMFT) \
+ mt -nologo -manifest $(BUILDMFT) -outputresource:$(BUILDBIN);2
+
+install: $(BUILDBIN)
Added: sandbox/aloha/httpd/modules/manager/config.m4
===================================================================
--- sandbox/aloha/httpd/modules/manager/config.m4 (rev 0)
+++ sandbox/aloha/httpd/modules/manager/config.m4 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,19 @@
+dnl modules enabled in this directory by default
+
+APACHE_MODPATH_INIT(manager)
+
+if test "$enable_manager" = "shared"; then
+ manager_mods_enable=shared
+elif test "$enable_manager" = "yes"; then
+ manager_mods_enable=yes
+else
+ manager_mods_enable=no
+fi
+
+manager_objs="mm_app.lo mm_asmm.lo mm_balancer.lo mm_cookie.lo mm_host.lo mm_manager.lo mm_member.lo mm_module.lo mm_pool.lo mm_server.lo mm_util.lo"
+APACHE_MODULE(manager, Apache manager module, $manager_objs, , $manager_mods_enable)
+
+
+APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current/../generators])
+
+APACHE_MODPATH_FINISH
Property changes on: sandbox/aloha/httpd/modules/manager/config.m4
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_api.h
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_api.h (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_api.h 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,873 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#ifndef MM_API_H
+#define MM_API_H
+
+/**
+ * @file mm_api.h
+ * @brief Manager Extension Module for Apache
+ *
+ * @defgroup MOD_MANAGER mod_manager
+ * @ingroup APACHE_MODS
+ * @{
+ */
+
+#define CORE_PRIVATE
+
+#include "apr_hooks.h"
+#include "apr.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "apr_buckets.h"
+#include "apr_md5.h"
+#include "apr_network_io.h"
+#include "apr_pools.h"
+#include "apr_strings.h"
+#include "apr_uri.h"
+#include "apr_date.h"
+#include "apr_strmatch.h"
+#include "apr_fnmatch.h"
+#include "apr_reslist.h"
+#include "apr_optional.h"
+#include "apr_uuid.h"
+#include "apr_version.h"
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "ap_config.h"
+#include "ap_listen.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_vhost.h"
+#include "http_main.h"
+#include "http_log.h"
+#include "http_connection.h"
+#include "util_filter.h"
+#include "util_ebcdic.h"
+#include "util_time.h"
+#include "ap_provider.h"
+#include "ap_mpm.h"
+#include "mpm.h"
+#include "mpm_common.h"
+
+#include "mm_asmm.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if APR_HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if !APR_HAS_THREADS
+#error This module does not compile unless you have a thread capable APR!
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_MMN 20080805
+
+#define MM_MCMP_MAJOR 1
+#define MM_MCMP_MINOR 0
+
+#define MM_MCMP_VERSION (MM_MCMP_MAJOR * 10 + MM_MCMP_MINOR)
+
+#define MM_MCMP_VERSION_STRING \
+ APR_STRINGIFY(MM_MCMP_MAJOR) "." \
+ APR_STRINGIFY(MM_MCMP_MINOR)
+
+
+#define MM_DEFAULT_NAME "_default_"
+#define MM_DEFAULT_DBROOT "logs"
+#define MM_LOCK_NAME "/_mm_lock"
+#define MM_DEFAULT_HANDLE "/server-manager"
+#define MM_HANDLER_NAME "Manager-Handler"
+#define MM_CMDHEADER_NAME "X-Server-Command"
+#define MM_RESHEADER_NAME "X-Server-Resource"
+#define MM_PINGHEADER_NAME "X-Server-Ping"
+#define MM_DEF_SESSION_C "JSESSIONID"
+#define MM_DEF_SESSION_P ";jsessionid"
+
+#define MM_DEFAULT_PROTOCOL mm_protocol_ajp
+#define MM_DEFAULT_AJP_PORT 8009
+#define MM_DEFAULT_HTTP_PORT 8080
+#define MM_DEFAULT_HTTPS_PORT 8443
+#define MM_DEFAULT_ADDRESS "localhost"
+
+
+/**
+ * MCMP Protocol commands
+ */
+#define MM_MCMP_INFO "Info"
+#define MM_MCMP_ENABLE "Enable"
+#define MM_MCMP_DISABLE "Disable"
+#define MM_MCMP_STOP "Stop"
+#define MM_MCMP_DELETE "Delete"
+#define MM_MCMP_CONFIG "Config"
+#define MM_MCMP_EXEC "Exec"
+#define MM_MCMP_RESET "Reset"
+
+/**
+ * Manager Resource types
+ */
+#define MM_RES_MANAGER "Manager"
+#define MM_RES_SERVER "Server"
+#define MM_RES_APP_POOL "ApplicationPool"
+#define MM_RES_BALANCER "Balancer"
+#define MM_RES_HOST "Host"
+#define MM_RES_MEMBER "Member"
+#define MM_RES_APPLICATION "Application"
+
+#define MM_BSIZE 4096
+#define MM_SSIZE 1024
+#define MM_DEFAULT_ADVPORT 23364
+#define MM_TM_RESOLUTION APR_TIME_C(100000)
+#define MM_DEFAULT_ADV_FREQ apr_time_from_sec(10)
+#define MM_TM_MAINTAIN_STEP 10
+
+/**
+ * Advertise protocol types
+ */
+#define MM_ADVERTISE_SERVER 0
+#define MM_ADVERTISE_STATUS 1
+
+/**
+ * Posix error codes
+ */
+#define MME_EPERM 1
+#define MME_EACCES 1
+#define MME_EINTR 4
+#define MME_EBUSY 16
+#define MME_ENODEV 19
+#define MME_EINVAL 22
+#define MME_ENOTCONN 57
+
+/**
+ * Table indexes
+ */
+#define MMDB_SERVER 0
+#define MMDB_MANAGER 1
+#define MMDB_HOST 2
+#define MMDB_HOST_LIST 3
+#define MMDB_APP_POOL 4
+#define MMDB_BALANCER 5
+#define MMDB_MEMBER 6
+#define MMDB_APPLICATION 7
+#define MMDB_MEMBERAPP 8
+
+/**
+ * Database record string sizes
+ */
+#define MMDB_TSSIZE 16
+#define MMDB_SSSIZE 32
+#define MMDB_MSSIZE 64
+#define MMDB_HSSIZE 256
+
+/**
+ * Boolean macros
+ */
+#define MM_STR_ON "On"
+#define MM_STR_OFF "Off"
+#define MM_STR_TRUE "True"
+#define MM_STR_FALSE "False"
+#define MM_STR_YES "Yes"
+#define MM_STR_NO "No"
+#define MM_STR_ONOFF(x) ((x) ? MM_STR_ON : MM_STR_OFF)
+#define MM_STR_BOOL(x) ((x) ? MM_STR_TRUE : MM_STR_FALSE)
+#define MM_STR_YN(x) ((x) ? MM_STR_YES : MM_STR_NO)
+#define MM_VAL_BOOL(x) ((!strcasecmp((x), "True") || !strcasecmp((x), "On") || \
+ *(x) == '1' || *(x) == 'Y' || *(x) == 'y') ? 1 : 0)
+
+#define MM_VAL_ONOFF MM_VAL_BOOL
+#define MM_VAL_YN(x) (*(x) == 'Y' || *(x) == 'y' ? 1 : 0)
+
+#define MM_FORCE_DEFAULT_NAME_REQ 0
+#define MM_FFNMATCH APR_FNM_CASE_BLIND
+/**
+ * Multicast Time to Live (ttl) for a advertise transmission.
+ */
+#define MM_ADVERTISE_HOPS 10
+
+/* Create a set of PROXY_DECLARE(type), PROXY_DECLARE_NONSTD(type) and
+ * PROXY_DECLARE_DATA with appropriate export and import tags for the platform
+ */
+#if !defined(WIN32)
+#define MANAGER_DECLARE(type) type
+#define MANAGER_DECLARE_NONSTD(type) type
+#define MANAGER_DECLARE_DATA
+#elif defined(MANAGER_DECLARE_STATIC)
+#define MANAGER_DECLARE(type) type __stdcall
+#define MANAGER_DECLARE_NONSTD(type) type
+#define MANAGER_DECLARE_DATA
+#elif defined(MANAGER_DECLARE_EXPORT)
+#define MANAGER_DECLARE(type) __declspec(dllexport) type __stdcall
+#define MANAGER_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define MANAGER_DECLARE_DATA __declspec(dllexport)
+#else
+#define MANAGER_DECLARE(type) __declspec(dllimport) type __stdcall
+#define MANAGER_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define MANAGER_DECLARE_DATA __declspec(dllimport)
+#endif
+
+void dbprintf(const char *format, ...);
+
+#define MM_SSAFE_COPY(t, f) \
+ if ((f)) \
+ apr_cpystrn((t), (f), sizeof((t)))
+
+#define MM_NSAFE_COPY(t, f, s) \
+ if ((f)) \
+ apr_cpystrn((t), (f), (s))
+
+#define MM_MAYBEQ_RPUTS(r, p, s) \
+ if ((p) && (strchr((s), ' ') || strchr((s), ';') || \
+ strchr((s), ',') || strchr((s), '\t'))) \
+ ap_rvputs((r), "\"", (s), "\"", NULL); \
+ else ap_rvputs((r), (s), NULL)
+
+
+/**
+ * Mod status type enumeration.
+ */
+typedef enum {
+ mm_status_off,
+ mm_status_on,
+ mm_status_full
+} mm_status_e;
+
+/**
+ * Protocol type enumeration.
+ */
+typedef enum {
+ mm_protocol_unknown,
+ mm_protocol_ajp,
+ mm_protocol_http,
+ mm_protocol_https
+} mm_protocol_e;
+
+/**
+ * Advertise mode enumeration.
+ */
+typedef enum {
+ mm_advertise_off,
+ mm_advertise_status,
+ mm_advertise_on
+} mm_advertise_e;
+
+/**
+ * Maintain mode enumeration.
+ */
+typedef enum {
+ mm_maintain_step, /** Step interval */
+ mm_maintain_full, /** Full maintenance */
+ mm_maintain_force /** Forced maintenance */
+} mm_maintain_e;
+
+/**
+ * Response type enumeration.
+ */
+typedef enum {
+ mm_response_ok,
+ mm_response_error, /** ?Error: */
+ mm_response_utype, /** ?Unknown-Type: */
+ mm_response_uparam, /** ?Unknown-Param: */
+ mm_response_version /** ?MCMP-Version */
+} mm_respose_type_e;
+
+/**
+ * MCMP Protocol command enumeration.
+ */
+typedef enum {
+ mm_mcmp_unknown,
+ mm_mcmp_info,
+ mm_mcmp_enable,
+ mm_mcmp_disable,
+ mm_mcmp_stop,
+ mm_mcmp_delete,
+ mm_mcmp_config,
+ mm_mcmp_exec,
+ mm_mcmp_reset
+} mm_mcmp_command_e;
+
+/**
+ * Manager Resource operation enumeration.
+ */
+typedef enum {
+ mm_resource_init,
+ mm_resource_open,
+ mm_resource_child_init,
+ mm_resource_close
+} mm_resource_op_e;
+
+/**
+ * Manager Resource state enumeration.
+ */
+typedef enum {
+ mm_state_unknown, /** - */
+ mm_state_active, /** A */
+ mm_state_busy, /** B */
+ mm_state_disabled, /** D */
+ mm_state_idle, /** I */
+ mm_state_stopped, /** S */
+ mm_state_error, /** E */
+} mm_state_e;
+
+/**
+ * Balancer method used for standalone operations.
+ */
+typedef enum {
+ mm_balance_undef,
+ mm_balance_r, /** R (Round Robin) */
+ mm_balance_b /** B (Bussines) */
+} mm_balance_method_e;
+
+/**
+ * Connection flush mode.
+ */
+typedef enum {
+ mm_flush_none, /** N (None) */
+ mm_flush_wait, /** T (FlushTimeout) */
+ mm_flush_auto /** A (Auto for ajp) */
+} mm_flush_mode_e;
+
+/**
+ * Data structure representing a Manager server
+ * configuration.
+ */
+typedef struct mm_server_conf_t mm_server_conf_t;
+struct mm_server_conf_t {
+ apr_pool_t *pool;
+ server_rec *server;
+ server_rec *main_server;
+ mm_status_e status;
+ int status_set;
+ const char *handle;
+ int handle_set;
+};
+
+/**
+ * Resource provider data structure
+ */
+typedef struct mm_resource_provider_t mm_resource_provider_t;
+
+/**
+ * Resource provider list structure
+ */
+typedef struct mm_resource_list_t mm_resource_list_t;
+
+/**
+ * Advertise header data structure
+ */
+typedef struct mm_advertise_hdr_t mm_advertise_hdr_t;
+struct mm_advertise_hdr_t {
+ int type;
+ apr_status_t status;
+ char suuid[APR_UUID_FORMATTED_LENGTH + 1];
+};
+
+/**
+ * Advertise server data structure
+ */
+typedef struct mm_advertise_srv_t mm_advertise_srv_t;
+struct mm_advertise_srv_t {
+ const char *handle;
+ const char *address;
+ const char *protocol;
+ server_rec *server;
+ apr_port_t port;
+};
+
+
+/**
+ * Shared memory data record structures
+ */
+typedef struct mmdb_manager_t mmdb_manager_t;
+struct mmdb_manager_t {
+ int strict;
+ int type;
+ int case_blind;
+ int status;
+ int advertise;
+ mm_advertise_e advertise_mode;
+ apr_uuid_t suuid;
+ char srvid[APR_UUID_FORMATTED_LENGTH + 2];
+ unsigned char ssalt[APR_MD5_DIGESTSIZE];
+ int generation;
+};
+
+typedef struct mmdb_hostlist_t mmdb_hostlist_t;
+struct mmdb_hostlist_t {
+ apr_uint32_t host_id;
+ apr_uint32_t selfref;
+ char name[MMDB_MSSIZE];
+};
+
+typedef struct mmdb_host_t mmdb_host_t;
+struct mmdb_host_t {
+ apr_uint32_t balancer_id;
+ mm_state_e status;
+ int is_virtual;
+ int keep_alive;
+ apr_uint32_t keep_alive_max;
+ apr_uint32_t limit_req_line;
+ apr_time_t timeout;
+ apr_time_t keep_alive_timeout;
+ char scheme[MMDB_TSSIZE];
+ char document_root[MMDB_HSSIZE];
+ char address[MMDB_MSSIZE];
+ apr_uint32_t port;
+};
+
+typedef struct mmdb_balancer_t mmdb_balancer_t;
+struct mmdb_balancer_t {
+ mm_state_e status;
+ apr_uint32_t members;
+ apr_uint32_t hosts;
+ int sticky_session;
+ int sticky_session_force;
+ int sticky_session_remove;
+ int retries;
+ int abort_if_headers_send;
+ int abort_if_response_get;
+ mm_balance_method_e method;
+ apr_time_t timeout;
+ char name[MMDB_SSSIZE];
+ char sticky_session_cookie[MMDB_SSSIZE];
+ char sticky_session_path[MMDB_SSSIZE];
+ /* Statistical data */
+};
+
+typedef struct mmdb_member_t mmdb_member_t;
+struct mmdb_member_t {
+ apr_uint32_t balancer_id;
+ mm_protocol_e type;
+ apr_uint32_t port;
+ apr_uint32_t ping;
+ apr_uint32_t ttl;
+ apr_uint32_t max_conn;
+ apr_uint32_t min_conn;
+ apr_uint32_t max_clients;
+ char name[MMDB_MSSIZE];
+ char address[MMDB_MSSIZE];
+ char route[MMDB_MSSIZE];
+ char domain[MMDB_MSSIZE];
+ apr_status_t err;
+ mm_state_e activation;
+ mm_flush_mode_e flush;
+ apr_time_t flush_wait;
+ /* Statistical data */
+ volatile mm_state_e state;
+ volatile apr_uint32_t lf;
+ volatile apr_uint32_t distance;
+ volatile apr_uint64_t lf_mult;
+ volatile apr_uint32_t busy;
+ volatile apr_uint32_t connected;
+ volatile apr_uint32_t elected;
+ volatile apr_uint32_t ssessions;
+ volatile apr_uint32_t err_client;
+ volatile apr_uint32_t err_node;
+ volatile apr_uint32_t trace;
+ volatile apr_uint32_t err_trace;
+ volatile apr_uint64_t readed;
+ volatile apr_uint64_t transferred;
+};
+
+typedef struct mmdb_app_pool_t mmdb_app_pool_t;
+struct mmdb_app_pool_t {
+ apr_uint32_t applications;
+ apr_time_t timeout;
+ volatile mm_state_e status;
+ volatile apr_uint32_t busy;
+ volatile apr_uint32_t concurrency;
+ char name[MMDB_MSSIZE];
+};
+
+typedef struct mmdb_app_t mmdb_app_t;
+struct mmdb_app_t {
+ apr_uint32_t host_id;
+ apr_uint32_t app_pool_id;
+ int status;
+ volatile mm_state_e state;
+ char url[MMDB_HSSIZE];
+};
+
+typedef struct mmdb_memberapp_t mmdb_memberapp_t;
+struct mmdb_memberapp_t {
+ apr_uint32_t app_id;
+ apr_uint32_t member_id;
+ volatile mm_state_e state;
+ /* Statistical data */
+ volatile apr_uint32_t busy;
+ volatile apr_uint32_t transactions;
+ volatile apr_uint32_t err_client;
+ volatile apr_uint32_t err_node;
+ volatile apr_uint64_t readed;
+ volatile apr_uint64_t transferred;
+};
+
+/**
+ * Data structure representing a Manager request
+ */
+typedef struct mm_request_rec mm_request_rec;
+struct mm_request_rec {
+ request_rec *r;
+ mm_server_conf_t *sc;
+};
+
+/**
+ * Manager private.
+ * Initialize callback system.
+ * @param pool The pool to use for callbacks.
+ */
+void mm_callback_initialize(apr_pool_t *pool);
+
+
+/**
+ * Manager private.
+ * Retrurn error description.
+ * @param status Error code.
+ */
+const char *mm_strerror(apr_status_t s);
+
+/**
+ * Manager private.
+ * Run advertise callbacks.
+ * @param mode Advertise mode from configuration.
+ * @param opaque Data passed to callback function.
+ * @param callback Callback function executed for
+ * each registered advertise callback.
+ * see @mm_advertisefn_t for details.
+ */
+apr_status_t mm_advertise_callback_run(mm_advertise_e mode, void *opaque,
+ apr_status_t (*callback)(void *, const char *));
+
+/**
+ * Manager private.
+ * Run maintenance callbacks.
+ * @param mode Maintenance mode. @see mm_maintain_e.
+ */
+apr_status_t mm_maintain_callback_run(mm_maintain_e mode);
+
+/**
+ * Manager private.
+ * Send response message.
+ * @param r Request to use
+ * @param type Response type
+ * @param s APR status code
+ */
+void mm_send_response_ex(request_rec *r, mm_respose_type_e type,
+ apr_status_t s, ...);
+
+/**
+ * Manager private.
+ * Get Command type enumeration.
+ * @param cmd Command string
+ */
+mm_mcmp_command_e mm_mcmp_command_get(const char *cmd);
+
+/**
+ * Manager private.
+ * Get Command type name.
+ * @param cmd Command. @see mm_mcmp_command_e.
+ */
+const char *mm_mcmp_command_name_get(mm_mcmp_command_e cmd);
+
+/**
+ * Manager private.
+ * Get State type name.
+ * @param state State. @see mm_state_e.
+ */
+const char *mm_state_name_get(mm_state_e state);
+
+/**
+ * Manager private.
+ * Get State type.
+ * @param state State string. @see mm_state_e.
+ */
+mm_state_e mm_state_get(const char *sstate);
+
+/**
+ * Manager private.
+ * Get Protocol type.
+ * @param protocol Protocol string. @see mm_protocol_e.
+ */
+mm_protocol_e mm_protocol_get(const char *protocol);
+
+/**
+ * Manager private.
+ * Get Protocol type name.
+ * @param protocol Protocol. @see mm_protocol_e.
+ */
+const char *mm_protocol_name_get(mm_protocol_e protocol);
+
+/**
+ * Manager private.
+ * Create Manager database.
+ * @param dbpath Path to the database directory
+ * @param pool The pool to use
+ */
+apr_status_t mmdb_create(const char *dbpath, apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Open Manager database.
+ * @param dbpath Path to the database directory
+ * @param pool The pool to use
+ */
+apr_status_t mmdb_open(const char *dbpath, apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Close Manager database.
+ */
+apr_status_t mmdb_close();
+
+/**
+ * Manager private.
+ * Maintain Manager database.
+ */
+apr_status_t mmdb_maintain(server_rec *s);
+
+/**
+ * Manager private.
+ * Return table slotmem.
+ * @param name Table name
+ */
+asmm_slotmem_t *mmdb_table_get(const char *name);
+
+/**
+ * Manager private.
+ * Return table slotmem.
+ * @param index Table number
+ */
+asmm_slotmem_t *mmdb_table_getn(int index);
+
+/**
+ * Manager private.
+ * Return table name.
+ * @param index Table number
+ */
+const char *mmdb_table_name_get(int id);
+
+/**
+ * Manager private.
+ * Join to advertise group.
+ * @param addr Advertise group address
+ * @param addr Advertise group port
+ * @param pool The pool to use
+ */
+apr_status_t mma_group_join(const char *addr, apr_port_t port,
+ apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * leave advertise group and close socket.
+ */
+void mma_group_leave();
+
+/**
+ * Manager private.
+ * Server advertise callback.
+ */
+apr_status_t mm_advertise_server_cb(void *cd, const char *data);
+
+/**
+ * The prototype for advertise callback function.
+ * @param mode Advertise mode. @see mm_advertise_e.
+ * @param context Callback private data.
+ * @param data Callback provided data buffer
+ * @param len Callback data buffer length
+ */
+typedef apr_status_t (mm_advertisefn_t)(mm_advertise_e mode, void *context,
+ char *data, apr_size_t size);
+
+/**
+ * Register advetrise callback.
+ * @param pool The pool to create any storage from
+ * @param context Callback private data.
+ * @param callback Callback function. @see mm_advertisefn_t for details.
+ */
+MANAGER_DECLARE(void) mm_register_advertise_callback(apr_pool_t *pool,
+ const void *context,
+ mm_advertisefn_t *callback);
+
+
+/**
+ * The prototype for maintenance callback function.
+ * @param mode Advertise mode. @see mm_advertise_e.
+ * @param context Callback private data.
+ */
+typedef apr_status_t (mm_maintainfn_t)(mm_maintain_e mode, void *context);
+
+/**
+ * Register maintain callback.
+ * @param pool The pool to create any storage from
+ * @param data Opaque data
+ * @param callback Callback function. @see mm_maintainfn_t for details.
+ */
+MANAGER_DECLARE(void) mm_register_maintain_callback(apr_pool_t *pool,
+ const void *data,
+ mm_maintainfn_t *callback);
+
+
+/**
+ * The prototype for resource provider function.
+ * @param cfg Manager configuration.
+ * @param cmd Command to execute.
+ * @param name Resource name.
+ * @param prev Previous resource data provider.
+ * @param prev_id Previous resource record id.
+ * @param prev_rec Previous resource record data.
+ * @param cmd_table Command table.
+ * @param cmd_offset Command table offset to the first instruction;
+ * @param r Current request record
+ */
+typedef apr_status_t (mm_runproviderfn_t)(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r);
+
+
+/**
+ * The prototype for resource provider initizalize function.
+ * @param cfg Manager configuration.
+ * @param op Resource operation. @see mm_resource_op_e
+ * @param pool The pool to create any storage from
+ */
+typedef apr_status_t (mm_iniproviderfn_t)(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool);
+
+/**
+ * Resource provider data structure
+ */
+struct mm_resource_provider_t {
+ int id; /** Id of the Resource */
+ const char *name; /** Name of the resource */
+ mm_runproviderfn_t *func; /** @see mm_runproviderfn_t */
+ mm_iniproviderfn_t *init; /** @see mm_iniproviderfn_t */
+ void *context; /** General purpose storage */
+};
+
+
+/**
+ * Resource provider list structure
+ */
+struct mm_resource_list_t {
+ mm_resource_provider_t *provider;
+ mm_resource_list_t *next;
+};
+
+
+/**
+ * Register resource provider.
+ * @param pool The pool to create any storage from
+ * @param provider Resource provider data structure
+ */
+MANAGER_DECLARE(void) mm_register_resource_provider(apr_pool_t *pool,
+ mm_resource_provider_t *provider);
+
+/**
+ * Find registered resource provider.
+ * @param name Resource provider name.
+ */
+MANAGER_DECLARE(mm_resource_provider_t *)mm_lookup_resource_provider(const char *name);
+
+/**
+ * List registered resource provider.
+ * @param pool The poll to allocate list.
+ */
+MANAGER_DECLARE(mm_resource_list_t *)mm_list_resource_providers(apr_pool_t *pool);
+
+/**
+ * Run registered resource providers.
+ * @param cfg Manager configuration.
+ * @param op Resource operation. @see mm_resource_op_e
+ * @param pool The pool to create any storage from
+ */
+MANAGER_DECLARE(void)mm_run_resource_providers(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register static Manager resource
+ */
+void mm_register_resource_manager(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register static Server resource
+ */
+void mm_register_resource_server(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register Host resource
+ */
+void mm_register_resource_host(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register ApplicationPool resource
+ */
+void mm_register_resource_app_pool(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register Balancer resource
+ */
+void mm_register_resource_balancer(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register Member resource
+ */
+void mm_register_resource_member(apr_pool_t *pool);
+
+/**
+ * Manager private.
+ * Register Application resource
+ */
+void mm_register_resource_application(apr_pool_t *pool);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* MM_API_H */
Property changes on: sandbox/aloha/httpd/modules/manager/mm_api.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_app.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_app.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_app.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,730 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Application object resource routines */
+#include "mm_api.h"
+
+static mmdb_manager_t *manager_rec = NULL;
+static mm_resource_provider_t *this_provider = NULL;
+
+static const char *app_params[] = {
+ "",
+ "Host",
+ "ApplicationPool",
+ "State",
+ "Status",
+ NULL
+};
+
+static const char *memberapp_params[] = {
+ "",
+ "State",
+ /* Statistical data */
+ "Busy",
+ "Transactions",
+ "ClientErrors",
+ "NodeErrors",
+ "Readed",
+ "Transferred",
+ NULL
+};
+
+static const char *get_host_name(apr_uint32_t id)
+{
+ apr_uint32_t next = 0;
+ mmdb_hostlist_t *hostlist;
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+
+ while ((hostlist = asmm_slot_next(hostlist_db, &next))) {
+ if (hostlist->host_id == id && hostlist->selfref == (next - 1))
+ return hostlist->name;
+ }
+ return NULL;
+}
+
+static const char *get_app_pool_name(apr_uint32_t id)
+{
+ mmdb_app_pool_t *app_pool;
+ asmm_slotmem_t *app_pool_db = mmdb_table_getn(MMDB_APP_POOL);
+
+ if ((app_pool = asmm_slot(app_pool_db, id))) {
+ return app_pool->name;
+ }
+ return NULL;
+}
+
+static mmdb_app_pool_t *get_app_pool(const char *value, apr_uint32_t *id)
+{
+ apr_uint32_t next = 0;
+ mmdb_app_pool_t *app_pool;
+ asmm_slotmem_t *app_pool_db = mmdb_table_getn(MMDB_APP_POOL);
+
+ while ((app_pool = asmm_slot_next(app_pool_db, &next))) {
+ if (strcasecmp(value, app_pool->name))
+ continue;
+ *id = next - 1;
+ return app_pool;
+ }
+ return NULL;
+}
+
+static void rdo_app_info_print(int pi, int pp,
+ mmdb_app_t *app,
+ request_rec *r)
+{
+ if (pp) {
+ ap_rvputs(r, app_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* Host */
+ ap_rvputs(r, get_host_name(app->host_id), NULL);
+ break;
+ case 2: /* ApplicationPool */
+ ap_rvputs(r, get_app_pool_name(app->app_pool_id), NULL);
+ break;
+ case 3: /* State */
+ ap_rputs(mm_state_name_get(app->state), r);
+ break;
+ case 4: /* Status */
+ ap_rprintf(r, "%d", app->status);
+ break;
+ }
+}
+
+static void rdo_memberapp_info_print(int pi, int pp,
+ mmdb_memberapp_t *mem,
+ request_rec *r)
+{
+ if (pp) {
+ ap_rvputs(r, memberapp_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* State */
+ ap_rputs(mm_state_name_get(mem->state), r);
+ break;
+ case 2: /* Busy */
+ ap_rprintf(r, "%u", mem->busy);
+ break;
+ case 3: /* Transactions */
+ ap_rprintf(r, "%u", mem->transactions);
+ break;
+ case 4: /* ClientErrors */
+ ap_rprintf(r, "%u", mem->err_client);
+ break;
+ case 5: /* NodeErrors */
+ ap_rprintf(r, "%u", mem->err_node);
+ break;
+ case 6: /* Readed */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->readed);
+ break;
+ case 7: /* Transferred */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->transferred);
+ break;
+ }
+}
+
+/* Dump Application info */
+static void rdo_app_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_app_t *app,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (app_params[j]) {
+ if (apr_fnmatch(ce[i].key, app_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (app_params[j]) {
+ if (!strcasecmp(ce[i].key, app_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_app_info_print(m, wcm, app, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (app_params[j]) {
+ if (apr_fnmatch(ce[i].key, app_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_app_info_print(j, 1, app, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (app_params[j]) {
+ if (!strcasecmp(ce[i].key, app_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_app_info_print(j, 1, app, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+/* Dump MemberApplication info */
+static void rdo_memberapp_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_memberapp_t *mem,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (memberapp_params[j]) {
+ if (apr_fnmatch(ce[i].key, memberapp_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (memberapp_params[j]) {
+ if (!strcasecmp(ce[i].key, memberapp_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_memberapp_info_print(m, wcm, mem, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (memberapp_params[j]) {
+ if (apr_fnmatch(ce[i].key, memberapp_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_memberapp_info_print(j, 1, mem, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (memberapp_params[j]) {
+ if (!strcasecmp(ce[i].key, memberapp_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_memberapp_info_print(j, 1, mem, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static apr_status_t rdo_app_config_do(int pi,
+ const char *value,
+ mmdb_app_t *app,
+ request_rec *r)
+{
+ int i;
+ apr_uint32_t app_pool_id;
+ mmdb_app_pool_t *app_pool;
+
+ switch (pi) {
+ case 2: /* ApplicationPool */
+ if (app->app_pool_id) {
+ if (!(app_pool = asmm_slot(mmdb_table_getn(MMDB_APP_POOL),
+ app->app_pool_id)))
+ return MME_EINVAL;
+ if (app_pool->applications)
+ app_pool->applications--;
+ }
+ if ((app_pool = get_app_pool(value, &app_pool_id))) {
+ app->state = mm_state_get(value);
+ if (app_pool_id)
+ app_pool->applications++;
+ }
+ break;
+ case 3: /* State */
+ app->state = mm_state_get(value);
+ break;
+ case 4: /* Status */
+ i = atoi(value);
+ if (ap_is_HTTP_VALID_RESPONSE(i))
+ app->status = i;
+ else
+ return MME_EINVAL;
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_memberapp_config_do(int pi,
+ const char *value,
+ mmdb_memberapp_t *mem,
+ request_rec *r)
+{
+ switch (pi) {
+ case 1: /* State */
+ mem->state = mm_state_get(value);
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+/* Configure Application */
+static int rdo_app_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ mmdb_app_t *app,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (app_params[j]) {
+ if (!strcasecmp(ce[i].key, app_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_app_config_do(j, ce[i].val,
+ app, r)) != APR_SUCCESS) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Configure MemberApplication */
+static int rdo_memberapp_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ mmdb_memberapp_t *memberapp,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (memberapp_params[j]) {
+ if (!strcasecmp(ce[i].key, memberapp_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_memberapp_config_do(j, ce[i].val,
+ memberapp, r)) != APR_SUCCESS) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static apr_status_t rdo_app(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int cblind = 0;
+ int wcm;
+ apr_uint32_t next = 0;
+ apr_uint32_t mapp = 0;
+
+ mmdb_app_t *app;
+ mmdb_memberapp_t *memberapp;
+ mmdb_member_t *member = NULL;
+ mmdb_host_t *host = NULL;
+ mmdb_app_pool_t *app_pool = NULL;
+
+ asmm_slotmem_t *member_db = mmdb_table_getn(MMDB_MEMBER);
+ asmm_slotmem_t *app_db = mmdb_table_getn(MMDB_APPLICATION);
+ asmm_slotmem_t *memberapp_db = mmdb_table_getn(MMDB_MEMBERAPP);
+ asmm_slotmem_t *app_pool_db = mmdb_table_getn(MMDB_APP_POOL);
+
+ if (!memberapp_db || !app_db || !member_db || !app_pool_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty Application name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ }
+ if (manager_rec && manager_rec->case_blind)
+ cblind = 1;
+ if (prev) {
+ switch (prev->id) {
+ case MMDB_HOST:
+ host = (mmdb_host_t *)prev_rec;
+ break;
+ case MMDB_MEMBER:
+ member = (mmdb_member_t *)prev_rec;
+ break;
+ case MMDB_APP_POOL:
+ app_pool = (mmdb_app_pool_t *)prev_rec;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: type %s in not a valid root for "
+ "Application: %s",
+ prev->name, name);
+ return APR_SUCCESS;
+ break;
+
+ }
+ }
+ if (!host && !member && !app_pool) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Missing root object for Application: %s",
+ name);
+ return APR_SUCCESS;
+ }
+ if (*name != '~')
+ wcm = apr_fnmatch_test(name);
+ while ((app = asmm_slot_next(app_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, app->url,
+ cblind ? MM_FFNMATCH : 0) != APR_SUCCESS)
+ continue;
+ }
+ else if (cblind ? strcasecmp(name, app->url) : strcmp(name, app->url))
+ continue;
+ if (host) {
+ if (prev_id != app->host_id)
+ continue;
+ /* Application defined inside Host
+ */
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm)
+ ap_rvputs(r, "@" MM_RES_APPLICATION "/",
+ app->url, ": ", NULL);
+ rdo_app_info(cmd_table, cmd_offset, wcm, app, r);
+ break;
+ case mm_mcmp_config:
+ if (rdo_app_config(cfg, cmd_table, cmd_offset,
+ app, r))
+ return APR_SUCCESS;
+ break;
+ case mm_mcmp_enable:
+ app->state = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ app->state = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ app->state = mm_state_stopped;
+ break;
+ case mm_mcmp_delete:
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for "
+ "Application",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ }
+ else if (member) {
+ /* Manage MemberApplication object
+ * because we were called from
+ * Member object
+ */
+ while ((memberapp = asmm_slot_next(memberapp_db, &mapp))) {
+ if (memberapp->app_id == (next - 1))
+ break;
+ }
+ if (!memberapp) {
+ /* No MemberApplication object found
+ * Database corrupted
+ */
+ return APR_ESYMNOTFOUND;
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm)
+ ap_rvputs(r, "@" MM_RES_APPLICATION "/",
+ app->url, ": ", NULL);
+ rdo_memberapp_info(cmd_table, cmd_offset, wcm,
+ memberapp, r);
+ break;
+ case mm_mcmp_config:
+ if (rdo_memberapp_config(cfg, cmd_table, cmd_offset,
+ memberapp, r))
+ return APR_SUCCESS;
+ break;
+ case mm_mcmp_enable:
+ memberapp->state = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ memberapp->state = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ memberapp->state = mm_state_stopped;
+ break;
+ case mm_mcmp_reset:
+ /* Reset statistical data */
+ memberapp->busy = 0;
+ memberapp->transactions = 0;
+ memberapp->err_client = 0;
+ memberapp->err_node = 0;
+ memberapp->readed = 0;
+ memberapp->transferred = 0;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for "
+ "MemberApplication",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ }
+ else {
+ if (prev_id != app->app_pool_id)
+ continue;
+ /* Application defined inside ApplicationPool
+ */
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm)
+ ap_rvputs(r, MM_RES_APPLICATION "/",
+ app->url, CRLF, NULL);
+ else
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ case mm_mcmp_delete:
+ app->app_pool_id = 0;
+ if (app_pool->applications)
+ app_pool->applications--;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for "
+ "Application",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone && host) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_uint32_t app_id;
+ /* Create new Application and
+ * MemberApplications for all
+ * Members matching balancer_id
+ */
+ if (!(app = asmm_salloc_ex(app_db, &app_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(app->url, name);
+ app->host_id = prev_id;
+ app->state = host->status;
+ app->status = HTTP_OK;
+ /* Configure Application from params */
+ if (rdo_app_config(cfg, cmd_table, cmd_offset, app, r)) {
+ /* There was an error during initial config
+ * Delete Application we created
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: failed creating Application: %s",
+ name);
+ asmm_free(app_db, app);
+ return APR_SUCCESS;
+ }
+
+ /* Add MemberApplication objects */
+ next = 0;
+ while ((member = asmm_slot_next(member_db, &next))) {
+ if (member->balancer_id == host->balancer_id) {
+ if (!(memberapp = asmm_salloc(memberapp_db)))
+ return apr_get_os_error();
+ memberapp->app_id = app_id;
+ memberapp->member_id = next - 1;
+ memberapp->state = app->state;
+ }
+ }
+ }
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_app(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ case mm_resource_open:
+ case mm_resource_child_init:
+ manager_rec = asmm_slot(mmdb_table_getn(MMDB_MANAGER), 0);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a Applications */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t app_provider = {
+ MMDB_APPLICATION,
+ MM_RES_APPLICATION,
+ rdo_app,
+ ini_app,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_application(apr_pool_t *pool)
+{
+ this_provider = &app_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_app.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_asmm.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_asmm.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_asmm.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,1548 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Advanced shared memory utility routines */
+#include "mm_asmm.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h> /* for getpid() */
+#endif
+
+#if APR_IS_BIGENDIAN
+#define ASMM_DEAD_COOKIE 0xDEADBEEF
+#else
+#define ASMM_DEAD_COOKIE 0xEFBEADDE
+#endif
+
+static apr_byte_t __zero_bit_mask[] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+static apr_byte_t __ones_bit_mask[] = {
+ 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE
+};
+
+static struct __byte_bits {
+ apr_byte_t left; /* number of left zeros */
+ apr_byte_t right; /* number of right zeros */
+ apr_byte_t count; /* zeros count*/
+ apr_byte_t first; /* first zero position */
+ apr_byte_t hole; /* hole size */
+ apr_byte_t pos; /* hole position */
+} __bit_mask[] = {
+ /* L R C F H P */
+ /* 00000000 */ { 8, 8, 8, 0, 8, 0},
+ /* 00000001 */ { 7, 0, 7, 0, 7, 0},
+ /* 00000010 */ { 6, 1, 7, 0, 6, 0},
+ /* 00000011 */ { 6, 0, 6, 0, 6, 0},
+ /* 00000100 */ { 5, 2, 7, 0, 5, 0},
+ /* 00000101 */ { 5, 0, 6, 0, 5, 0},
+ /* 00000110 */ { 5, 1, 6, 0, 5, 0},
+ /* 00000111 */ { 5, 0, 5, 0, 5, 0},
+ /* 00001000 */ { 4, 3, 7, 0, 4, 0},
+ /* 00001001 */ { 4, 0, 6, 0, 4, 0},
+ /* 00001010 */ { 4, 1, 6, 0, 4, 0},
+ /* 00001011 */ { 4, 0, 5, 0, 4, 0},
+ /* 00001100 */ { 4, 2, 6, 0, 4, 0},
+ /* 00001101 */ { 4, 0, 5, 0, 4, 0},
+ /* 00001110 */ { 4, 1, 5, 0, 4, 0},
+ /* 00001111 */ { 4, 0, 4, 0, 4, 0},
+ /* 00010000 */ { 3, 4, 7, 0, 4, 4},
+ /* 00010001 */ { 3, 0, 6, 0, 3, 0},
+ /* 00010010 */ { 3, 1, 6, 0, 3, 0},
+ /* 00010011 */ { 3, 0, 5, 0, 3, 0},
+ /* 00010100 */ { 3, 2, 6, 0, 3, 0},
+ /* 00010101 */ { 3, 0, 5, 0, 3, 0},
+ /* 00010110 */ { 3, 1, 5, 0, 3, 0},
+ /* 00010111 */ { 3, 0, 4, 0, 3, 0},
+ /* 00011000 */ { 3, 3, 6, 0, 3, 0},
+ /* 00011001 */ { 3, 0, 5, 0, 3, 0},
+ /* 00011010 */ { 3, 1, 5, 0, 3, 0},
+ /* 00011011 */ { 3, 0, 4, 0, 3, 0},
+ /* 00011100 */ { 3, 2, 5, 0, 3, 0},
+ /* 00011101 */ { 3, 0, 4, 0, 3, 0},
+ /* 00011110 */ { 3, 1, 4, 0, 3, 0},
+ /* 00011111 */ { 3, 0, 3, 0, 3, 0},
+ /* 00100000 */ { 2, 5, 7, 0, 5, 0},
+ /* 00100001 */ { 2, 0, 6, 0, 4, 0},
+ /* 00100010 */ { 2, 1, 6, 0, 3, 0},
+ /* 00100011 */ { 2, 0, 5, 0, 3, 0},
+ /* 00100100 */ { 2, 2, 6, 0, 2, 0},
+ /* 00100101 */ { 2, 0, 5, 0, 2, 0},
+ /* 00100110 */ { 2, 1, 5, 0, 2, 0},
+ /* 00100111 */ { 2, 0, 4, 0, 2, 0},
+ /* 00101000 */ { 2, 3, 6, 0, 3, 5},
+ /* 00101001 */ { 2, 0, 5, 0, 2, 0},
+ /* 00101010 */ { 2, 1, 5, 0, 2, 0},
+ /* 00101011 */ { 2, 0, 4, 0, 2, 0},
+ /* 00101100 */ { 2, 2, 5, 0, 2, 0},
+ /* 00101101 */ { 2, 0, 4, 0, 2, 0},
+ /* 00101110 */ { 2, 1, 4, 0, 2, 0},
+ /* 00101111 */ { 2, 0, 3, 0, 2, 0},
+ /* 00110000 */ { 2, 4, 6, 0, 4, 4},
+ /* 00110001 */ { 2, 0, 5, 0, 3, 4},
+ /* 00110010 */ { 2, 1, 5, 0, 2, 0},
+ /* 00110011 */ { 2, 0, 4, 0, 2, 0},
+ /* 00110100 */ { 2, 2, 5, 0, 2, 0},
+ /* 00110101 */ { 2, 0, 4, 0, 2, 0},
+ /* 00110110 */ { 2, 1, 4, 0, 2, 0},
+ /* 00110111 */ { 2, 0, 3, 0, 2, 0},
+ /* 00111000 */ { 2, 3, 5, 0, 3, 5},
+ /* 00111001 */ { 2, 0, 4, 0, 2, 0},
+ /* 00111010 */ { 2, 1, 4, 0, 2, 0},
+ /* 00111011 */ { 2, 0, 3, 0, 2, 0},
+ /* 00111100 */ { 2, 2, 4, 0, 2, 0},
+ /* 00111101 */ { 2, 0, 3, 0, 2, 0},
+ /* 00111110 */ { 2, 1, 3, 0, 2, 0},
+ /* 00111111 */ { 2, 0, 2, 0, 2, 0},
+ /* 01000000 */ { 1, 6, 7, 0, 6, 2},
+ /* 01000001 */ { 1, 0, 6, 0, 5, 2},
+ /* 01000010 */ { 1, 1, 6, 0, 4, 2},
+ /* 01000011 */ { 1, 0, 5, 0, 4, 2},
+ /* 01000100 */ { 1, 2, 6, 0, 3, 2},
+ /* 01000101 */ { 1, 0, 5, 0, 3, 2},
+ /* 01000110 */ { 1, 1, 5, 0, 3, 2},
+ /* 01000111 */ { 1, 0, 4, 0, 3, 2},
+ /* 01001000 */ { 1, 3, 6, 0, 3, 5},
+ /* 01001001 */ { 1, 0, 5, 0, 2, 2},
+ /* 01001010 */ { 1, 1, 5, 0, 2, 2},
+ /* 01001011 */ { 1, 0, 4, 0, 2, 2},
+ /* 01001100 */ { 1, 2, 5, 0, 2, 2},
+ /* 01001101 */ { 1, 0, 4, 0, 2, 2},
+ /* 01001110 */ { 1, 1, 4, 0, 2, 2},
+ /* 01001111 */ { 1, 0, 3, 0, 2, 2},
+ /* 01010000 */ { 1, 4, 6, 0, 4, 4},
+ /* 01010001 */ { 1, 0, 5, 0, 3, 4},
+ /* 01010010 */ { 1, 1, 5, 0, 2, 4},
+ /* 01010011 */ { 1, 0, 4, 0, 2, 4},
+ /* 01010100 */ { 1, 2, 5, 0, 2, 6},
+ /* 01010101 */ { 1, 0, 4, 0, 1, 0},
+ /* 01010110 */ { 1, 1, 4, 0, 1, 0},
+ /* 01010111 */ { 1, 0, 3, 0, 1, 0},
+ /* 01011000 */ { 1, 3, 5, 0, 3, 5},
+ /* 01011001 */ { 1, 0, 4, 0, 2, 5},
+ /* 01011010 */ { 1, 1, 4, 0, 1, 0},
+ /* 01011011 */ { 1, 0, 3, 0, 1, 0},
+ /* 01011100 */ { 1, 2, 4, 0, 2, 6},
+ /* 01011101 */ { 1, 0, 3, 0, 1, 0},
+ /* 01011110 */ { 1, 1, 3, 0, 1, 0},
+ /* 01011111 */ { 1, 0, 2, 0, 1, 0},
+ /* 01100000 */ { 1, 5, 6, 0, 5, 0},
+ /* 01100001 */ { 1, 0, 5, 0, 4, 0},
+ /* 01100010 */ { 1, 1, 5, 0, 3, 0},
+ /* 01100011 */ { 1, 0, 4, 0, 3, 0},
+ /* 01100100 */ { 1, 2, 5, 0, 2, 0},
+ /* 01100101 */ { 1, 0, 4, 0, 2, 0},
+ /* 01100110 */ { 1, 1, 4, 0, 2, 0},
+ /* 01100111 */ { 1, 0, 3, 0, 2, 0},
+ /* 01101000 */ { 1, 3, 5, 0, 3, 5},
+ /* 01101001 */ { 1, 0, 4, 0, 2, 5},
+ /* 01101010 */ { 1, 1, 4, 0, 1, 0},
+ /* 01101011 */ { 1, 0, 3, 0, 1, 0},
+ /* 01101100 */ { 1, 2, 4, 0, 2, 6},
+ /* 01101101 */ { 1, 0, 3, 0, 1, 0},
+ /* 01101110 */ { 1, 1, 3, 0, 1, 0},
+ /* 01101111 */ { 1, 0, 2, 0, 1, 0},
+ /* 01110000 */ { 1, 4, 5, 0, 4, 4},
+ /* 01110001 */ { 1, 0, 4, 0, 3, 4},
+ /* 01110010 */ { 1, 1, 4, 0, 2, 4},
+ /* 01110011 */ { 1, 0, 3, 0, 2, 4},
+ /* 01110100 */ { 1, 2, 4, 0, 2, 6},
+ /* 01110101 */ { 1, 0, 3, 0, 1, 0},
+ /* 01110110 */ { 1, 1, 3, 0, 1, 0},
+ /* 01110111 */ { 1, 0, 2, 0, 1, 0},
+ /* 01111000 */ { 1, 3, 4, 0, 3, 5},
+ /* 01111001 */ { 1, 0, 3, 0, 2, 5},
+ /* 01111010 */ { 1, 1, 3, 0, 1, 0},
+ /* 01111011 */ { 1, 0, 2, 0, 1, 0},
+ /* 01111100 */ { 1, 2, 3, 0, 2, 6},
+ /* 01111101 */ { 1, 0, 2, 0, 1, 0},
+ /* 01111110 */ { 1, 1, 2, 0, 1, 0},
+ /* 01111111 */ { 1, 0, 1, 0, 1, 0},
+ /* 10000000 */ { 0, 7, 7, 1, 7, 1},
+ /* 10000001 */ { 0, 0, 6, 1, 6, 1},
+ /* 10000010 */ { 0, 1, 6, 1, 5, 1},
+ /* 10000011 */ { 0, 0, 5, 1, 5, 1},
+ /* 10000100 */ { 0, 2, 6, 1, 4, 1},
+ /* 10000101 */ { 0, 0, 5, 1, 4, 1},
+ /* 10000110 */ { 0, 1, 5, 1, 4, 1},
+ /* 10000111 */ { 0, 0, 4, 1, 4, 1},
+ /* 10001000 */ { 0, 3, 6, 1, 3, 1},
+ /* 10001001 */ { 0, 0, 5, 1, 3, 1},
+ /* 10001010 */ { 0, 1, 5, 1, 3, 1},
+ /* 10001011 */ { 0, 0, 4, 1, 3, 1},
+ /* 10001100 */ { 0, 2, 5, 1, 3, 1},
+ /* 10001101 */ { 0, 0, 4, 1, 3, 1},
+ /* 10001110 */ { 0, 1, 4, 1, 3, 1},
+ /* 10001111 */ { 0, 0, 3, 1, 3, 1},
+ /* 10010000 */ { 0, 4, 6, 1, 4, 4},
+ /* 10010001 */ { 0, 0, 5, 1, 3, 4},
+ /* 10010010 */ { 0, 1, 5, 1, 2, 1},
+ /* 10010011 */ { 0, 0, 4, 1, 2, 1},
+ /* 10010100 */ { 0, 2, 5, 1, 2, 1},
+ /* 10010101 */ { 0, 0, 4, 1, 2, 1},
+ /* 10010110 */ { 0, 1, 4, 1, 2, 1},
+ /* 10010111 */ { 0, 0, 3, 1, 2, 1},
+ /* 10011000 */ { 0, 3, 5, 1, 3, 5},
+ /* 10011001 */ { 0, 0, 4, 1, 2, 1},
+ /* 10011010 */ { 0, 1, 4, 1, 2, 1},
+ /* 10011011 */ { 0, 0, 3, 1, 2, 1},
+ /* 10011100 */ { 0, 2, 4, 1, 2, 1},
+ /* 10011101 */ { 0, 0, 3, 1, 2, 1},
+ /* 10011110 */ { 0, 1, 3, 1, 2, 1},
+ /* 10011111 */ { 0, 0, 2, 1, 2, 1},
+ /* 10100000 */ { 0, 5, 6, 1, 5, 1},
+ /* 10100001 */ { 0, 0, 5, 1, 4, 1},
+ /* 10100010 */ { 0, 1, 5, 1, 3, 1},
+ /* 10100011 */ { 0, 0, 4, 1, 3, 1},
+ /* 10100100 */ { 0, 2, 5, 1, 2, 1},
+ /* 10100101 */ { 0, 0, 4, 1, 2, 1},
+ /* 10100110 */ { 0, 1, 4, 1, 2, 1},
+ /* 10100111 */ { 0, 0, 3, 1, 2, 1},
+ /* 10101000 */ { 0, 3, 5, 1, 3, 5},
+ /* 10101001 */ { 0, 0, 4, 1, 2, 5},
+ /* 10101010 */ { 0, 1, 4, 1, 1, 1},
+ /* 10101011 */ { 0, 0, 3, 1, 1, 1},
+ /* 10101100 */ { 0, 2, 4, 1, 2, 6},
+ /* 10101101 */ { 0, 0, 3, 1, 1, 1},
+ /* 10101110 */ { 0, 1, 3, 1, 1, 1},
+ /* 10101111 */ { 0, 0, 2, 1, 1, 1},
+ /* 10110000 */ { 0, 4, 5, 1, 4, 4},
+ /* 10110001 */ { 0, 0, 4, 1, 3, 4},
+ /* 10110010 */ { 0, 1, 4, 1, 2, 4},
+ /* 10110011 */ { 0, 0, 3, 1, 2, 4},
+ /* 10110100 */ { 0, 2, 4, 1, 2, 6},
+ /* 10110101 */ { 0, 0, 3, 1, 1, 1},
+ /* 10110110 */ { 0, 1, 3, 1, 1, 1},
+ /* 10110111 */ { 0, 0, 2, 1, 1, 1},
+ /* 10111000 */ { 0, 3, 4, 1, 3, 5},
+ /* 10111001 */ { 0, 0, 3, 1, 2, 5},
+ /* 10111010 */ { 0, 1, 3, 1, 1, 1},
+ /* 10111011 */ { 0, 0, 2, 1, 1, 1},
+ /* 10111100 */ { 0, 2, 3, 1, 2, 6},
+ /* 10111101 */ { 0, 0, 2, 1, 1, 1},
+ /* 10111110 */ { 0, 1, 2, 1, 1, 1},
+ /* 10111111 */ { 0, 0, 1, 1, 1, 1},
+ /* 11000000 */ { 0, 6, 6, 2, 6, 2},
+ /* 11000001 */ { 0, 0, 5, 2, 5, 2},
+ /* 11000010 */ { 0, 1, 5, 2, 4, 2},
+ /* 11000011 */ { 0, 0, 4, 2, 4, 2},
+ /* 11000100 */ { 0, 2, 5, 2, 3, 2},
+ /* 11000101 */ { 0, 0, 4, 2, 3, 2},
+ /* 11000110 */ { 0, 1, 4, 2, 3, 2},
+ /* 11000111 */ { 0, 0, 3, 2, 3, 2},
+ /* 11001000 */ { 0, 3, 5, 2, 3, 5},
+ /* 11001001 */ { 0, 0, 4, 2, 2, 2},
+ /* 11001010 */ { 0, 1, 4, 2, 2, 2},
+ /* 11001011 */ { 0, 0, 3, 2, 2, 2},
+ /* 11001100 */ { 0, 2, 4, 2, 2, 2},
+ /* 11001101 */ { 0, 0, 3, 2, 2, 2},
+ /* 11001110 */ { 0, 1, 3, 2, 2, 2},
+ /* 11001111 */ { 0, 0, 2, 2, 2, 2},
+ /* 11010000 */ { 0, 4, 5, 2, 4, 4},
+ /* 11010001 */ { 0, 0, 4, 2, 3, 4},
+ /* 11010010 */ { 0, 1, 4, 2, 2, 4},
+ /* 11010011 */ { 0, 0, 3, 2, 2, 4},
+ /* 11010100 */ { 0, 2, 4, 2, 2, 6},
+ /* 11010101 */ { 0, 0, 3, 2, 1, 2},
+ /* 11010110 */ { 0, 1, 3, 2, 1, 2},
+ /* 11010111 */ { 0, 0, 2, 2, 1, 2},
+ /* 11011000 */ { 0, 3, 4, 2, 3, 5},
+ /* 11011001 */ { 0, 0, 3, 2, 2, 5},
+ /* 11011010 */ { 0, 1, 3, 2, 1, 2},
+ /* 11011011 */ { 0, 0, 2, 2, 1, 2},
+ /* 11011100 */ { 0, 2, 3, 2, 2, 6},
+ /* 11011101 */ { 0, 0, 2, 2, 1, 2},
+ /* 11011110 */ { 0, 1, 2, 2, 1, 2},
+ /* 11011111 */ { 0, 0, 1, 2, 1, 2},
+ /* 11100000 */ { 0, 5, 5, 3, 5, 3},
+ /* 11100001 */ { 0, 0, 4, 3, 4, 3},
+ /* 11100010 */ { 0, 1, 4, 3, 3, 3},
+ /* 11100011 */ { 0, 0, 3, 3, 3, 3},
+ /* 11100100 */ { 0, 2, 4, 3, 2, 3},
+ /* 11100101 */ { 0, 0, 3, 3, 2, 3},
+ /* 11100110 */ { 0, 1, 3, 3, 2, 3},
+ /* 11100111 */ { 0, 0, 2, 3, 2, 3},
+ /* 11101000 */ { 0, 3, 4, 3, 3, 5},
+ /* 11101001 */ { 0, 0, 3, 3, 2, 5},
+ /* 11101010 */ { 0, 1, 3, 3, 1, 3},
+ /* 11101011 */ { 0, 0, 2, 3, 1, 3},
+ /* 11101100 */ { 0, 2, 3, 3, 2, 6},
+ /* 11101101 */ { 0, 0, 2, 3, 1, 3},
+ /* 11101110 */ { 0, 1, 2, 3, 1, 3},
+ /* 11101111 */ { 0, 0, 1, 3, 1, 3},
+ /* 11110000 */ { 0, 4, 4, 4, 4, 4},
+ /* 11110001 */ { 0, 0, 3, 4, 3, 4},
+ /* 11110010 */ { 0, 1, 3, 4, 2, 4},
+ /* 11110011 */ { 0, 0, 2, 4, 2, 4},
+ /* 11110100 */ { 0, 2, 3, 4, 2, 6},
+ /* 11110101 */ { 0, 0, 2, 4, 1, 4},
+ /* 11110110 */ { 0, 1, 2, 4, 1, 4},
+ /* 11110111 */ { 0, 0, 1, 4, 1, 4},
+ /* 11111000 */ { 0, 3, 3, 5, 3, 5},
+ /* 11111001 */ { 0, 0, 2, 5, 2, 5},
+ /* 11111010 */ { 0, 1, 2, 5, 1, 5},
+ /* 11111011 */ { 0, 0, 1, 5, 1, 5},
+ /* 11111100 */ { 0, 2, 2, 6, 2, 6},
+ /* 11111101 */ { 0, 0, 1, 6, 1, 6},
+ /* 11111110 */ { 0, 1, 1, 7, 1, 7},
+ /* 11111111 */ { 0, 0, 0, 0, 0, 0}
+};
+
+static apr_byte_t __sbit_mask[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 0
+};
+
+
+#define _GET_BIT(a, x) ((((a)[(x) >> 3] & __zero_bit_mask[(x) & 0x07]) != 0))
+#define _SET_BIT(a, x) ((void)((a)[(x) >> 3] |= __zero_bit_mask[(x) & 0x07]))
+#define _CLR_BIT(a, x) ((void)((a)[(x) >> 3] &= __ones_bit_mask[(x) & 0x07]))
+#define _FLP_BIT(a, x) ((void)((a)[(x) >> 3] ^= __zero_bit_mask[(x) & 0x07]))
+
+#define _ASMM_VLOCK(m) \
+ if ((m)->lock) \
+ (void)apr_global_mutex_lock((m)->lock)
+
+#define _ASMM_LOCK(m) \
+ if ((m)->lock) { \
+ apr_status_t _rv; \
+ if ((_rv = apr_global_mutex_lock((m)->lock)) != APR_SUCCESS) { \
+ apr_set_os_error(_rv); \
+ return NULL; } } else (void)(0)
+
+#define _ASMM_UNLOCK(m) \
+ if ((m)->lock) apr_global_mutex_unlock((m)->lock)
+
+static apr_status_t asmm_bmp_get(const apr_byte_t *bmp, apr_uint32_t len,
+ apr_uint32_t *pos)
+{
+ apr_uint32_t i;
+
+ for (i = 0; i < len; i++) {
+ if (bmp[i] != 0xFF) {
+ *pos = (i << 3) + __sbit_mask[bmp[i]];
+ return APR_SUCCESS;
+ }
+ }
+ return APR_EOF;
+}
+
+static apr_uint32_t asmm_bmp_free(const apr_byte_t *bmp, apr_uint32_t len)
+{
+ apr_uint32_t i, c = 0;
+
+ for (i = 0; i < len; i++) {
+ c += __bit_mask[i].count;
+ }
+ return c;
+}
+
+static apr_status_t asmm_bmp_find(const apr_byte_t *bmp, apr_uint32_t len,
+ apr_uint32_t size, apr_uint32_t *pos)
+{
+ apr_uint32_t i;
+
+ len = len >> 3;
+ if (size > 8) {
+ apr_uint32_t nb, p;
+ nb = size >> 3;
+ if ((nb << 3) < size)
+ nb++;
+ for (i = 0; i <= len - nb; i++) {
+ apr_uint32_t r;
+ if ((r = __bit_mask[bmp[i]].right) != 0) {
+ p = (i << 3) + 8 - r;
+ if (!_GET_BIT(bmp, p + size - 1)) {
+ apr_uint32_t j;
+ for (j = 1; j < nb; j++) {
+ if (__bit_mask[bmp[i + j]].left != 8)
+ break;
+ r += __bit_mask[bmp[i + j]].left;
+ }
+ if (r >= size) {
+ *pos = p;
+ return APR_SUCCESS;
+ }
+ }
+ else
+ i += nb;
+ }
+ }
+ }
+ else { /* find the hole in the bitmap */
+ for (i = 0; i < len; i++) {
+ if (__bit_mask[bmp[i]].hole >= (apr_byte_t)size) {
+ *pos = (i << 3) + __bit_mask[bmp[i]].pos;
+ return APR_SUCCESS;
+ }
+ else if (__bit_mask[bmp[i]].right +
+ __bit_mask[bmp[i + 1]].left >= (apr_byte_t)size) {
+ *pos = (i << 3) + 8 - __bit_mask[bmp[i]].right;
+ return APR_SUCCESS;
+ }
+ }
+ }
+ return APR_EOF;
+}
+
+static void asmm_bmp_set(apr_byte_t *bmp, apr_uint32_t from,
+ apr_uint32_t to)
+{
+ for (; from < to; from++)
+ _SET_BIT(bmp, from);
+}
+
+static void asmm_bmp_clr(apr_byte_t *bmp, apr_uint32_t from,
+ apr_uint32_t to)
+{
+ for (; from < to; from++)
+ _CLR_BIT(bmp, from);
+}
+
+
+/* In shared memory bitmap data */
+typedef struct asmm_shm_data_t asmm_shm_data_t;
+struct asmm_shm_data_t {
+ volatile apr_uint64_t timestamp;
+ volatile apr_uint16_t flags;
+ volatile apr_uint16_t nsections;
+ apr_uint32_t section;
+ apr_uint32_t blksize;
+ apr_uint32_t nblocks;
+ /* Followed by apr_byte_t[nblocks >> 3] */
+ /* Followed by apr_byte_t[nblocks * blksize] */
+};
+
+/* In memory wrapper over shared memory bitmaps */
+typedef struct asmm_mem_data_t asmm_mem_data_t;
+struct asmm_mem_data_t {
+ const char *name;
+ apr_shm_t *shm;
+ asmm_shm_data_t *hdr;
+ apr_byte_t *bitmap;
+ apr_byte_t *data;
+ asmm_mem_data_t *next;
+};
+
+/* In memory */
+struct asmm_slotmem_t {
+ volatile apr_uint64_t timestamp;
+ volatile apr_uint16_t nsections;
+ volatile apr_uint16_t flags;
+ apr_uint16_t maxsections;
+ apr_uint16_t pflags;
+ apr_uint32_t blksize;
+ apr_uint32_t nblocks;
+ apr_interval_time_t timeout;
+ const char *prefix;
+ asmm_mem_data_t *sections;
+ apr_global_mutex_t *lock;
+ apr_pool_t *pool;
+};
+
+/* Memory node header
+ * When refcount is zero only then the node
+ * can be deallocated
+ */
+typedef struct asmm_mem_node_t asmm_mem_node_t;
+struct asmm_mem_node_t {
+ volatile apr_uint32_t refcount;
+ apr_uint32_t size;
+ /* Followed by apr_byte_t[size * blksize] */
+};
+
+static apr_status_t slotmem_cleanup(asmm_slotmem_t *mem)
+{
+ asmm_mem_data_t *bmp = mem->sections;
+ apr_uint16_t clr = 0;
+
+ if (mem->maxsections)
+ clr = ASMM_DIRTY;
+
+ while (bmp) {
+ bmp->hdr->flags |= clr;
+ if (mem->pflags & ASMM_OWNER) {
+ apr_shm_destroy(bmp->shm);
+ apr_file_remove(bmp->name, NULL);
+ }
+ else {
+ apr_shm_detach(bmp->shm);
+ }
+ bmp = bmp->next;
+ }
+ mem->sections = NULL;
+ return APR_SUCCESS;
+}
+
+static apr_status_t create_bitmap_segment(asmm_mem_data_t **bmp,
+ apr_uint32_t blksize,
+ apr_uint32_t nblocks,
+ const char *name,
+ apr_pool_t *ctx)
+{
+ apr_size_t size;
+ apr_uint32_t bsa;
+ apr_uint32_t nba;
+ apr_uint32_t bba;
+ apr_byte_t *data;
+ apr_status_t rv;
+
+ *bmp = (asmm_mem_data_t *)apr_palloc(ctx, sizeof(asmm_mem_data_t));
+
+ /* Align everything to 8 bytes */
+ bsa = APR_ALIGN(blksize + sizeof(asmm_mem_node_t), 8);
+ nba = APR_ALIGN(nblocks, 8);
+ bba = APR_ALIGN(nblocks, 64);
+ size = sizeof(asmm_shm_data_t) + (bba >> 3) + nba * bsa;
+
+ apr_shm_remove(name, ctx);
+ if ((rv = apr_shm_create(&(*bmp)->shm, size, name, ctx)) != APR_SUCCESS)
+ return rv;
+
+ data = (apr_byte_t *)apr_shm_baseaddr_get((*bmp)->shm);
+
+ (*bmp)->hdr = (asmm_shm_data_t *)data;
+ (*bmp)->bitmap = data + sizeof(asmm_shm_data_t);
+ (*bmp)->data = (*bmp)->bitmap + (bba >> 3);
+ (*bmp)->next = NULL;
+ (*bmp)->name = apr_pstrdup(ctx, name);
+
+ /* Set bitmap to all free except alignment overflow */
+ memset((*bmp)->bitmap, 0xFF, bba >> 3);
+ memset((*bmp)->bitmap, 0, nba >> 3);
+ memset((*bmp)->data, 0, nba * bsa);
+
+ (*bmp)->hdr->blksize = bsa;
+ (*bmp)->hdr->nblocks = nba;
+ (*bmp)->hdr->section = 0;
+ (*bmp)->hdr->nsections = 0;
+ (*bmp)->hdr->flags = 0;
+ (*bmp)->hdr->timestamp = 0;
+ /* Ignore errors */
+ mm_unixd_set_shm_perms(name);
+
+ return APR_SUCCESS;
+}
+
+static void copy_bitmap_segment(asmm_mem_data_t *to,
+ asmm_mem_data_t *from)
+{
+
+ to->hdr->blksize = from->hdr->blksize;
+ to->hdr->nblocks = from->hdr->nblocks;
+ to->hdr->section = from->hdr->section;
+ to->hdr->nsections = from->hdr->nsections;
+ to->hdr->flags = from->hdr->flags;
+ /* Copy bitmap */
+ memcpy(to->bitmap, from->bitmap, from->hdr->nblocks >> 3);
+ /* Copy data */
+ memcpy(to->data, from->data, from->hdr->nblocks * from->hdr->blksize);
+}
+
+
+static apr_status_t open_bitmap_segment(asmm_mem_data_t **bmp,
+ const char *name,
+ apr_pool_t *ctx)
+{
+ apr_byte_t *data;
+ apr_status_t rv;
+
+ apr_shm_t *shm = NULL;
+
+ if ((rv = apr_shm_attach(&shm, name, ctx)) != APR_SUCCESS) {
+ *bmp = NULL;
+ return rv;
+ }
+ *bmp = (asmm_mem_data_t *)apr_palloc(ctx, sizeof(asmm_mem_data_t));
+ data = (apr_byte_t *)apr_shm_baseaddr_get(shm);
+
+ (*bmp)->shm = shm;
+ (*bmp)->hdr = (asmm_shm_data_t *)data;
+ (*bmp)->bitmap = data + sizeof(asmm_shm_data_t);
+ (*bmp)->data = (*bmp)->bitmap + (APR_ALIGN((*bmp)->hdr->nblocks, 64) >> 3);
+ (*bmp)->next = NULL;
+ (*bmp)->name = apr_pstrdup(ctx, name);
+
+ if ((*bmp)->hdr->flags & ASMM_DIRTY) {
+ /* Memory is dirty probably already closed by parent */
+ apr_shm_destroy(shm);
+ *bmp = NULL;
+ return APR_EBADF;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t new_slotmem_segment(asmm_slotmem_t *mem)
+{
+ apr_status_t rv;
+ asmm_mem_data_t *bmp, *p;
+ char sname[APR_PATH_MAX];
+
+ if (mem->nsections + 1 > mem->maxsections)
+ return APR_EOF;
+ sprintf(sname, "%s.%03d", mem->prefix, mem->nsections);
+
+ if ((rv = create_bitmap_segment(&bmp, mem->blksize,
+ mem->nblocks, sname,
+ mem->pool)) != APR_SUCCESS)
+ return rv;
+ bmp->hdr->section = mem->nsections++;
+ bmp->hdr->flags = mem->flags;
+ bmp->hdr->timestamp = apr_time_now();
+ if (mem->timestamp == bmp->hdr->timestamp) {
+ /* Make sure they are always different
+ */
+ bmp->hdr->timestamp++;
+ mem->timestamp = bmp->hdr->timestamp;
+ }
+ else
+ mem->timestamp = bmp->hdr->timestamp;
+ mem->sections->hdr->nsections = mem->nsections;
+ /* Put the segment to the end of list */
+ for (p = mem->sections; p; p = p->next) {
+ p->hdr->timestamp = mem->timestamp;
+ if (p->next == NULL) {
+ p->next = bmp;
+ break;
+ }
+ }
+ return rv;
+}
+
+static apr_status_t add_slotmem_segment(asmm_slotmem_t *mem)
+{
+ apr_status_t rv;
+ apr_uint16_t n;
+ asmm_mem_data_t *bmp = NULL;
+ asmm_mem_data_t *p = NULL;
+ char sname[APR_PATH_MAX];
+
+ for (n = mem->nsections; n < mem->sections->hdr->nsections; n++) {
+ sprintf(sname, "%s.%03d", mem->prefix, n);
+ if ((rv = open_bitmap_segment(&bmp, sname, mem->pool)) != APR_SUCCESS)
+ return rv;
+ mem->timestamp = bmp->hdr->timestamp;
+ mem->nsections++;
+ if (p && p->next == NULL) {
+ p->next = bmp;
+ p = bmp;
+ continue;
+ }
+ /* Put the segment to the end of list */
+ for (p = mem->sections; p; p = p->next) {
+ if (p->next == NULL) {
+ p->next = bmp;
+ break;
+ }
+ }
+ }
+ return rv;
+}
+
+apr_status_t asmm_slotmem_create(asmm_slotmem_t **mem,
+ const char *name,
+ apr_uint32_t blksize,
+ apr_uint32_t nblocks,
+ apr_uint16_t flags,
+ apr_uint16_t maxsections,
+ apr_pool_t *ctx)
+{
+ apr_status_t rv;
+ asmm_mem_data_t *bmp;
+ char sname[APR_PATH_MAX];
+
+ strcpy(sname, name);
+ strcat(sname, ".000");
+ if ((rv = create_bitmap_segment(&bmp, blksize,
+ nblocks, sname, ctx)) != APR_SUCCESS) {
+ *mem = NULL;
+ return rv;
+ }
+ *mem = (asmm_slotmem_t *)apr_palloc(ctx, sizeof(asmm_slotmem_t));
+ (*mem)->prefix = apr_pstrdup(ctx, name);
+ (*mem)->blksize = bmp->hdr->blksize;
+ (*mem)->nblocks = bmp->hdr->nblocks;
+ (*mem)->nsections = bmp->hdr->nsections = 1;
+ (*mem)->flags = bmp->hdr->flags = flags;
+ (*mem)->timestamp = bmp->hdr->timestamp = apr_time_now();
+ (*mem)->maxsections = maxsections;
+ (*mem)->pool = ctx;
+ (*mem)->sections = bmp;
+ (*mem)->timeout = ASMM_WAIT_INTERVAL * ASMM_WAIT_LOOPS;
+ (*mem)->pflags = ASMM_OWNER;
+ (*mem)->lock = NULL;
+
+ return rv;
+}
+
+apr_status_t asmm_slotmem_close(asmm_slotmem_t *mem)
+{
+ if (mem)
+ return slotmem_cleanup(mem);
+ else
+ return APR_EINVAL;
+}
+
+apr_status_t asmm_slotmem_open(asmm_slotmem_t **mem, const char *name,
+ apr_pool_t *ctx)
+{
+ apr_uint32_t i;
+ apr_status_t rv;
+ asmm_mem_data_t *bmp;
+ char sname[APR_PATH_MAX];
+
+ strcpy(sname, name);
+ strcat(sname, ".000");
+ if ((rv = open_bitmap_segment(&bmp, sname, ctx)) != APR_SUCCESS) {
+ *mem = NULL;
+ return rv;
+ }
+ *mem = (asmm_slotmem_t *)apr_palloc(ctx, sizeof(asmm_slotmem_t));
+ (*mem)->prefix = apr_pstrdup(ctx, name);
+ (*mem)->blksize = bmp->hdr->blksize;
+ (*mem)->nblocks = bmp->hdr->nblocks;
+ (*mem)->nsections = bmp->hdr->nsections;
+ (*mem)->timestamp = bmp->hdr->timestamp;
+ (*mem)->maxsections = 0;
+ (*mem)->pool = ctx;
+ (*mem)->sections = bmp;
+ (*mem)->timeout = ASMM_WAIT_INTERVAL * ASMM_WAIT_LOOPS;
+ (*mem)->pflags = 0;
+ (*mem)->lock = NULL;
+
+ for (i = 1; i < (*mem)->nsections; i++) {
+ asmm_mem_data_t *sec;
+ sprintf(sname, "%s.%03d", name, i);
+ if ((rv = open_bitmap_segment(&sec, sname, ctx)) == APR_SUCCESS) {
+ bmp->next = sec;
+ bmp = sec;
+ }
+ else {
+ /* One of the segments is missing? */
+ slotmem_cleanup(*mem);
+ *mem = NULL;
+ return APR_EBADF;
+ }
+ }
+ return rv;
+}
+
+apr_status_t asmm_slotmem_copy(asmm_slotmem_t **mem, asmm_slotmem_t *org,
+ const char *name, apr_pool_t *ctx)
+{
+ apr_uint32_t i = 1;
+ apr_status_t rv;
+ asmm_mem_data_t *bmp;
+ asmm_mem_data_t *sec;
+ asmm_mem_data_t *ptr = org->sections;
+ char sname[APR_PATH_MAX];
+
+ strcpy(sname, name);
+ strcat(sname, ".000");
+ if ((rv = create_bitmap_segment(&bmp, ptr->hdr->blksize,
+ ptr->hdr->nblocks,
+ sname, ctx)) != APR_SUCCESS) {
+ *mem = NULL;
+ return rv;
+ }
+ copy_bitmap_segment(bmp, org->sections);
+ *mem = (asmm_slotmem_t *)apr_palloc(ctx, sizeof(asmm_slotmem_t));
+ (*mem)->prefix = name;
+ (*mem)->blksize = bmp->hdr->blksize;
+ (*mem)->nblocks = bmp->hdr->nblocks;
+ (*mem)->timestamp = bmp->hdr->timestamp;
+ (*mem)->nsections = org->nsections;
+ (*mem)->maxsections = org->maxsections;
+ (*mem)->pool = ctx;
+ (*mem)->sections = bmp;
+ (*mem)->timeout = org->timeout;
+ (*mem)->pflags = ASMM_OWNER;
+ (*mem)->lock = NULL;
+
+ ptr = ptr->next;
+ while (ptr) {
+ sprintf(sname, "%s.%03d", name, i);
+ if ((rv = create_bitmap_segment(&sec, (*mem)->blksize,
+ (*mem)->nblocks, sname,
+ (*mem)->pool)) != APR_SUCCESS) {
+ /* One of the segments cannot be created */
+ slotmem_cleanup(*mem);
+ *mem = NULL;
+ return APR_EBADF;
+ }
+ copy_bitmap_segment(sec, ptr);
+ bmp->next = sec;
+ bmp = sec;
+ ptr = ptr->next;
+ }
+ return rv;
+}
+
+void asmm_slotmem_lock_set(asmm_slotmem_t *mem,
+ apr_global_mutex_t *lock)
+{
+ mem->lock = lock;
+}
+
+void asmm_slotmem_timeout_set(asmm_slotmem_t *mem,
+ apr_interval_time_t timeout)
+{
+ mem->timeout = timeout;
+}
+
+apr_global_mutex_t *asmm_slotmem_lock_get(asmm_slotmem_t *mem)
+{
+ return mem->lock;
+}
+
+apr_status_t asmm_slotmem_lock(asmm_slotmem_t *mem)
+{
+ if (mem->lock)
+ return apr_global_mutex_lock(mem->lock);
+ else
+ return APR_SUCCESS;
+}
+
+apr_status_t asmm_slotmem_unlock(asmm_slotmem_t *mem)
+{
+ if (mem->lock)
+ return apr_global_mutex_unlock(mem->lock);
+ else
+ return APR_SUCCESS;
+}
+
+apr_status_t asmm_slotmem_maintain(asmm_slotmem_t *mem)
+{
+ apr_status_t rv = APR_SUCCESS;
+ if (mem && mem->sections->hdr->flags & ASMM_NEW_SECTION) {
+ if (mem->lock)
+ (void)apr_global_mutex_lock(mem->lock);
+ rv = new_slotmem_segment(mem);
+ mem->sections->hdr->flags &= ~ASMM_NEW_SECTION;
+ if (mem->lock)
+ (void)apr_global_mutex_unlock(mem->lock);
+ }
+ return rv;
+}
+
+void *asmm_malloc(asmm_slotmem_t *mem, apr_size_t size)
+{
+ apr_status_t rv;
+ apr_size_t sza;
+ apr_uint32_t n, p;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ if ((bmp->hdr->flags & ASMM_DYNAMIC) != ASMM_DYNAMIC) {
+ apr_set_os_error(APR_EINVAL);
+ return NULL;
+ }
+
+ sza = APR_ALIGN(size + sizeof(asmm_mem_node_t), mem->blksize);
+ n = sza / mem->blksize;
+ if (n > mem->nblocks) {
+ /* Segment overflow.
+ * Adjust the memory so that largest
+ * alloc size can fit inside a single Segment
+ */
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ _ASMM_LOCK(mem);
+ while (bmp) {
+ if (asmm_bmp_find(bmp->bitmap, bmp->hdr->nblocks,
+ n, &p) == APR_SUCCESS) {
+ data = bmp->data + p * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ node->refcount = 0;
+ node->size = n;
+ asmm_bmp_set(bmp->bitmap, p, p + n);
+ break;
+ }
+ bmp = bmp->next;
+ }
+ if (data) {
+ /* Slotmem is modified */
+ mem->timestamp = apr_time_now();
+ while (bmp) {
+ bmp->hdr->timestamp = mem->timestamp;
+ bmp = bmp->next;
+ }
+ }
+ _ASMM_UNLOCK(mem);
+ if (data) {
+ return data + sizeof(asmm_mem_node_t);
+ }
+ else {
+ if (!mem->maxsections) {
+ apr_interval_time_t i;
+ /* Add new segment request
+ */
+ mem->sections->hdr->flags |= ASMM_NEW_SECTION;
+ /* TODO: Wait for flag to be cleared
+ * and then try again.
+ * This is 1000 * 10ms maximum delay (10 sec)
+ */
+ for (i = 0; i < mem->timeout; i += ASMM_WAIT_INTERVAL) {
+ apr_sleep(ASMM_WAIT_INTERVAL);
+ if (mem->sections->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ if ((mem->sections->hdr->flags & ASMM_NEW_SECTION) !=
+ ASMM_NEW_SECTION) {
+ _ASMM_LOCK(mem);
+ add_slotmem_segment(mem);
+ _ASMM_UNLOCK(mem);
+ break;
+ }
+ }
+ if (mem->sections->hdr->flags & ASMM_NEW_SECTION) {
+ apr_set_os_error(APR_TIMEUP);
+ return NULL;
+ }
+ }
+ else if (mem->nsections + 1 > mem->maxsections) {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ else {
+ _ASMM_LOCK(mem);
+ if ((rv = new_slotmem_segment(mem)) != APR_SUCCESS) {
+ _ASMM_UNLOCK(mem);
+ apr_set_os_error(rv);
+ return NULL;
+ }
+ mem->sections->hdr->flags &= ~ASMM_NEW_SECTION;
+ _ASMM_UNLOCK(mem);
+ }
+ _ASMM_LOCK(mem);
+ bmp = mem->sections;
+ while (bmp) {
+ if (asmm_bmp_find(bmp->bitmap, bmp->hdr->nblocks,
+ n, &p) == APR_SUCCESS) {
+ data = bmp->data + p * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ node->refcount = 0;
+ node->size = n;
+ asmm_bmp_set(bmp->bitmap, p, p + n);
+ break;
+ }
+ bmp = bmp->next;
+ }
+ _ASMM_UNLOCK(mem);
+ if (data) {
+ return data + sizeof(asmm_mem_node_t);
+ }
+ else {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ }
+}
+
+void *asmm_salloc_ex(asmm_slotmem_t *mem, apr_uint32_t *slot)
+{
+ apr_status_t rv;
+ apr_uint32_t p;
+ apr_uint32_t sn = 1;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ _ASMM_LOCK(mem);
+
+ while (bmp) {
+ if (asmm_bmp_get(bmp->bitmap, bmp->hdr->nblocks,
+ &p) == APR_SUCCESS) {
+ data = bmp->data + p * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->refcount == ASMM_DEAD_COOKIE) {
+ /* Clear old memory */
+ memset(data, 0, bmp->hdr->blksize);
+ }
+ node->size = 1;
+ asmm_bmp_set(bmp->bitmap, p, p + 1);
+ *slot = p * sn;
+ break;
+ }
+ sn++;
+ bmp = bmp->next;
+ }
+ if (data) {
+ /* Slotmem is modified */
+ mem->timestamp = apr_time_now();
+ while (bmp) {
+ bmp->hdr->timestamp = mem->timestamp;
+ bmp = bmp->next;
+ }
+ }
+ _ASMM_UNLOCK(mem);
+ if (data) {
+ return data + sizeof(asmm_mem_node_t);
+ }
+ else {
+ if (!mem->maxsections) {
+ apr_interval_time_t i;
+ /* Add new segment request
+ */
+ mem->sections->hdr->flags |= ASMM_NEW_SECTION;
+ /* TODO: Wait for flag to be cleared
+ * and then try again.
+ * This is 1000 * 10ms maximum delay (10 sec)
+ */
+ for (i = 0; i < mem->timeout; i += ASMM_WAIT_INTERVAL) {
+ apr_sleep(ASMM_WAIT_INTERVAL);
+ if (mem->sections->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ if ((mem->sections->hdr->flags & ASMM_NEW_SECTION) !=
+ ASMM_NEW_SECTION) {
+ _ASMM_LOCK(mem);
+ add_slotmem_segment(mem);
+ _ASMM_UNLOCK(mem);
+ break;
+ }
+ }
+ if (mem->sections->hdr->flags & ASMM_NEW_SECTION) {
+ apr_set_os_error(APR_TIMEUP);
+ return NULL;
+ }
+ }
+ else if (mem->nsections + 1 > mem->maxsections) {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ else {
+ _ASMM_LOCK(mem);
+ if ((rv = new_slotmem_segment(mem)) != APR_SUCCESS) {
+ _ASMM_UNLOCK(mem);
+ apr_set_os_error(rv);
+ return NULL;
+ }
+ mem->sections->hdr->flags &= ~ASMM_NEW_SECTION;
+ _ASMM_UNLOCK(mem);
+ }
+ sn = 1;
+ _ASMM_LOCK(mem);
+ bmp = mem->sections;
+ while (bmp) {
+ if (asmm_bmp_get(bmp->bitmap, bmp->hdr->nblocks,
+ &p) == APR_SUCCESS) {
+ data = bmp->data + p * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->refcount == ASMM_DEAD_COOKIE) {
+ /* Clear old memory */
+ memset(data, 0, bmp->hdr->blksize);
+ }
+ node->size = 1;
+ asmm_bmp_set(bmp->bitmap, p, p + 1);
+ *slot = p * sn;
+ break;
+ }
+ sn++;
+ bmp = bmp->next;
+ }
+ _ASMM_UNLOCK(mem);
+ if (data) {
+ return data + sizeof(asmm_mem_node_t);
+ }
+ else {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ }
+}
+
+void *asmm_salloc(asmm_slotmem_t *mem)
+{
+ apr_uint32_t unused;
+ return asmm_salloc_ex(mem, &unused);
+}
+
+void asmm_free(asmm_slotmem_t *mem, void *p)
+{
+ apr_byte_t *data;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return;
+ }
+
+ data = (apr_byte_t *)p - sizeof(asmm_mem_node_t);
+ node = (asmm_mem_node_t *)data;
+ if (node->refcount) {
+ /* memory is still referenced */
+ if (node->refcount != ASMM_DEAD_COOKIE) {
+ node->refcount--;
+ apr_set_os_error(APR_EBUSY);
+ }
+ else
+ apr_set_os_error(APR_ENOENT);
+ return;
+ }
+ _ASMM_VLOCK(mem);
+ while (bmp) {
+ if (data >= bmp->data &&
+ data < bmp->data + bmp->hdr->blksize * bmp->hdr->nblocks) {
+ apr_uint32_t pos = (data - bmp->data) / bmp->hdr->blksize;
+ asmm_bmp_clr(bmp->bitmap, pos, pos + node->size);
+ node->size = 0;
+ node->refcount = ASMM_DEAD_COOKIE;
+ break;
+ }
+ bmp = bmp->next;
+ }
+ /* Slotmem is modified */
+ mem->timestamp = apr_time_now();
+ while (bmp) {
+ bmp->hdr->timestamp = mem->timestamp;
+ bmp = bmp->next;
+ }
+ _ASMM_UNLOCK(mem);
+}
+
+void asmm_memref(void *p, int on)
+{
+ apr_byte_t *data = (apr_byte_t *)p;
+ asmm_mem_node_t *node;
+
+ node = (asmm_mem_node_t *)(data - sizeof(asmm_mem_node_t));
+ if (node->refcount != ASMM_DEAD_COOKIE) {
+ if (on)
+ node->refcount++;
+ else if (node->refcount)
+ node->refcount--;
+ }
+}
+
+int asmm_memsize(void *p)
+{
+ apr_byte_t *data = (apr_byte_t *)p;
+ asmm_mem_node_t *node;
+
+ node = (asmm_mem_node_t *)(data - sizeof(asmm_mem_node_t));
+ if (node->refcount != ASMM_DEAD_COOKIE)
+ return node->size;
+ else
+ return 0;
+}
+
+void *asmm_slot(asmm_slotmem_t *mem, apr_uint32_t slot)
+{
+ apr_uint32_t section = 1;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp;
+
+ if (!mem) {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ bmp = mem->sections;
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ if (slot < section * bmp->hdr->nblocks) {
+ data = bmp->data + (slot - (section - 1) * bmp->hdr->nblocks) * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size)
+ return data + sizeof(asmm_mem_node_t);
+ else {
+ apr_set_os_error(APR_EINIT);
+ return NULL;
+ }
+ }
+ bmp = bmp->next;
+ section++;
+ }
+ apr_set_os_error(APR_ESYMNOTFOUND);
+ return NULL;
+}
+
+void *asmm_slot_next(asmm_slotmem_t *mem, apr_uint32_t *next)
+{
+ apr_uint32_t i, section = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ for (i = *next - section * bmp->hdr->nblocks;
+ i < (section + 1) * bmp->hdr->nblocks; i++) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size) {
+ *next = i + 1 + section * bmp->hdr->nblocks;
+ return data + sizeof(asmm_mem_node_t);
+ }
+ }
+ bmp = bmp->next;
+ section++;
+ }
+ apr_set_os_error(APR_EOF);
+ return NULL;
+}
+
+void *asmm_memory(asmm_slotmem_t *mem, apr_uint32_t index)
+{
+ apr_uint32_t i, idx = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks; idx++) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (idx == index)
+ break;
+ if (node->size)
+ i += node->size;
+ else
+ i++;
+ }
+ if (data)
+ break;
+ bmp = bmp->next;
+ }
+ if (data)
+ return data + sizeof(asmm_mem_node_t);
+ else {
+ apr_set_os_error(APR_ESYMNOTFOUND);
+ return NULL;
+ }
+}
+
+static void **create_slot_array(asmm_slotmem_t *mem, apr_size_t *size,
+ apr_pool_t *ctx)
+{
+
+ apr_uint32_t i, x = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+ void **a = NULL;
+
+ a = (void **)apr_pcalloc(ctx, sizeof(void *) *
+ (mem->nsections * bmp->hdr->nblocks + 1));
+
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks; i++, x++) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ a[x] = data + sizeof(asmm_mem_node_t);
+ }
+ bmp = bmp->next;
+ }
+ *size = x;
+ return a;
+}
+
+static void **create_memory_array(asmm_slotmem_t *mem, apr_size_t *size,
+ apr_pool_t *ctx)
+{
+
+ apr_uint32_t i, x = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp = mem->sections;
+ void **a = NULL;
+
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks;) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size) {
+ i += node->size;
+ x++;
+ }
+ else
+ i++;
+ }
+ bmp = bmp->next;
+ }
+ a = (void **)apr_pcalloc(ctx, sizeof(void *) * (x + 1));
+ bmp = mem->sections;
+ x = 0;
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks;) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size) {
+ i += node->size;
+ a[x++] = data + sizeof(asmm_mem_node_t);
+ }
+ else
+ i++;
+ }
+ bmp = bmp->next;
+ }
+ *size = x;
+ return a;
+}
+
+void **asmm_aalloc(asmm_slotmem_t *mem, apr_size_t *size, apr_pool_t *ctx)
+{
+ if (mem->flags & ASMM_DYNAMIC)
+ return create_memory_array(mem, size, ctx);
+ else
+ return create_slot_array(mem, size, ctx);
+}
+
+apr_uint32_t asmm_slotmem_free_get(asmm_slotmem_t *mem)
+{
+ apr_uint32_t cnt = 0;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return 0;
+ }
+ while (bmp) {
+ cnt += asmm_bmp_free(bmp->bitmap, bmp->hdr->nblocks);
+ bmp = bmp->next;
+ }
+ return cnt;
+}
+
+apr_uint32_t asmm_slotmem_used_get(asmm_slotmem_t *mem)
+{
+ apr_uint32_t num = 0, cnt = 0;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return 0;
+ }
+ while (bmp) {
+ num += bmp->hdr->nblocks;
+ cnt += asmm_bmp_free(bmp->bitmap, bmp->hdr->nblocks);
+ bmp = bmp->next;
+ }
+ return (num - cnt);
+}
+
+apr_size_t asmm_slotmem_overhead_get()
+{
+ return sizeof(asmm_mem_node_t);
+}
+
+apr_size_t asmm_slotmem_slotsize_get(asmm_slotmem_t *mem)
+{
+ if (mem->sections)
+ return mem->sections->hdr->blksize;
+ else
+ return 0;
+}
+
+int asmm_slotmem_is_modified(asmm_slotmem_t *mem)
+{
+ if (mem->sections && mem->sections->hdr->timestamp != mem->timestamp)
+ return 1;
+ else
+ return 0;
+}
+
+void asmm_slotmem_set_modified(asmm_slotmem_t *mem)
+{
+ asmm_mem_data_t *bmp = mem->sections;
+ apr_time_t now = apr_time_now();
+
+ while (bmp) {
+ bmp->hdr->timestamp = now;
+ bmp = bmp->next;
+ }
+ mem->timestamp = now;
+}
+
+void asmm_slotmem_sync_modified(asmm_slotmem_t *mem)
+{
+ if (mem->sections)
+ mem->timestamp = mem->sections->hdr->timestamp;
+}
+
+void asmm_slotmem_set_dirty(asmm_slotmem_t *mem)
+{
+ asmm_mem_data_t *bmp = mem->sections;
+
+ while (bmp) {
+ bmp->hdr->flags |= ASMM_DIRTY;
+ bmp = bmp->next;
+ }
+}
+
+void asmm_slotmem_clr_dirty(asmm_slotmem_t *mem)
+{
+ asmm_mem_data_t *bmp = mem->sections;
+
+ while (bmp) {
+ bmp->hdr->flags &= ~ASMM_DIRTY;
+ bmp = bmp->next;
+ }
+}
+
+void *asmm_slotmem_section_base_get(asmm_slotmem_t *mem, apr_uint32_t section)
+{
+ apr_uint32_t sn = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_data_t *bmp = mem->sections;
+
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ if (sn == section) {
+ return bmp->data;
+ }
+ bmp = bmp->next;
+ sn++;
+ }
+ apr_set_os_error(APR_ESYMNOTFOUND);
+ return NULL;
+}
+
+apr_uint32_t asmm_slotmem_sections_get(asmm_slotmem_t *mem)
+{
+ return mem->nsections;
+}
+
+void *asmm_slot_search(asmm_slotmem_t *mem,
+ const char *key, int icase,
+ apr_size_t key_offset,
+ apr_uint32_t *slot)
+{
+ apr_uint32_t i, section = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp;
+
+ if (!mem) {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ bmp = mem->sections;
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks; i++) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size) {
+ const char *s = data + sizeof(asmm_mem_node_t) + key_offset;
+ if (icase ? !strcasecmp(s, key) : !strcmp(s, key)) {
+ if (slot)
+ *slot = i + section * bmp->hdr->nblocks;
+ return data + sizeof(asmm_mem_node_t);
+ }
+ }
+ }
+ bmp = bmp->next;
+ section++;
+ }
+ apr_set_os_error(APR_EOF);
+ return NULL;
+}
+
+void *asmm_slot_match(asmm_slotmem_t *mem,
+ const char *key, int icase,
+ apr_size_t key_offset,
+ apr_uint32_t *slot)
+{
+ apr_uint32_t i, section = 0;
+ apr_byte_t *data = NULL;
+ asmm_mem_node_t *node;
+ asmm_mem_data_t *bmp;
+ int mf = icase ? APR_FNM_CASE_BLIND : 0;
+
+ if (!mem) {
+ apr_set_os_error(APR_ENOMEM);
+ return NULL;
+ }
+ bmp = mem->sections;
+ if (bmp && bmp->hdr->flags & ASMM_DIRTY) {
+ apr_set_os_error(APR_EBADF);
+ return NULL;
+ }
+ while (bmp) {
+ for (i = 0; i < bmp->hdr->nblocks; i++) {
+ data = bmp->data + i * bmp->hdr->blksize;
+ node = (asmm_mem_node_t *)data;
+ if (node->size) {
+ const char *s = data + sizeof(asmm_mem_node_t) + key_offset;
+ if (*s == '~' && apr_fnmatch(s + 1, key, mf) == APR_SUCCESS) {
+ if (slot)
+ *slot = i + section * bmp->hdr->nblocks;
+ return data + sizeof(asmm_mem_node_t);
+ }
+ }
+ }
+ bmp = bmp->next;
+ section++;
+ }
+ apr_set_os_error(APR_EOF);
+ return NULL;
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_asmm.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_asmm.h
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_asmm.h (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_asmm.h 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,361 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#ifndef MM_ASMM_H
+#define MM_ASMM_H
+
+/**
+ * @file mm_asmm.h
+ * @brief Advanced shared memory
+ */
+/**
+ * @defgroup MM_ASMM shared memory routines
+ * @ingroup Manager
+ * @{
+ */
+
+
+#include "apr.h"
+#include "apr_general.h"
+#include "apr_strings.h"
+#include "apr_fnmatch.h"
+#include "apr_shm.h"
+#include "apr_time.h"
+#include "apr_global_mutex.h"
+#include "apr_thread_proc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ASMM_DYNAMIC 0x0001
+#define ASMM_NEW_SECTION 0x0002
+#define ASMM_DIRTY 0x0004
+#define ASMM_HAS_LOCK 0x0008
+#define ASMM_OWN_LOCK 0x0010
+#define ASMM_UNLIMITED 0xFFFF
+#define ASMM_OWNER 0x0001
+#define ASMM_WAIT_INTERVAL APR_TIME_C(10000)
+#define ASMM_WAIT_LOOPS 1000
+
+
+/**
+ * Structure for referencing slot memory.
+ */
+typedef struct asmm_slotmem_t asmm_slotmem_t;
+
+/**
+ * Create shared slot memory.
+ * @param mem The newly created slotmem descriptor.
+ * @param name The full path to the backup file prefix
+ * (using / on all systems)
+ * @param blksize Size of each slot (rounded to 8 bytes)
+ * @param nblocks Maximum number of slots (rounded to 8 slots)
+ * @param flags Or'ed value of:
+ * <PRE>
+ * ASMM_DYNAMIC allow large slots
+ * ASMM_HAS_LOCK create global lock mutex
+ * </PRE>
+ * @param maxsections Maximum number of sections that can
+ * be dynamically created. If 0 the memory is not
+ * resizable. For maximum allowable use ASMM_UNLIMITED.
+ * @param ctx The pool to use.
+ */
+apr_status_t asmm_slotmem_create(asmm_slotmem_t **mem,
+ const char *name,
+ apr_uint32_t blksize,
+ apr_uint32_t nblocks,
+ apr_uint16_t flags,
+ apr_uint16_t maxsections,
+ apr_pool_t *ctx);
+
+/**
+ * Close the specified slotmem.
+ * @param mem The slotmem descriptor to close.
+ * @remark If the slotmem descriptor is the one obrained
+ * by creating slotmem the attached shared memory
+ * will be marked as ASMM_DIRTY. Subsequent alloc
+ * requests will fail with APR_EBADF error.
+ */
+apr_status_t asmm_slotmem_close(asmm_slotmem_t *mem);
+
+/**
+ * Open shared slot memory.
+ * @param mem The opened slotmem descriptor.
+ * @param name The full path to the backup file prefix
+ * (using / on all systems). The same as used
+ * for asmm_create_slotmem.
+ * @param ctx The pool to use.
+ */
+apr_status_t asmm_slotmem_open(asmm_slotmem_t **mem, const char *name,
+ apr_pool_t *ctx);
+
+/**
+ * Copy shared memory.
+ * @param mem The newly created slotmem descriptor.
+ * @param org The slotmem to copy from.
+ * @param name The full path to the backup file prefix
+ * (using / on all systems)
+ * @param ctx The pool to use.
+ */
+apr_status_t asmm_slotmem_copy(asmm_slotmem_t **mem, asmm_slotmem_t *org,
+ const char *name, apr_pool_t *ctx);
+
+/**
+ * Set allocation timeout.
+ * @param mem The slotmem descriptor to set.
+ * @param timeout Timeout in microseconds.
+ * @remark When child tries to allocate the memory
+ * and cannot obtain enough free memory it sets
+ * the ASMM_NEW_SECTION flag and waits up to timeout
+ * for a new slotmem segment to be created by the parent.
+ * Default timeout value is 10 seconds.
+ */
+void asmm_slotmem_timeout_set(asmm_slotmem_t *mem,
+ apr_interval_time_t timeout);
+
+/**
+ * Set global lock mutex.
+ * @param mem The slotmem descriptor to set.
+ * @param lock Mutex to use.
+ */
+void asmm_slotmem_lock_set(asmm_slotmem_t *mem,
+ apr_global_mutex_t *lock);
+
+/**
+ * Get global lock mutex.
+ * @param mem The slotmem descriptor to get.
+ */
+apr_global_mutex_t *asmm_slotmem_lock_get(asmm_slotmem_t *mem);
+
+/**
+ * Lock the slotmem.
+ * @param mem The slotmem descriptor to lock.
+ */
+apr_status_t asmm_slotmem_lock(asmm_slotmem_t *mem);
+
+/**
+ * Unlock previously locked slotmem.
+ * @param mem The slotmem descriptor to unlock.
+ */
+apr_status_t asmm_slotmem_unlock(asmm_slotmem_t *mem);
+
+/**
+ * Maintain slotmem.
+ * @param mem The slotmem descriptor to use.
+ * @remark Function will add new slotmem segment if
+ * ASMM_NEW_SECTION flag was set
+ */
+apr_status_t asmm_slotmem_maintain(asmm_slotmem_t *mem);
+
+/**
+ * Allocate memory.
+ * @param mem The slotmem descriptor to allocate from.
+ * @param size The memory size to allocate.
+ * @remark The memory must be created with ASMM_DYNAMIC flag
+ * or this call will return NULL and set errno to APR_EINVAL
+ *
+ * @remark If the memory was closed by creator the
+ * return value is NULL errno is set to APR_EBADF
+ *
+ * @remark If there was not enough free memory to satisfy the
+ * requested size the call will wait up to timeout
+ * microseconds for creator to create a new memory segment.
+ * If creator fails to do that within timeout the return
+ * value is NULL and errno is set to APR_TIMEUP.
+ */
+void *asmm_malloc(asmm_slotmem_t *mem, apr_size_t size);
+
+
+/**
+ * Allocate one memory slot
+ * @param mem The slotmem descriptor to allocate from.
+ * @param slot The slot number allocated.
+ * @remark If the memory was closed by creator the
+ * return value is NULL errno is set to APR_EBADF
+ *
+ * @remark If there was not enough free memory for a slot
+ * the call will wait up to timeout
+ * microseconds for creator to create a new memory segment.
+ * If creator fails to do that within timeout the return
+ * value is NULL and errno is set to APR_TIMEUP.
+ */
+void *asmm_salloc_ex(asmm_slotmem_t *mem, apr_uint32_t *slot);
+
+/**
+ * Allocate one memory slot
+ * @param mem The slotmem descriptor to allocate from.
+ * @remark If the memory was closed by creator the
+ * return value is NULL errno is set to APR_EBADF
+ *
+ * @remark If there was not enough free memory for a slot
+ * the call will wait up to timeout
+ * microseconds for creator to create a new memory segment.
+ * If creator fails to do that within timeout the return
+ * value is NULL and errno is set to APR_TIMEUP.
+ */
+void *asmm_salloc(asmm_slotmem_t *mem);
+
+/**
+ * Deallocate previously allocated memory
+ * @param mem The slotmem descriptor to use.
+ * @param p Memory previously allocated by calling asmm_malloc
+ * or asmm_salloc.
+ * @remark Memory will be actually deallocated when its reference
+ * count is zero
+ */
+void asmm_free(asmm_slotmem_t *mem, void *p);
+
+/**
+ * Reference or derefrence allocated memory.
+ * @param p Memory previously allocated by calling asmm_malloc
+ * or asmm_salloc.
+ * @param on If non zero reference the memory. If zero dereference
+ * the memory
+ */
+void asmm_memref(void *p, int on);
+
+/**
+ * Return the memory slot size in number of slots
+ * @param p Memory previously allocated by calling asmm_malloc
+ * or asmm_salloc.
+ * @remark If memory was deallocated the returned size is 0
+ */
+int asmm_memsize(void *p);
+
+/**
+ * Get memory slot address
+ * @param mem The slotmem descriptor to use.
+ * @param slot Slot number
+ */
+void *asmm_slot(asmm_slotmem_t *mem, apr_uint32_t slot);
+
+/**
+ * Get next memory slot address
+ * @param mem The slotmem descriptor to use.
+ * @param next Start/next slot number.
+ * @remark On return next points to slot number + 1.
+ */
+void *asmm_slot_next(asmm_slotmem_t *mem, apr_uint32_t *next);
+
+/**
+ * Search for memory slot address
+ * @param mem The slotmem descriptor to use.
+ * @param key The memory key to find.
+ * @param icase Case insensitive searc if non zero.
+ * @param key_off Key offset in allocated memory.
+ * @param slot On success the slot number.
+ */
+void *asmm_slot_search(asmm_slotmem_t *mem, const char *key,
+ int icase,
+ apr_size_t key_offset,
+ apr_uint32_t *slot);
+
+/**
+ * Get memory address
+ * @param mem The slotmem descriptor to use.
+ * @param index Allocated memory index
+ */
+void *asmm_memory(asmm_slotmem_t *mem, apr_uint32_t index);
+
+/**
+ * Create array of allocated memory slots
+ * @param mem The slotmem descriptor to use.
+ * @param size Return array size
+ * @param ctx Pool to allocate from
+ * @remark Each item of the returned array points to
+ * to the allocated memory slot.
+ */
+void **asmm_aalloc(asmm_slotmem_t *mem, apr_size_t *size, apr_pool_t *ctx);
+
+/**
+ * Return number of free blocks.
+ * @param mem The slotmem descriptor to use.
+ */
+apr_uint32_t asmm_slotmem_free_get(asmm_slotmem_t *mem);
+
+/**
+ * Return number of used blocks.
+ * @param mem The slotmem descriptor to use.
+ */
+apr_uint32_t asmm_slotmem_used_get(asmm_slotmem_t *mem);
+
+/**
+ * Return the overhead for each slot in slotmem.
+ */
+apr_size_t asmm_slotmem_overhead_get();
+
+/**
+ * Return the size of each slot
+ * @param mem The slotmem descriptor to use.
+ */
+apr_uint32_t asmm_slotmem_slotsize_get(asmm_slotmem_t *mem);
+
+/**
+ * Return the section base address
+ * @param mem The slotmem descriptor to use.
+ * @param section Section number.
+ */
+void *asmm_slotmem_section_base_get(asmm_slotmem_t *mem, apr_uint32_t section);
+
+/**
+ * Return non zero if shared memory is modified
+ * @param mem The slotmem descriptor to use.
+ * @remark Function compares in-memory with shared memory timestamps
+ * and returns non zero if they are different.
+ */
+int asmm_slotmem_is_modified(asmm_slotmem_t *mem);
+
+/**
+ * Synchronise and set shared memory modification timestamps
+ * @param mem The slotmem descriptor to use.
+ */
+void asmm_slotmem_set_modified(asmm_slotmem_t *mem);
+
+/**
+ * Synchronise shared memory modification timestamps
+ * @param mem The slotmem descriptor to use.
+ */
+void asmm_slotmem_sync_modified(asmm_slotmem_t *mem);
+
+/**
+ * Return the number of sections
+ * @param mem The slotmem descriptor to use.
+ */
+apr_uint32_t asmm_slotmem_sections_get(asmm_slotmem_t *mem);
+
+/**
+ * Set unix security permissions.
+ * @param fname Shared memory name.
+ */
+apr_status_t mm_unixd_set_shm_perms(const char *fname);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* MM_ASMM_H */
Property changes on: sandbox/aloha/httpd/modules/manager/mm_asmm.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_balancer.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_balancer.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_balancer.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,552 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Balancer object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+
+static const char *balancer_params[] = {
+ "",
+ "Status",
+ "StickySession",
+ "StickySessionCookie",
+ "StickySessionPath",
+ "StickySessionRemove",
+ "StickySessionForce",
+ "TimeOut",
+ "MaxFailoverAttempts",
+ "AbortIfHeadersSend",
+ "AbortIfResponseReceived",
+ "InterstageMethod",
+ NULL
+};
+
+static const char *bal_get_method_name(mm_balance_method_e method)
+{
+ switch(method) {
+ case mm_balance_r:
+ return "R";
+ break;
+ case mm_balance_b:
+ return "B";
+ break;
+ }
+ return "-";
+}
+
+static mm_balance_method_e bal_get_method(const char *method)
+{
+ switch(apr_toupper(*method)) {
+ case 'R':
+ return mm_balance_r;
+ break;
+ case 'B':
+ return mm_balance_r;
+ break;
+ }
+ return mm_balance_undef;
+}
+
+static void rdo_balancer_info_print(int pi, int pp,
+ mmdb_balancer_t *bal,
+ request_rec *r)
+{
+ if (pp) {
+ ap_rvputs(r, balancer_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* Status */
+ ap_rputs(mm_state_name_get(bal->status), r);
+ break;
+ case 2: /* StickySession */
+ ap_rputs(MM_STR_ONOFF(bal->sticky_session), r);
+ break;
+ case 3: /* StickySessionCookie */
+ ap_rvputs(r, bal->sticky_session_cookie, NULL);
+ break;
+ case 4: /* StickySessionPath */
+ MM_MAYBEQ_RPUTS(r, pp, bal->sticky_session_path);
+ break;
+ case 5: /* StickySessionRemove */
+ ap_rputs(MM_STR_ONOFF(bal->sticky_session_remove), r);
+ break;
+ case 6: /* StickySessionForce */
+ ap_rputs(MM_STR_ONOFF(bal->sticky_session_force), r);
+ break;
+ case 7: /* TimeOut */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(bal->timeout));
+ break;
+ case 8: /* MaxFailoverAttempts */
+ ap_rprintf(r, "%d", bal->retries);
+ break;
+ case 9: /* AbortIfHeadersSend */
+ ap_rputs(MM_STR_ONOFF(bal->abort_if_headers_send), r);
+ break;
+ case 10: /* AbortIfResponseReceived */
+ ap_rputs(MM_STR_ONOFF(bal->abort_if_response_get), r);
+ break;
+ case 11: /* InterstageMethod */
+ ap_rputs(bal_get_method_name(bal->method), r);
+ break;
+ }
+}
+
+/* Dump Balancer info */
+static void rdo_balancer_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_balancer_t *bal,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (balancer_params[j]) {
+ if (apr_fnmatch(ce[i].key, balancer_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (balancer_params[j]) {
+ if (!strcasecmp(ce[i].key, balancer_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_balancer_info_print(m, wcm, bal, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (balancer_params[j]) {
+ if (apr_fnmatch(ce[i].key, balancer_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_balancer_info_print(j, 1, bal, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (balancer_params[j]) {
+ if (!strcasecmp(ce[i].key, balancer_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_balancer_info_print(j, 1, bal, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static int balancer_exist(const char *value, mmdb_balancer_t **bp)
+{
+ apr_uint32_t next = 0;
+ mmdb_balancer_t *balancer;
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ while ((balancer = asmm_slot_next(balancer_db, &next))) {
+ if (strcasecmp(value, balancer->name))
+ continue;
+ *bp = balancer;
+ return 1;
+ }
+ return 0;
+}
+
+static apr_status_t rdo_balancer_config_do(int pi,
+ const char *value,
+ mmdb_balancer_t *bal,
+ request_rec *r)
+{
+ switch (pi) {
+ case 1: /* Status */
+ bal->status = mm_state_get(value);
+ break;
+ case 2: /* StickySession */
+ bal->sticky_session = MM_VAL_ONOFF(value);
+ break;
+ case 3: /* StickySessionCookie */
+ MM_SSAFE_COPY(bal->sticky_session_cookie, value);
+ break;
+ case 4: /* StickySessionPath */
+ MM_SSAFE_COPY(bal->sticky_session_path, value);
+ break;
+ case 5: /* StickySessionRemove */
+ bal->sticky_session_remove = MM_VAL_ONOFF(value);
+ break;
+ case 6: /* StickySessionForce */
+ bal->sticky_session_force = MM_VAL_ONOFF(value);
+ break;
+ case 7: /* TimeOut */
+ bal->timeout = APR_TIME_C(1000) * atoi(value);
+ break;
+ case 8: /* MaxFailoverAttempts */
+ bal->retries = atoi(value);
+ break;
+ case 9: /* AbortIfHeadersSend */
+ bal->abort_if_headers_send = MM_VAL_ONOFF(value);
+ break;
+ case 10: /* AbortIfResponseReceived */
+ bal->abort_if_response_get = MM_VAL_ONOFF(value);
+ break;
+ case 11: /* InterstageMethod */
+ bal->method= bal_get_method(value);
+ break;
+ }
+ return 0;
+}
+
+/* Configure Balancer */
+static int rdo_balancer_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ apr_uint32_t balancer_id,
+ mmdb_balancer_t *balancer,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (balancer_params[j]) {
+ if (!strcasecmp(ce[i].key, balancer_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_balancer_config_do(j, ce[i].val,
+ balancer, r))) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static void rdo_balancer_delete(apr_uint32_t balancer_id)
+{
+ apr_uint32_t next = 0;
+ mmdb_balancer_t *balancer;
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ while ((balancer = asmm_slot_next(balancer_db, &next))) {
+ if ((next - 1) == balancer_id) {
+ asmm_free(balancer_db, balancer);
+ break;
+ }
+ }
+}
+
+static apr_status_t create_balancer(mm_server_conf_t *cfg,
+ const char *name,
+ asmm_slotmem_t *balancer_db,
+ mmdb_balancer_t **balancer,
+ apr_uint32_t *balancer_id)
+{
+ /* Create _default_ balancer */
+ if (!(*balancer = asmm_salloc_ex(balancer_db, balancer_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY((*balancer)->name, name);
+ MM_SSAFE_COPY((*balancer)->sticky_session_cookie, MM_DEF_SESSION_C);
+ MM_SSAFE_COPY((*balancer)->sticky_session_path, MM_DEF_SESSION_P);
+ (*balancer)->sticky_session = 1;
+ (*balancer)->sticky_session_remove = 0;
+ (*balancer)->sticky_session_force = 0;
+ (*balancer)->abort_if_headers_send = 0;
+ (*balancer)->abort_if_response_get = 0;
+ (*balancer)->method = mm_balance_r;
+ (*balancer)->retries = 0; /* Unlimited */
+ (*balancer)->timeout = cfg->main_server->timeout;
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_balancer(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int wcm;
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+ apr_uint32_t next = 0;
+ mmdb_balancer_t *balancer;
+
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ if (!balancer_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+#if MM_FORCE_DEFAULT_NAME_REQ
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty balancer name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+#else
+ name = MM_DEFAULT_NAME;
+#endif
+ }
+ wcm = apr_fnmatch_test(name);
+ while ((balancer = asmm_slot_next(balancer_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, balancer->name,
+ MM_FFNMATCH) != APR_SUCCESS)
+ continue;
+ }
+ else if (strcasecmp(name, balancer->name))
+ continue;
+ if (cmd_offset < ca->nelts) {
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[cmd_offset].key);
+ if (mp) {
+ apr_status_t rc;
+ if (mp == this_provider) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] recursion not allowed: %s",
+ mm_mcmp_command_name_get(cmd),
+ this_provider->name);
+ return APR_SUCCESS;
+ }
+ rc = (*mp->func)(cfg, cmd,
+ ce[cmd_offset].val, this_provider,
+ next - 1, balancer,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS) {
+ }
+ wdone++;
+ if (wcm)
+ continue;
+ else
+ break;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm) {
+ ap_rvputs(r, "@" MM_RES_BALANCER "/", balancer->name, NULL);
+ if (cmd_offset < ca->nelts)
+ ap_rputs(": ", r);
+ else
+ ap_rputs(CRLF, r);
+ }
+ if (cmd_offset < ca->nelts)
+ rdo_balancer_info(cmd_table, cmd_offset, wcm, balancer, r);
+ break;
+ case mm_mcmp_enable:
+ balancer->status = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ balancer->status = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ balancer->status = mm_state_stopped;
+ break;
+ case mm_mcmp_delete:
+ if (balancer->status != mm_state_stopped) {
+ /* Balancer must be stopped before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Balancer not stopped: %s",
+ balancer->name);
+ return APR_SUCCESS;
+ }
+ else if (balancer->members || balancer->hosts) {
+ /* Balancer must be empty before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Balancer not empty: %s",
+ balancer->name);
+ return APR_SUCCESS;
+ }
+ else {
+ /* Delete Balancer entries */
+ if (strcmp(balancer->name, MM_DEFAULT_NAME)) {
+ /* Remove any dependant objects */
+ asmm_free(balancer_db, balancer);
+ }
+ else if (!wcm) {
+ mm_send_response_ex(r, mm_response_error,
+ MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+ r->server,
+ "mod_manager: Cannot delete "
+ MM_DEFAULT_NAME " Balancer");
+ return APR_SUCCESS;
+ }
+ }
+ case mm_mcmp_config:
+ if (rdo_balancer_config(cfg, cmd_table, cmd_offset,
+ next - 1, balancer, r))
+ return APR_SUCCESS;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Balancer",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_status_t rv;
+ apr_uint32_t balancer_id;
+ /* Add new Balancer */
+ if ((rv = create_balancer(cfg, name, balancer_db,
+ &balancer, &balancer_id)) != APR_SUCCESS)
+ return rv;
+ /* Update Balancer from provided params */
+ rdo_balancer_config(cfg, cmd_table, cmd_offset,
+ balancer_id, balancer, r);
+ }
+ else {
+ mm_send_response_ex(r, mm_response_utype, 0, MM_RES_BALANCER "/",
+ name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown balancer: %s", name);
+ return APR_SUCCESS;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_balancer_init(mm_server_conf_t *cfg, apr_pool_t *pool)
+{
+ apr_uint32_t balancer_id;
+ mmdb_balancer_t *balancer;
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ if (!balancer_db)
+ return APR_ENOMEM;
+ /* Create _default_ balancer */
+ return create_balancer(cfg, MM_DEFAULT_NAME,
+ balancer_db,
+ &balancer,
+ &balancer_id);
+}
+
+static apr_status_t ini_balancer(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ return rdo_balancer_init(cfg, pool);
+ break;
+ case mm_resource_open:
+ case mm_resource_child_init:
+ case mm_resource_close:
+ /* Nothing to do for a Balancer */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t balancer_provider = {
+ MMDB_BALANCER,
+ MM_RES_BALANCER,
+ rdo_balancer,
+ ini_balancer,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_balancer(apr_pool_t *pool)
+{
+ this_provider = &balancer_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_balancer.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_cookie.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_cookie.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_cookie.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,212 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Cookie utility routines */
+#include "mm_cookie.h"
+
+#define COOKIE_SEPS ";"
+#define COOKIE_SEPC ';'
+#ifdef MM_COOKIE_SPEC_RFC
+#define COOKIE_SPEC "()<>@,;:\\\"/[]?={} \t"
+#else
+#define COOKIE_SPEC "()<>@,;:\\\"={} \t"
+#endif
+
+typedef enum {
+ MMC_COOKIE_COMMAND,
+ MMC_COOKIE_PATH,
+ MMC_COOKIE_VERSION,
+ MMC_COOKIE_DOMAIN,
+ MMC_COOKIE_COMMENT,
+ MMC_COOKIE_COMMENTURL,
+ MMC_COOKIE_MAXAGE,
+ MMC_COOKIE_EXPIRES,
+ MMC_COOKIE_PORT,
+ MMC_COOKIE_SECURE,
+ MMC_COOKIE_DISCARD,
+ MMC_COOKIE_LEN
+} mmc_cookie_av_e;
+
+static struct mmc_cookie_spec {
+ const char *name;
+ int param;
+ mmc_cookie_av_e av;
+} mmc_cookie_specs[] = {
+ { MMS_COOKIE_COMMAND, 1, MMC_COOKIE_COMMAND },
+ { MMS_COOKIE_PATH, 1, MMC_COOKIE_PATH },
+ { MMS_COOKIE_VERSION, 1, MMC_COOKIE_VERSION },
+ { MMS_COOKIE_DOMAIN, 1, MMC_COOKIE_DOMAIN },
+ { MMS_COOKIE_COMMENT, 1, MMC_COOKIE_COMMENT },
+ { MMS_COOKIE_COMMENTURL, 1, MMC_COOKIE_COMMENTURL},
+ { MMS_COOKIE_MAXAGE, 1, MMC_COOKIE_MAXAGE },
+ { MMS_COOKIE_EXPIRES, 1, MMC_COOKIE_EXPIRES },
+ { MMS_COOKIE_PORT, 1, MMC_COOKIE_PORT },
+ { MMS_COOKIE_SECURE, 0, MMC_COOKIE_SECURE },
+ { MMS_COOKIE_DISCARD, 0, MMC_COOKIE_DISCARD },
+ { NULL, 0, MMC_COOKIE_LEN }
+};
+
+static const char *mmc_true_str = "True";
+static const char *mmc_zero_str = "";
+
+static char *mmc_trim_str(char *str)
+{
+ char *p = str;
+
+ for (p = str; *p; p++); /* Find end of string */
+ for (p--; p >= str; p--) {
+ if (apr_isspace(*p))
+ *p = '\0'; /* Zap trailing blanks */
+ else
+ break;
+ }
+ while (apr_isspace(*str))
+ str++; /* Strip leading blanks */
+ return str;
+}
+
+static char *mmc_trim_unquote(char *str)
+{
+ char *p = str;
+
+ for (p = str; *p; p++); /* Find end of string */
+ for (p--; p >= str; p--) {
+ if (apr_isspace(*p))
+ *p = '\0'; /* Zap trailing blanks */
+ else
+ break;
+ }
+ while (apr_isspace(*str))
+ str++; /* Strip leading blanks */
+ if (*str == '"' && p != str && *p == '"') {
+ *p = '\0';
+ str++;
+ }
+ return str;
+}
+
+static int mmc_name_valid(const char *cookie)
+{
+ const char *p = cookie;
+ while (*p) {
+ if (strchr(COOKIE_SPEC, *p))
+ return 0;
+ p++;
+ }
+ return 1;
+}
+
+static APR_INLINE int mmc_is_valid(int c)
+{
+ if (apr_isalnum(c) ||
+ c == '*' ||
+ c == '?' ||
+ c == '[')
+ return 1;
+ else
+ return 0;
+
+}
+/* Note: Parser doesn't allow embedded quotes inside quoted values.
+ */
+apr_status_t mmc_cookie_parse(apr_table_t *cookies, const char *cookie,
+ apr_pool_t *p)
+{
+ char *str, *tok, *state, *val;
+ int i;
+
+ while (*cookie && apr_isspace(*cookie))
+ cookie++;
+ if (*cookie == '\0')
+ return APR_EINVAL;
+
+ str = apr_pstrdup(p, cookie);
+ tok = apr_strtok(str, COOKIE_SEPS, &state);
+ while (tok != NULL) {
+ int dollar = 0;
+ int hasav = 0;
+ tok = mmc_trim_str(tok);
+ if (*tok == '$') {
+ tok++;
+ dollar = 1;
+ }
+ if ((val = strchr(tok, '='))) {
+ *val++ = '\0';
+ val = mmc_trim_unquote(val);
+ tok = mmc_trim_str(tok);
+ if (*val == '"') {
+ char *p;
+ /* We have embedded separator inside quotes */
+ *(state - 1) = COOKIE_SEPC;
+ if (!(state = strchr(state + 1, '"'))) {
+ /* Bad formating */
+ return APR_EINVAL;
+ }
+ if ((p = strchr(state + 1, COOKIE_SEPC))) {
+ *p++ = '\0';
+ state = p;
+ }
+ val = mmc_trim_unquote(val);
+ }
+ }
+ i = 0;
+ while (mmc_cookie_specs[i].name) {
+ if (!strcasecmp(tok, mmc_cookie_specs[i].name)) {
+ if (!val && mmc_cookie_specs[i].param)
+ return APR_EINVAL;
+ switch (mmc_cookie_specs[i].av) {
+ case MMC_COOKIE_SECURE:
+ case MMC_COOKIE_DISCARD:
+ apr_table_setn(cookies, mmc_cookie_specs[i].name,
+ mmc_true_str);
+ break;
+ default:
+ apr_table_setn(cookies, mmc_cookie_specs[i].name,
+ val);
+ break;
+ }
+ break;
+ }
+ i++;
+ }
+ if (i >= MMC_COOKIE_LEN) {
+ if (dollar) {
+ return APR_EINVAL;
+ }
+ else if (mmc_is_valid(*tok)) {
+ if (!mmc_name_valid(tok))
+ return APR_EINVAL;
+ if (!val) {
+ if ((val = strchr(tok, '/')))
+ *(val++) = '\0';
+ }
+ apr_table_addn(cookies, tok, val ? val : mmc_zero_str);
+ }
+ }
+ tok = apr_strtok(NULL, COOKIE_SEPS, &state);
+ }
+ return APR_SUCCESS;
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_cookie.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_cookie.h
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_cookie.h (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_cookie.h 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,83 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#ifndef MM_COOKIE_H
+#define MM_COOKIE_H
+
+
+/**
+ * @file mmc_cookie.h
+ * @brief Manager cookie library
+ */
+/**
+ * @defgroup MM_COOKIE cookie routines
+ * @ingroup Manager
+ * @{
+ */
+
+#include "apr.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "apr_tables.h"
+#include "apr_errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MMS_COOKIE_COMMAND "Command"
+
+/**
+ * RFC 2109 Cookie attributes
+ */
+#define MMS_COOKIE_PATH "Path"
+#define MMS_COOKIE_VERSION "Version"
+#define MMS_COOKIE_DOMAIN "Domain"
+#define MMS_COOKIE_COMMENT "Comment"
+#define MMS_COOKIE_COMMENTURL "CommentURL"
+#define MMS_COOKIE_MAXAGE "Max-Age"
+#define MMS_COOKIE_EXPIRES "Expires"
+#define MMS_COOKIE_PORT "Port"
+#define MMS_COOKIE_SECURE "Secure"
+#define MMS_COOKIE_DISCARD "Discard"
+
+/**
+ * Parse [Set-]Cookie: header accoring to the RFC 2109
+ * @param cookies Parsed cookies table
+ * @param cookie Input string to parse
+ * @param pool Pool to use
+ */
+apr_status_t mmc_cookie_parse(apr_table_t *cookies, const char *cookie,
+ apr_pool_t *p);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* MM_COOKIE_H */
Property changes on: sandbox/aloha/httpd/modules/manager/mm_cookie.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_host.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_host.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_host.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,715 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Host object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+
+static const char *host_params[] = {
+ "",
+ "ServerName",
+ "ServerAlias",
+ "DocumentRoot",
+ "IsVirtual",
+ "KeepAlive",
+ "KeepAliveTimeout",
+ "MaxKeepAliveRequests",
+ "TimeOut",
+ "LimitRequestBody",
+ "Address",
+ "Port",
+ "Status",
+ NULL
+};
+
+static char *print_aliases(char *dst, int len, mmdb_hostlist_t *hostlist,
+ request_rec *r)
+{
+ int sep = 0;
+ apr_uint32_t next = 0;
+ mmdb_hostlist_t *alias;
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+ *dst = '\0';
+ while ((alias = asmm_slot_next(hostlist_db, &next))) {
+ /* Skip ourself */
+ if ((next - 1) == hostlist->selfref)
+ continue;
+ /* Check if this is alias */
+ if (alias->selfref != hostlist->selfref)
+ continue;
+ if (sep++) {
+ *(dst++) = ' ';
+ }
+ dst = apr_cpystrn(dst, alias->name, len);
+ len -= (strlen(alias->name) - 1);
+ }
+}
+
+static void rdo_host_info_print(int pi, int pp,
+ mmdb_host_t *host,
+ mmdb_hostlist_t *hostlist,
+ request_rec *r)
+{
+ char b[MM_BSIZE];
+
+ if (pp) {
+ ap_rvputs(r, host_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* ServerName */
+ ap_rvputs(r, hostlist->name, NULL);
+ break;
+ case 2: /* ServerAlias */
+ print_aliases(b, MM_BSIZE, hostlist, r);
+ MM_MAYBEQ_RPUTS(r, pp, b);
+ break;
+ case 3: /* DocumentRoot */
+ MM_MAYBEQ_RPUTS(r, pp, host->document_root);
+ break;
+ case 4: /* IsVirtual */
+ ap_rputs(MM_STR_BOOL(host->is_virtual), r);
+ break;
+ case 5: /* KeepAlive */
+ ap_rputs(MM_STR_ONOFF(host->keep_alive), r);
+ break;
+ case 6: /* KeepAliveTimeout */
+ ap_rprintf(r, "%" APR_TIME_T_FMT,
+ apr_time_as_msec(host->keep_alive_timeout));
+ break;
+ case 7: /* MaxKeepAliveRequests */
+ ap_rprintf(r, "%d", host->keep_alive_max);
+ break;
+ case 8: /* TimeOut */
+ ap_rprintf(r, "%" APR_TIME_T_FMT,
+ apr_time_as_msec(host->timeout));
+ break;
+ case 9: /* LimitRequestBody */
+ ap_rprintf(r, "%d", host->limit_req_line);
+ break;
+ case 10: /* Address */
+ ap_rvputs(r, host->address, NULL);
+ break;
+ case 11: /* Port */
+ ap_rprintf(r, "%d", host->port);
+ break;
+ case 12: /* Status */
+ ap_rputs(mm_state_name_get(host->status), r);
+ break;
+ }
+}
+
+/* Dump Host info */
+static void rdo_host_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_host_t *host,
+ mmdb_hostlist_t *hostlist,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (host_params[j]) {
+ if (apr_fnmatch(ce[i].key, host_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (host_params[j]) {
+ if (!strcasecmp(ce[i].key, host_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ if (m != 2 || host->is_virtual)
+ rdo_host_info_print(m, wcm, host, hostlist, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (host_params[j]) {
+ if (apr_fnmatch(ce[i].key, host_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_host_info_print(j, 1, host, hostlist, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (host_params[j]) {
+ if (!strcasecmp(ce[i].key, host_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_host_info_print(j, 1, host, hostlist, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static int host_exist(const char *value, mmdb_hostlist_t **hl)
+{
+ apr_uint32_t next = 0;
+ mmdb_hostlist_t *hostlist;
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+ while ((hostlist = asmm_slot_next(hostlist_db, &next))) {
+ if (strcasecmp(value, hostlist->name))
+ continue;
+ *hl = hostlist;
+ return 1;
+ }
+ return 0;
+}
+
+#define ALIASES_SEPS ", "
+
+static void add_aliases(mmdb_hostlist_t *hostlist, const char *value)
+{
+ int remove;
+ char *tok, *state;
+ char str[MM_BSIZE];
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+ apr_cpystrn(str, value, MM_BSIZE);
+ tok = apr_strtok(str, ALIASES_SEPS, &state);
+ while (tok != NULL) {
+ if (*tok == '-') {
+ tok++;
+ remove = 1;
+ }
+ else
+ remove = 0;
+ if (*tok) {
+ mmdb_hostlist_t *alias = NULL;
+ if (!host_exist(tok, &alias)) {
+ /* Add new ServerAlias */
+ if (!(alias = asmm_salloc(hostlist_db)))
+ return;
+ MM_SSAFE_COPY(alias->name, tok);
+ alias->host_id = hostlist->host_id;
+ /* Reference to VirtualHost */
+ alias->selfref = hostlist->selfref;
+ }
+ else if (remove && alias) {
+ asmm_free(hostlist_db, alias);
+ }
+ }
+ tok = apr_strtok(NULL, ALIASES_SEPS, &state);
+ }
+}
+
+static apr_status_t rdo_host_config_do(int pi,
+ const char *value,
+ mmdb_host_t *host,
+ mmdb_hostlist_t *hostlist,
+ request_rec *r)
+{
+ switch (pi) {
+ case 1: /* ServerName */
+ MM_SSAFE_COPY(hostlist->name, value);
+ break;
+ case 2: /* ServerAlias */
+ add_aliases(hostlist, value);
+ break;
+ case 3: /* DocumentRoot */
+ MM_SSAFE_COPY(host->document_root, value);
+ break;
+ case 4: /* IsVirtual */
+ ap_rputs(MM_STR_BOOL(host->is_virtual), r);
+ break;
+ case 5: /* KeepAlive */
+ host->keep_alive = MM_VAL_ONOFF(value);
+ break;
+ case 6: /* KeepAliveTimeout */
+ host->keep_alive_timeout = APR_TIME_C(1000) * atoi(value);
+ break;
+ case 7: /* MaxKeepAliveRequests */
+ host->keep_alive_max = atoi(value);
+ break;
+ case 8: /* TimeOut */
+ host->timeout = APR_TIME_C(1000) * atoi(value);
+ break;
+ case 9: /* LimitRequestBody */
+ host->limit_req_line = atoi(value);
+ break;
+ case 10: /* Address */
+ MM_SSAFE_COPY(host->address, value);
+ break;
+ case 11: /* Port */
+ host->port = atoi(value);
+ break;
+ case 12: /* Status */
+ host->status = mm_state_get(value);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+/* Configure Host */
+static int rdo_host_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ mmdb_host_t *host,
+ mmdb_hostlist_t *hostlist,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (host_params[j]) {
+ if (!strcasecmp(ce[i].key, host_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_host_config_do(j, ce[i].val,
+ host, hostlist, r))) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error, rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static void rdo_host_delete(asmm_slotmem_t *host_db,
+ asmm_slotmem_t *hostlist_db,
+ mmdb_host_t *host, apr_uint32_t host_id)
+{
+ apr_uint32_t next = 0;
+ mmdb_hostlist_t *hostlist;
+
+ /* Delete all HostList entries matching Host Id */
+ while ((hostlist = asmm_slot_next(hostlist_db, &next))) {
+ if (hostlist->host_id == host_id)
+ asmm_free(hostlist_db, hostlist);
+ }
+ asmm_free(host_db, host);
+}
+
+static apr_status_t rdo_host(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int wcm = 0;
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+ apr_uint32_t next = 0;
+ mmdb_host_t *host;
+ mmdb_hostlist_t *hostlist;
+
+ asmm_slotmem_t *host_db = mmdb_table_getn(MMDB_HOST);
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+ if (!host_db || !hostlist_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+#if MM_FORCE_DEFAULT_NAME_REQ
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty host name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+#else
+ name = MM_DEFAULT_NAME;
+#endif
+ }
+ if (*name != '~')
+ wcm = apr_fnmatch_test(name);
+ while ((hostlist = asmm_slot_next(hostlist_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, hostlist->name,
+ MM_FFNMATCH) != APR_SUCCESS)
+ continue;
+ }
+ else if (strcasecmp(name, hostlist->name))
+ continue;
+ /* Check if this is alias */
+ if ((next - 1) != hostlist->selfref) {
+ continue;
+ }
+ /* We have a matching record */
+ if (!(host = asmm_slot(host_db, hostlist->host_id))) {
+ /* HostList without Host record
+ * Corrupted database?
+ */
+ return APR_ESYMNOTFOUND;
+ }
+ if (cmd_offset < ca->nelts) {
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[cmd_offset].key);
+ if (mp) {
+ apr_status_t rc;
+ if (mp == this_provider) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] recursion not allowed: %s",
+ mm_mcmp_command_name_get(cmd),
+ this_provider->name);
+ return APR_SUCCESS;
+ }
+ rc = (*mp->func)(cfg, cmd,
+ ce[cmd_offset].val, this_provider,
+ hostlist->host_id, host,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS) {
+ }
+ wdone++;
+ if (wcm)
+ continue;
+ else
+ break;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm) {
+ ap_rvputs(r, "@" MM_RES_HOST "/", hostlist->name, NULL);
+ if (cmd_offset < ca->nelts)
+ ap_rputs(": ", r);
+ else
+ ap_rputs(CRLF, r);
+ }
+ if (cmd_offset < ca->nelts)
+ rdo_host_info(cmd_table, cmd_offset, wcm,
+ host, hostlist, r);
+ break;
+ case mm_mcmp_enable:
+ host->status = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ host->status = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ host->status = mm_state_stopped;
+ break;
+ case mm_mcmp_delete:
+ if (host->status != mm_state_stopped) {
+ /* Host must be stopped before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Host not stopped: %s",
+ hostlist->name);
+ return APR_SUCCESS;
+ }
+ if (strcmp(hostlist->name, MM_DEFAULT_NAME)) {
+ /* Delete Host and HostList entries */
+ mmdb_balancer_t *pbal = NULL;
+ if (host->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ host->balancer_id);
+ rdo_host_delete(host_db, hostlist_db, host,
+ hostlist->host_id);
+ if (pbal && pbal->hosts)
+ pbal->hosts--;
+ }
+ else if (!wcm) {
+ mm_send_response_ex(r, mm_response_error,
+ MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+ r->server,
+ "mod_manager: Cannot delete default Host");
+ return APR_SUCCESS;
+ }
+ case mm_mcmp_config:
+ if (prev && prev->id == MMDB_BALANCER) {
+ mmdb_balancer_t *nbal = (mmdb_balancer_t *)prev_rec;
+ if (prev_id != host->balancer_id) {
+ mmdb_balancer_t *pbal = NULL;
+ if (host->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ host->balancer_id);
+ /* Attach the Host to another Balancer */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "mod_manager: Host: %s assigned to"
+ " Balancer: %s",
+ hostlist->name, nbal->name);
+ host->balancer_id = prev_id;
+ nbal->hosts++;
+ if (pbal && pbal->hosts)
+ pbal->hosts--;
+ }
+ }
+ if (rdo_host_config(cfg, cmd_table, cmd_offset,
+ host, hostlist, r))
+ return APR_SUCCESS;
+ break;
+ case mm_mcmp_reset:
+ case mm_mcmp_exec:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Host",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_uint32_t host_id;
+ apr_uint32_t hostlist_id;
+ if (prev && prev->id != MMDB_BALANCER) {
+ mm_send_response_ex(r, mm_response_utype, 0, prev->name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: type %s in not valid root for Host: %s",
+ prev->name, name);
+ return APR_SUCCESS;
+ }
+ if (!prev) {
+ /* Use _default_ balancer */
+ prev_id = 0;
+ }
+
+ /* Add new VirtualHost */
+ if (!(hostlist = asmm_salloc_ex(hostlist_db, &hostlist_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(hostlist->name, name);
+
+ /* Create Host record */
+ if (!(host = asmm_salloc_ex(host_db, &host_id)))
+ return apr_get_os_error();
+ hostlist->host_id = host_id;
+ /* Self reference */
+ hostlist->selfref = hostlist_id;
+ /* New Host is always virtual */
+ host->is_virtual = 1;
+ host->balancer_id = prev_id;
+ /* Update Host from provided params */
+ rdo_host_config(cfg, cmd_table, cmd_offset, host, hostlist, r);
+ if (prev_rec) {
+ ((mmdb_balancer_t *)prev_rec)->hosts++;
+ }
+
+ }
+ else {
+ mm_send_response_ex(r, mm_response_utype, 0, MM_RES_HOST "/",
+ name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown host: %s", name);
+ return APR_SUCCESS;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ if (!prev)
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_host_init(mm_server_conf_t *cfg, apr_pool_t *pool)
+{
+ server_rec *s = cfg->main_server;
+ core_server_config *csc;
+ mmdb_host_t *host;
+ mmdb_hostlist_t *hostlist;
+ mmdb_hostlist_t *alias;
+ asmm_slotmem_t *host_db = mmdb_table_getn(MMDB_HOST);
+ asmm_slotmem_t *hostlist_db = mmdb_table_getn(MMDB_HOST_LIST);
+
+ if (!host_db || !hostlist_db)
+ return APR_ENOMEM;
+
+ while (s) {
+ apr_uint32_t host_id;
+ apr_uint32_t hostlist_id;
+ /* Create HostList record for each server_rec */
+ if (!(hostlist = asmm_salloc_ex(hostlist_db, &hostlist_id)))
+ return apr_get_os_error();
+ if (s->is_virtual) {
+ MM_SSAFE_COPY(hostlist->name, s->server_hostname);
+ }
+ else {
+ strcpy(hostlist->name, MM_DEFAULT_NAME);
+ }
+ /* Now create and populate Host record */
+ if (!(host = asmm_salloc_ex(host_db, &host_id)))
+ return apr_get_os_error();
+ hostlist->host_id = host_id;
+ hostlist->selfref = hostlist_id; /* Reference itself */
+
+ host->is_virtual = s->is_virtual;
+ host->keep_alive = s->keep_alive;
+ host->keep_alive_max = s->keep_alive_max;
+ host->limit_req_line = s->limit_req_line;
+ host->timeout = s->timeout;
+ host->keep_alive_timeout = s->keep_alive_timeout;
+ if (s->server_scheme &&
+ (strcmp(s->server_scheme, "https") == 0)) {
+ strcpy(host->scheme, "https");
+ }
+ else {
+ strcpy(host->scheme, "http");
+ }
+ if (s->addrs) {
+ char *ip;
+ apr_sockaddr_ip_get(&ip, s->addrs->host_addr);
+ MM_SSAFE_COPY(host->address, ip);
+ host->port = s->addrs->host_addr->port;
+ }
+
+ csc = (core_server_config *)ap_get_module_config(s->module_config,
+ &core_module);
+ MM_SSAFE_COPY(host->document_root, csc->ap_document_root);
+
+ if (!s->is_virtual) {
+ if (!(alias = asmm_salloc(hostlist_db)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(alias->name, s->server_hostname);
+ alias->host_id = host_id;
+ alias->selfref = hostlist_id;
+ }
+ /* Look for ServerAlias */
+ if (s->names) {
+ int i;
+ for (i = 0; i < s->names->nelts; i++) {
+ const char *a = ((char **)s->names->elts)[i];
+ if (!a || !*a)
+ continue;
+ if (!(alias = asmm_salloc(hostlist_db)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(alias->name, a);
+ alias->host_id = host_id;
+ alias->selfref = hostlist_id;
+ }
+ }
+ /* Look for ServerAliasMatch */
+ if (s->wild_names) {
+ int i;
+ for (i = 0; i < s->wild_names->nelts; i++) {
+ const char *a = ((char **)s->wild_names->elts)[i];
+ if (!a || !*a)
+ continue;
+ if (!(alias = asmm_salloc(hostlist_db)))
+ return apr_get_os_error();
+ apr_cpystrn(&alias->name[1], a, sizeof(alias->name) - 1);
+ alias->name[0] = '~';
+ alias->host_id = host_id;
+ alias->selfref = hostlist_id;
+ }
+ }
+ s = s->next;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_host(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ return rdo_host_init(cfg, pool);
+ break;
+ case mm_resource_open:
+ case mm_resource_child_init:
+ case mm_resource_close:
+ /* Nothing to do for a Host */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t host_provider = {
+ MMDB_HOST,
+ MM_RES_HOST,
+ rdo_host,
+ ini_host,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_host(apr_pool_t *pool)
+{
+ this_provider = &host_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_host.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_manager.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_manager.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_manager.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,371 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+
+static const char *manager_params[] = {
+ "",
+ "ProtocolVersion",
+ "ServerId",
+ "Advertise",
+ "AdvertiseMode",
+ "Status",
+ "Strict",
+ "CaseInsensitive",
+ "SecurityKey",
+ NULL
+};
+
+static void rdo_manager_info_print(int pi, int pp,
+ mm_server_conf_t *cfg,
+ request_rec *r)
+{
+ mmdb_manager_t *m = (mmdb_manager_t *)this_provider->context;
+ if (pp) {
+ ap_rvputs(r, manager_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* ProtocolVersion */
+ ap_rputs(MM_MCMP_VERSION_STRING, r);
+ break;
+ case 2: /* ServerId */
+ ap_rvputs(r, m->srvid + 1, NULL);
+ break;
+ case 3: /* Advertise */
+ ap_rputs(MM_STR_ONOFF(m->advertise), r);
+ break;
+ case 4: /* AdvertiseMode */
+ switch (m->advertise_mode) {
+ case mm_advertise_off:
+ ap_rputs("Off", r);
+ break;
+ case mm_advertise_on:
+ ap_rputs("On", r);
+ break;
+ case mm_advertise_status:
+ ap_rputs("Status", r);
+ break;
+ }
+ break;
+ case 5: /* Status */
+ ap_rprintf(r, "%d", m->status);
+ break;
+ case 6: /* Strict */
+ ap_rputs(MM_STR_ONOFF(m->strict), r);
+ break;
+ case 7: /* CaseInsensitive */
+ ap_rputs(MM_STR_ONOFF(m->case_blind), r);
+ break;
+ case 8: /* SecurityKey */
+ {
+ int i, c = 0;
+ for (i = 0; i < APR_MD5_DIGESTSIZE; i++)
+ c += m->ssalt[i];
+ ap_rputs(MM_STR_ONOFF(c), r);
+ }
+ break;
+ }
+}
+
+/* Dump Manager info */
+static void rdo_manager_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ mm_server_conf_t *cfg,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+ const char *param = NULL;
+ const char *value = NULL;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (manager_params[j]) {
+ if (apr_fnmatch(ce[i].key, manager_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (manager_params[j]) {
+ if (!strcasecmp(ce[i].key, manager_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_manager_info_print(m, 0, cfg, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ /* Multiple params */
+ int sep = 0;
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (manager_params[j]) {
+ if (apr_fnmatch(ce[i].key, manager_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_manager_info_print(j, 1, cfg, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (manager_params[j]) {
+ if (!strcasecmp(ce[i].key, manager_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_manager_info_print(j, 1, cfg, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static apr_status_t rdo_manager_config_do(int pi,
+ const char *value,
+ request_rec *r)
+{
+ mmdb_manager_t *m = (mmdb_manager_t *)this_provider->context;
+
+ switch (pi) {
+ case 6: /* Strict */
+ m->strict = MM_VAL_ONOFF(value);
+ break;
+ case 7: /* CaseInsensitive */
+ m->case_blind = MM_VAL_ONOFF(value);
+ break;
+ case 8: /* SecurityKey */
+ {
+ apr_md5_ctx_t mc;
+ apr_md5_init(&mc);
+ apr_md5_update(&mc, value, strlen(value));
+ apr_md5_final(m->ssalt, &mc);
+ }
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+/* Configure Manager */
+static int rdo_manager_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (manager_params[j]) {
+ if (!strcasecmp(ce[i].key, manager_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_manager_config_do(j, ce[i].val, r)) != APR_SUCCESS) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static apr_status_t rdo_manager(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ mmdb_manager_t *m = (mmdb_manager_t *)this_provider->context;
+ switch (cmd) {
+ case mm_mcmp_info:
+ rdo_manager_info(cmd_table, cmd_offset, cfg, r);
+ break;
+ case mm_mcmp_enable:
+ if (!m->advertise) {
+ m->type = MM_ADVERTISE_SERVER;
+ m->status = HTTP_OK;
+ }
+ break;
+ case mm_mcmp_disable:
+ if (m->advertise) {
+ m->type = MM_ADVERTISE_STATUS;
+ m->status = HTTP_SERVICE_UNAVAILABLE;
+ }
+ break;
+ case mm_mcmp_stop:
+ m->advertise = 0;
+ break;
+ case mm_mcmp_reset:
+ m->status = 0;
+ break;
+ case mm_mcmp_config:
+ if (rdo_manager_config(cfg, cmd_table, cmd_offset, r))
+ return APR_SUCCESS;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Manager",
+ mm_mcmp_command_name_get(cmd));
+ break;
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_manager_init(mm_server_conf_t *cfg)
+{
+ apr_status_t rv;
+ asmm_slotmem_t *manager_db = NULL;
+ mmdb_manager_t *manager = NULL;
+
+ manager_db = mmdb_table_getn(MMDB_MANAGER);
+ if (!(manager = asmm_salloc(manager_db))) {
+ rv = apr_get_os_error();
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, cfg->main_server,
+ "mod_manager: database alloc for Manager");
+ return rv;
+ }
+ apr_uuid_get(&manager->suuid);
+ manager->srvid[0] = '/';
+ apr_uuid_format(&manager->srvid[1], &manager->suuid);
+ this_provider->context = manager;
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_manager_child_init(mm_server_conf_t *cfg)
+{
+ apr_status_t rv;
+ asmm_slotmem_t *manager_db = NULL;
+ mmdb_manager_t *manager = NULL;
+
+ manager_db = mmdb_table_getn(MMDB_MANAGER);
+ if (!(manager = asmm_slot(manager_db, 0))) {
+ rv = apr_get_os_error();
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, cfg->main_server,
+ "mod_manager: database record for Manager");
+ return rv;
+ }
+ this_provider->context = manager;
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_manager(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ return rdo_manager_init(cfg);
+ break;
+ case mm_resource_open:
+ case mm_resource_child_init:
+ return rdo_manager_child_init(cfg);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a Manager */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t manager_provider = {
+ MMDB_MANAGER,
+ MM_RES_MANAGER,
+ rdo_manager,
+ ini_manager,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_manager(apr_pool_t *pool)
+{
+ this_provider = &manager_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_manager.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_member.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_member.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_member.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,766 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Node object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+static int server_limit = 0;
+static int thread_limit = 0;
+static int max_clients = 0;
+static int max_childs = 0;
+static int max_requests_per_child = 0;
+static int max_threads_per_child = 0;
+
+static const char *member_params[] = {
+ "",
+ "Balancer",
+ "Type",
+ "Address",
+ "Port",
+ "Route",
+ "Domain",
+ "Ping",
+ "MaxConnections",
+ "MinConnections",
+ "MaxClients",
+ "TTL",
+ "LF",
+ "Distance",
+ "Activation",
+ "FlushMode",
+ "FlushTimeout",
+ /* Statistical data */
+ "State",
+ "Error",
+ "Busy",
+ "Connected",
+ "Elected",
+ "StickySessions",
+ "ClientErrors",
+ "NodeErrors",
+ "Trace",
+ "TraceErrors",
+ "Readed",
+ "Transferred",
+ NULL
+};
+
+static const char *get_balancer_name(apr_uint32_t id)
+{
+ mmdb_balancer_t *balancer;
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ if ((balancer = asmm_slot(balancer_db, id))) {
+ return balancer->name;
+ }
+ return NULL;
+}
+
+static const char *get_flush_name(mm_flush_mode_e mode)
+{
+ switch(mode) {
+ case mm_flush_wait:
+ return "T";
+ break;
+ case mm_flush_auto:
+ return "A";
+ break;
+ }
+ return "N";
+}
+
+static mm_flush_mode_e get_flush_mode(const char *mode)
+{
+ switch(apr_toupper(*mode)) {
+ case 'T':
+ return mm_flush_wait;
+ break;
+ case 'A':
+ return mm_flush_auto;
+ break;
+ }
+ return mm_flush_none;
+}
+
+static apr_status_t add_app_members(apr_uint32_t member_id,
+ apr_uint32_t balancer_id)
+{
+ apr_uint32_t napp = 0;
+ apr_uint32_t nhost = 0;
+ mmdb_host_t *host;
+ mmdb_app_t *app;
+ mmdb_memberapp_t *memberapp;
+ asmm_slotmem_t *host_db = mmdb_table_getn(MMDB_HOST);
+ asmm_slotmem_t *app_db = mmdb_table_getn(MMDB_APPLICATION);
+ asmm_slotmem_t *memberapp_db = mmdb_table_getn(MMDB_MEMBERAPP);
+
+ while ((host = asmm_slot_next(host_db, &nhost))) {
+ if (host->balancer_id != balancer_id)
+ continue;
+ napp = 0;
+ while ((app = asmm_slot_next(app_db, &napp))) {
+ if (app->host_id != (nhost - 1))
+ continue;
+ if (!(memberapp = asmm_salloc(memberapp_db)))
+ return apr_get_os_error();
+ memberapp->app_id = napp - 1;
+ memberapp->member_id = member_id;
+ memberapp->state = app->state;
+ }
+ }
+ return APR_SUCCESS;
+}
+
+static void del_app_members(apr_uint32_t member_id)
+{
+ apr_uint32_t next = 0;
+ mmdb_memberapp_t *memberapp;
+ asmm_slotmem_t *memberapp_db = mmdb_table_getn(MMDB_MEMBERAPP);
+
+ while ((memberapp = asmm_slot_next(memberapp_db, &next))) {
+ if (memberapp->member_id != member_id)
+ continue;
+ asmm_free(memberapp_db, memberapp);
+ }
+}
+
+
+static void rdo_member_info_print(int pi, int pp,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ char buf[512];
+ const char *p;
+
+ if (pp) {
+ ap_rvputs(r, member_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* Balancer */
+ ap_rvputs(r, get_balancer_name(mem->balancer_id), NULL);
+ break;
+ case 2: /* Type */
+ ap_rputs(mm_protocol_name_get(mem->type), r);
+ break;
+ case 3: /* Address */
+ ap_rvputs(r, mem->address, NULL);
+ break;
+ case 4: /* Port */
+ ap_rprintf(r, "%u", mem->port);
+ break;
+ case 5: /* Route */
+ ap_rvputs(r, mem->route, NULL);
+ break;
+ case 6: /* Domain */
+ ap_rvputs(r, mem->domain, NULL);
+ break;
+ case 7: /* Ping */
+ ap_rprintf(r, "%u", mem->ping);
+ break;
+ case 8: /* MaxConnections */
+ ap_rprintf(r, "%u", mem->max_conn);
+ break;
+ case 9: /* MinConnections */
+ ap_rprintf(r, "%u", mem->min_conn);
+ break;
+ case 10: /* MaxClients */
+ ap_rprintf(r, "%u", mem->max_clients);
+ break;
+ case 11: /* TTL */
+ ap_rprintf(r, "%u", mem->ttl);
+ break;
+ case 12: /* LF */
+ ap_rprintf(r, "%u", mem->lf);
+ break;
+ case 13: /* Distance */
+ ap_rprintf(r, "%u", mem->distance);
+ break;
+ case 14: /* Activation */
+ ap_rputs(mm_state_name_get(mem->activation), r);
+ break;
+ case 15: /* FlushMode */
+ ap_rputs(get_flush_name(mem->flush), r);
+ break;
+ case 16: /* FlushTimeout */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(mem->flush_wait));
+ break;
+ case 17: /* State */
+ ap_rputs(mm_state_name_get(mem->state), r);
+ break;
+ case 18: /* Error */
+ if (!(p = mm_strerror(mem->err))) {
+ if (!(p = apr_strerror(mem->err, buf, sizeof(buf))))
+ p = "Unknown Error";
+ }
+ if (pp)
+ ap_rprintf(r, "\"%d: %s\"", mem->err, p);
+ else
+ ap_rprintf(r, "%d: %s", mem->err, p);
+ break;
+ case 19: /* Busy */
+ ap_rprintf(r, "%u", mem->busy);
+ break;
+ case 20: /* Connected */
+ ap_rprintf(r, "%u", mem->connected);
+ break;
+ case 21: /* Elected */
+ ap_rprintf(r, "%u", mem->elected);
+ break;
+ case 22: /* StickySessions */
+ ap_rprintf(r, "%u", mem->ssessions);
+ break;
+ case 23: /* ClientErrors */
+ ap_rprintf(r, "%u", mem->err_client);
+ break;
+ case 24: /* NodeErrors */
+ ap_rprintf(r, "%u", mem->err_node);
+ break;
+ case 25: /* Trace */
+ ap_rprintf(r, "%u", mem->trace);
+ break;
+ case 26: /* TraceErrors */
+ ap_rprintf(r, "%u", mem->err_trace);
+ break;
+ case 27: /* Readed */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->readed);
+ break;
+ case 28: /* Transferred */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->transferred);
+ break;
+ }
+}
+
+/* Dump Member info */
+static void rdo_member_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (member_params[j]) {
+ if (apr_fnmatch(ce[i].key, member_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_member_info_print(m, wcm, mem, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (member_params[j]) {
+ if (apr_fnmatch(ce[i].key, member_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_member_info_print(j, 1, mem, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_member_info_print(j, 1, mem, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static apr_status_t rdo_member_config_do(int pi,
+ const char *value,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ int i;
+
+ switch (pi) {
+ case 2: /* Type */
+ if (mem->state == mm_state_stopped)
+ mem->type = mm_protocol_get(value);
+ else
+ return MME_EPERM;
+ break;
+ case 3: /* Address */
+ if (mem->state == mm_state_stopped)
+ MM_SSAFE_COPY(mem->address, value);
+ else
+ return MME_EPERM;
+ break;
+ case 4: /* Port */
+ if (mem->state == mm_state_stopped)
+ mem->port = atoi(value);
+ else
+ return MME_EPERM;
+ break;
+ case 5: /* Route */
+ MM_SSAFE_COPY(mem->route, value);
+ break;
+ case 6: /* Domain */
+ MM_SSAFE_COPY(mem->domain, value);
+ break;
+ case 7: /* Ping */
+ mem->ping = atoi(value);
+ break;
+ case 8: /* MaxConnections */
+ i = atoi(value);
+ if (i < 1 || i > max_threads_per_child)
+ return MME_EINVAL;
+ else
+ mem->max_conn = i;
+ break;
+ case 9: /* MinConnections */
+ i = atoi(value);
+ if (i < 1 || i > (int)mem->max_conn)
+ return MME_EINVAL;
+ else
+ mem->min_conn = i;
+ break;
+ case 10: /* MaxClients */
+ i = atoi(value);
+ if (i < 1 || i > max_clients)
+ return MME_EINVAL;
+ else
+ mem->max_clients = i;
+ break;
+ case 11: /* TTL */
+ mem->ttl = atoi(value);
+ break;
+ case 12: /* LF */
+ mem->lf = atoi(value);
+ break;
+ case 13: /* Distance */
+ mem->distance = atoi(value);
+ break;
+ case 14: /* Activation */
+ mem->activation = mm_state_get(value);
+ break;
+ case 15: /* FlushMode */
+ mem->flush = get_flush_mode(value);
+ break;
+ case 16: /* FlushTimeout */
+ mem->flush_wait = atoi(value) * APR_TIME_C(1000);
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+/* Configure Member */
+static int rdo_member_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ apr_uint32_t member_id,
+ mmdb_member_t *member,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_member_config_do(j, ce[i].val,
+ member, r)) != APR_SUCCESS) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static apr_status_t rdo_member(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int wcm;
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+ apr_uint32_t next = 0;
+ mmdb_member_t *member;
+
+ asmm_slotmem_t *member_db = mmdb_table_getn(MMDB_MEMBER);
+
+ if (!member_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty member name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ }
+ wcm = apr_fnmatch_test(name);
+ while ((member = asmm_slot_next(member_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, member->name,
+ MM_FFNMATCH) != APR_SUCCESS)
+ continue;
+ }
+ else if (strcasecmp(name, member->name))
+ continue;
+ if (cmd_offset < ca->nelts) {
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[cmd_offset].key);
+ if (mp) {
+ apr_status_t rc;
+ if (mp == this_provider) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] recursion not allowed: %s",
+ mm_mcmp_command_name_get(cmd),
+ this_provider->name);
+ return APR_SUCCESS;
+ }
+ rc = (*mp->func)(cfg, cmd,
+ ce[cmd_offset].val, this_provider,
+ next - 1, member,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS) {
+ }
+ wdone++;
+ if (wcm)
+ continue;
+ else
+ break;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm) {
+ ap_rvputs(r, "@" MM_RES_MEMBER "/", member->name, NULL);
+ if (cmd_offset < ca->nelts)
+ ap_rputs(": ", r);
+ else
+ ap_rputs(CRLF, r);
+ }
+ if (cmd_offset < ca->nelts)
+ rdo_member_info(cmd_table, cmd_offset, wcm, member, r);
+ break;
+ case mm_mcmp_enable:
+ member->state = mm_state_active;
+ member->activation = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ member->state = mm_state_disabled;
+ member->activation = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ member->state = mm_state_stopped;
+ member->activation = mm_state_stopped;
+ break;
+ case mm_mcmp_reset:
+ /* Reset statistical data */
+ member->elected = 0;
+ member->ssessions = 0;
+ member->err_client = 0;
+ member->err_node = 0;
+ member->err_trace = 0;
+ member->trace = 0;
+ member->readed = 0;
+ member->transferred = 0;
+ break;
+ case mm_mcmp_delete:
+ if (member->state != mm_state_stopped) {
+ /* Member must be stopped before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Member not stopped: %s",
+ member->name);
+ return APR_SUCCESS;
+ }
+ else {
+ /* Delete Member entry */
+ mmdb_balancer_t *pbal = NULL;
+ if (member->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ member->balancer_id);
+ del_app_members(next - 1);
+ asmm_free(member_db, member);
+ if (pbal && pbal->members)
+ pbal->members--;
+ }
+ break;
+ case mm_mcmp_config:
+ if (prev && prev->id == MMDB_BALANCER) {
+ mmdb_balancer_t *nbal = (mmdb_balancer_t *)prev_rec;
+ if (prev_id != member->balancer_id) {
+ mmdb_balancer_t *pbal = NULL;
+ if (member->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ member->balancer_id);
+ /* Attach the Member to another Balancer */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "mod_manager: Member: %s assigned to "
+ "Balancer: %s",
+ member->name, nbal->name);
+ member->balancer_id = prev_id;
+ nbal->members++;
+ if (pbal && pbal->members)
+ pbal->members--;
+ }
+ }
+ if (rdo_member_config(cfg, cmd_table, cmd_offset,
+ next - 1, member, r))
+ return APR_SUCCESS;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Balancer",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_uint32_t member_id;
+ if (prev && prev->id != MMDB_BALANCER) {
+ mm_send_response_ex(r, mm_response_utype, 0, prev->name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: type %s in not balancer for "
+ "Member: %s",
+ prev->name, name);
+ return APR_SUCCESS;
+ }
+ if (!prev) {
+ /* Use _default_ balancer */
+ prev_id = 0;
+ }
+ /* Add new Member */
+ if (!(member = asmm_salloc_ex(member_db, &member_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(member->name, name);
+ member->balancer_id = prev_id;
+ member->state = mm_state_stopped;
+ member->activation = mm_state_stopped;
+ member->lf = 1;
+ member->max_conn = max_threads_per_child;
+ member->min_conn = max_threads_per_child;
+ member->max_clients = max_clients;
+ /* Update Member from provided params */
+ if (rdo_member_config(cfg, cmd_table, cmd_offset,
+ member_id, member, r)) {
+ /* There was an error during initial config
+ * Delete member we created
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: failed creating member: %s",
+ name);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ }
+ if (!member->route[0])
+ strcpy(member->route, member->name);
+ if (!member->address[0])
+ strcpy(member->address, MM_DEFAULT_ADDRESS);
+ if (member->type == mm_protocol_unknown)
+ member->type = MM_DEFAULT_PROTOCOL;
+ if (!member->port) {
+ switch (member->type) {
+ case mm_protocol_ajp:
+ member->port = MM_DEFAULT_AJP_PORT;
+ break;
+ case mm_protocol_http:
+ member->port = MM_DEFAULT_HTTP_PORT;
+ break;
+ case mm_protocol_https:
+ member->port = MM_DEFAULT_HTTPS_PORT;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error,
+ MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Unknown protocol %d for "
+ "Member: %s",
+ member->type, member->name);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ break;
+ }
+ }
+ if (member->min_conn > member->max_conn)
+ member->min_conn = member->max_conn;
+ member->state = mm_state_stopped;
+ /* Add Applications linked to the Member's Balancer */
+ if (add_app_members(member_id, member->balancer_id) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: adding MemberApplication for: %s",
+ member->name);
+ del_app_members(member_id);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ }
+ if (prev_rec) {
+ ((mmdb_balancer_t *)prev_rec)->members++;
+ }
+ }
+ else {
+ mm_send_response_ex(r, mm_response_utype, 0, MM_RES_MEMBER "/",
+ name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown member: %s", name);
+ return APR_SUCCESS;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ if (!prev)
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_member_init(mm_server_conf_t *cfg)
+{
+
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+ ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DAEMON, &max_requests_per_child);
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_childs);
+ if (max_childs < 1)
+ max_childs = 1;
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+ if (max_threads_per_child < 1)
+ max_threads_per_child = 1;
+ max_clients = max_childs * max_threads_per_child;
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_member(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ case mm_resource_open:
+ case mm_resource_child_init:
+ return rdo_member_init(cfg);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a Member */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t member_provider = {
+ MMDB_MEMBER,
+ MM_RES_MEMBER,
+ rdo_member,
+ ini_member,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_member(apr_pool_t *pool)
+{
+ this_provider = &member_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_member.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_module.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_module.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_module.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,1449 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+#define CORE_PRIVATE
+
+#include "mm_api.h"
+#include "mm_cookie.h"
+#include "mod_core.h"
+#include "scoreboard.h"
+#include "mod_status.h"
+#include "mod_ssl.h"
+#include "util_script.h"
+
+#ifndef MAX
+#define MAX(x,y) ((x) >= (y) ? (x) : (y))
+#endif
+
+#define MM_SRVCONF(p) ap_get_module_config((p)->server->module_config, \
+ &manager_module)
+#define MM_GETCONF(s) ap_get_module_config((s)->module_config, \
+ &manager_module)
+
+/*
+ * Declare ourselves so the configuration routines can find and know us.
+ * We'll fill it in at the end of the module.
+ */
+module AP_MODULE_DECLARE_DATA manager_module;
+
+
+/*
+ * Server global data
+ */
+typedef struct mm_global_data_t {
+ int generation;
+ char *database_path;
+ void *database;
+ apr_pool_t *ppool;
+ apr_pool_t *cpool;
+} mm_global_data_t;
+
+static const char *mm_handler_name = MM_HANDLER_NAME;
+/*
+ * Global data instance
+ * For parent, registered in process pool
+ * For child, registered in child pool
+ */
+static mm_global_data_t *mmgd = NULL;
+static server_rec *mmsr = NULL;
+
+/* Global Database slots */
+static mmdb_manager_t *mmdb_manager_rec = NULL;
+static apr_global_mutex_t *mm_manager_mutex = NULL;
+
+/*
+ * Server private data
+ */
+static int mm_generation = 0;
+static apr_time_t mm_child_started = 0;
+static pid_t mm_parent_pid = -1;
+
+/*
+ * Global configuration
+ */
+static int mm_manager_strict = 0;
+static int mm_advertise_set = 0;
+static int mm_advertise_run = 0;
+static char *mm_database_root = NULL;
+static char *mm_lock_filename = NULL;
+static char *mm_advertise_adrs = NULL;
+static char *mm_advertise_adsi = NULL;
+static char *mm_advertise_srvm = NULL;
+static char *mm_advertise_srvs = NULL;
+static char *mm_advertise_srvi = NULL;
+
+static char *mm_advertise_skey = NULL;
+
+
+static mm_advertise_srv_t mm_advs_server;
+
+
+/* Advertise is by default turned off */
+static apr_port_t mm_advertise_port = MM_DEFAULT_ADVPORT;
+static apr_port_t mm_advertise_srvp = 0;
+static mm_advertise_e mm_advertise_mode = mm_advertise_off;
+static apr_interval_time_t mm_advertise_freq = MM_DEFAULT_ADV_FREQ;
+static mm_mcmp_command_e mcmp_command_type = mm_mcmp_unknown;
+
+
+/* Parent and child manager thread statuses */
+static volatile int is_mp_running = 0;
+static volatile int is_mc_running = 0;
+static volatile int is_mp_created = 0;
+static volatile int is_mc_created = 0;
+
+/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
+ * IPv4 match-any-address, 0.0.0.0. */
+#define IS_INADDR_ANY(addr) ((addr)->family == APR_INET && \
+ (addr)->sa.sin.sin_addr.s_addr == INADDR_ANY)
+
+/* Evaluates to true if the (apr_sockaddr_t *) addr argument is the
+ * IPv6 match-any-address, [::]. */
+#define IS_IN6ADDR_ANY(addr) ((addr)->family == APR_INET6 && \
+ IN6_IS_ADDR_UNSPECIFIED(&(addr)->sa.sin6.sin6_addr))
+
+#define MMDB_DIR_MODE (APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE | \
+ APR_FPROT_GREAD | APR_FPROT_GWRITE | APR_FPROT_GEXECUTE)
+
+static const char *mm_advertise_str[] = {
+ "Off",
+ "Status",
+ "On"
+};
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Server helper routines. */
+/* */
+/*--------------------------------------------------------------------------*/
+static apr_status_t mm_manager_dolock()
+{
+ if (mm_manager_mutex)
+ return apr_global_mutex_lock(mm_manager_mutex);
+ else
+ return APR_SUCCESS;
+}
+
+static apr_status_t mm_manager_unlock()
+{
+ if (mm_manager_mutex)
+ return apr_global_mutex_unlock(mm_manager_mutex);
+ else
+ return APR_SUCCESS;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Server configuration data. */
+/* */
+/*--------------------------------------------------------------------------*/
+static void *mm_create_server_config(apr_pool_t *p, server_rec *s)
+{
+ mm_server_conf_t *mmsc = apr_pcalloc(p, sizeof(mm_server_conf_t));
+
+ mmsc->pool = p;
+ mmsc->handle = MM_DEFAULT_HANDLE;
+ mmsc->server = s;
+ if (!s->is_virtual) {
+ mmsc->handle_set = 1;
+ mmsr = s;
+ }
+ mmsc->main_server = mmsr;
+ return mmsc;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Merge server configuration data. */
+/* */
+/*--------------------------------------------------------------------------*/
+static void *mm_merge_server_config(apr_pool_t *p, void *base, void *over)
+{
+ mm_server_conf_t *mmsc = apr_pcalloc(p, sizeof(mm_server_conf_t));
+ mm_server_conf_t *mmsb = (mm_server_conf_t *)base;
+ mm_server_conf_t *mmso = (mm_server_conf_t *)over;
+
+ mmsc->status = mmso->status_set ? mmso->status : mmsb->status;
+ mmsc->handle = mmso->handle_set ? mmso->handle : mmsb->handle;
+ mmsc->status_set = mmso->status_set || mmsb->status_set;
+ mmsc->handle_set = mmso->handle_set || mmsb->handle_set;
+ mmsc->pool = p;
+ mmsc->server = mmsb->server;
+ mmsc->main_server = mmsr;
+
+ return mmsc;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* ManagerStatus directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_status(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ mm_server_conf_t *mmsc = MM_SRVCONF(cmd);
+
+ if (strcasecmp(arg, "Off") == 0)
+ mmsc->status = mm_status_off;
+ else if (strcasecmp(arg, "On") == 0)
+ mmsc->status = mm_status_on;
+ else if (strcasecmp(arg, "Full") == 0)
+ mmsc->status = mm_status_full;
+ else
+ return "ManagerStatus must be one of: Off | On | Full";
+
+ mmsc->status_set = 1;
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* ManagerDatabaseRoot directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_dbroot(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+
+ if (mm_database_root != NULL)
+ return "Duplicate ManagerDatabaseRoot directives are not allowed";
+
+ /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */
+ mm_database_root = ap_server_root_relative(cmd->pool, arg);
+ if (mm_database_root == NULL)
+ return "Invalid ManagerDatabaseRoot name";
+ if (mm_database_root[strlen(mm_database_root) - 1] == '/')
+ mm_database_root[strlen(mm_database_root) - 1] = '\0';
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* ManagerHandle directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_handle(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ apr_size_t sl;
+ mm_server_conf_t *mmsc = MM_SRVCONF(cmd);
+
+ if (*arg == '/') {
+ sl = strlen(arg);
+ if (arg[sl - 1] == '/')
+ --sl;
+ mmsc->handle = apr_pstrndup(cmd->pool, arg, sl);
+ }
+ else {
+ if (!strcasecmp(arg, "Off"))
+ mmsc->handle = NULL;
+ else if (!strcasecmp(arg, "On")) {
+ if (!cmd->path || *(cmd->path) != '/')
+ return "ManagerHandle On must be declared inside <Location>";
+ sl = strlen(cmd->path);
+ if (sl > 1 && cmd->path[sl - 1] == '/')
+ --sl;
+ mmsc->handle = apr_pstrndup(cmd->pool, cmd->path, sl);
+ }
+ }
+ mmsc->handle_set = 1;
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* ServerAdvertise directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_advertise_m(cmd_parms *cmd, void *dummy,
+ const char *arg, const char *opt)
+{
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+
+ if (strcasecmp(arg, "Off") == 0)
+ mm_advertise_mode = mm_advertise_off;
+ else if (strcasecmp(arg, "On") == 0)
+ mm_advertise_mode = mm_advertise_on;
+ else
+ return "ServerAdvertise must be Off or On";
+ if (opt) {
+ const char *p = strstr(opt, "://");
+ if (p) {
+ mm_advertise_srvm = apr_pstrndup(cmd->pool, opt, p - opt);
+ opt = p + 3;
+ }
+ if (apr_parse_addr_port(&mm_advertise_srvs,
+ &mm_advertise_srvi,
+ &mm_advertise_srvp,
+ opt, cmd->pool) != APR_SUCCESS ||
+ !mm_advertise_srvs ||
+ !mm_advertise_srvp)
+ return "Invalid ServerAdvertise Address";
+ }
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* ManagerStrictParser directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_parse_strict(cmd_parms *cmd, void *dummy,
+ int flag)
+{
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+
+ mm_manager_strict = flag;
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* AdvertiseGroup directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_advertise_g(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+ if (mm_advertise_set)
+ return "Duplicate AdvertiseGroup directives are not allowed";
+
+ if (apr_parse_addr_port(&mm_advertise_adrs,
+ &mm_advertise_adsi,
+ &mm_advertise_port,
+ arg, cmd->pool) != APR_SUCCESS)
+ return "Invalid AdvertiseGroup address";
+ if (!mm_advertise_adrs)
+ return "Missing Ip part from AdvertiseGroup address";
+ if (!mm_advertise_port)
+ mm_advertise_port = MM_DEFAULT_ADVPORT;
+ mm_advertise_set = 1;
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* AdvertiseFrequency directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_advertise_f(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ apr_time_t s, u = 0;
+ const char *p;
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+ if ((p = strchr(arg, '.')) || (p = strchr(arg, ',')))
+ u = atoi(p + 1);
+
+ s = atoi(arg);
+ mm_advertise_freq = s * APR_USEC_PER_SEC + u * APR_TIME_C(1000);
+ if (mm_advertise_freq == 0)
+ return "Invalid AdvertiseFrequency value";
+
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* AdvertiseSecurityKey directive */
+/* */
+/*--------------------------------------------------------------------------*/
+static const char *mm_cmd_advertise_k(cmd_parms *cmd, void *dummy,
+ const char *arg)
+{
+ const char *errs = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+ if (errs != NULL)
+ return errs;
+ mm_advertise_skey = apr_pstrdup(cmd->pool, arg);
+ return NULL;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Manager Status module provider. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_status_hook(request_rec *r, int flags)
+{
+ mm_server_conf_t *mmsc = MM_SRVCONF(r);
+
+ if (flags & AP_STATUS_SHORT || mmsc->status == mm_status_off)
+ return OK;
+
+ ap_rputs("<hr />\n<h1>Manager Status</h1>\n", r);
+ ap_rputs("<table border=\"0\">\n", r);
+ ap_rvputs(r, "<tr><td>Database Root:</td><td>",
+ mm_database_root ? mm_database_root : "-",
+ "</td></tr>\n", NULL);
+ ap_rvputs(r, "<tr><td>Database Path:</td><td>",
+ mmgd->database_path ? mmgd->database_path : "-",
+ "</td></tr>\n", NULL);
+ ap_rvputs(r, "<tr><td>Handle Uri:</td><td>",
+ mmsc->handle ? mmsc->handle : "-",
+ "</td></tr>\n", NULL);
+ ap_rvputs(r, "<tr><td>ServerAdvertise:</td><td>",
+ mm_advertise_str[mm_advertise_mode],
+ "</td></tr>\n", NULL);
+ ap_rputs("</table>\n", r);
+ if (mmsc->status != mm_status_full)
+ return OK;
+
+ /* TODO: Add more statistical data
+ * for Full status.
+ */
+
+ return OK;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Pre config hook. */
+/* Hook our status provider to Status module */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_pre_config_hook(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ APR_OPTIONAL_HOOK(ap, status_hook, mm_status_hook,
+ NULL, NULL, APR_HOOK_MIDDLE);
+ mm_callback_initialize(pconf);
+
+ return OK;
+}
+
+static void * APR_THREAD_FUNC mm_mp_thread(apr_thread_t *thd, void *data)
+{
+ int f_time = 1;
+ apr_interval_time_t a_step = 0;
+ server_rec *s = (server_rec *)data;
+ is_mp_created = 1;
+
+ while (is_mp_running) {
+ apr_sleep(MM_TM_RESOLUTION);
+ if (!is_mp_running)
+ break;
+ if (mm_advertise_run) {
+ a_step += MM_TM_RESOLUTION;
+ if (a_step >= mm_advertise_freq || f_time) {
+ /* Run advertise */
+ mm_advertise_callback_run(mmdb_manager_rec->advertise_mode,
+ mmdb_manager_rec,
+ mm_advertise_server_cb);
+ a_step = 0;
+ f_time = 0;
+ }
+ }
+ if (!is_mp_running)
+ break;
+ /* Maintain database.
+ * Add new memory segments if requested from client
+ */
+ mmdb_maintain(s);
+ /* TODO: Implement actual work for parent thread */
+ if (!is_mp_running)
+ break;
+ }
+ is_mp_created = 0;
+ return NULL;
+}
+
+static void * APR_THREAD_FUNC mm_mc_thread(apr_thread_t *thd, void *data)
+{
+ int step = 0;
+ server_rec *s = (server_rec *)data;
+ is_mc_created = 1;
+
+ while (is_mc_running) {
+ apr_sleep(MM_TM_RESOLUTION);
+ if (!is_mc_running)
+ break;
+ if (++step >= MM_TM_MAINTAIN_STEP) {
+ mm_maintain_callback_run(mm_maintain_full);
+ step = 0;
+ }
+ else
+ mm_maintain_callback_run(mm_maintain_step);
+ /* TODO: Implement actual work for client thread */
+ if (!is_mc_running)
+ break;
+ }
+ is_mc_created = 0;
+ return NULL;
+}
+
+static apr_status_t mm_pconfig_cleanup(void *data);
+
+static apr_status_t mm_process_cleanup(void *data)
+{
+ int advertise_run = mm_advertise_run;
+
+ is_mp_running = 0;
+ mm_advertise_run = 0;
+ if (advertise_run && mmdb_manager_rec->advertise) {
+ mmdb_manager_rec->type = MM_ADVERTISE_STATUS;
+ mmdb_manager_rec->status = HTTP_FORBIDDEN;
+ mm_advertise_callback_run(mm_advertise_status, mmdb_manager_rec,
+ mm_advertise_server_cb);
+ }
+ if (is_mp_created) {
+ apr_sleep(1000);
+ /* Wait for the parent maintenance thread to finish */
+ while (is_mp_created) {
+ apr_sleep(MM_TM_RESOLUTION);
+ }
+ }
+ if (advertise_run && mmdb_manager_rec->advertise) {
+ mmdb_manager_rec->type = MM_ADVERTISE_STATUS;
+ mmdb_manager_rec->status = HTTP_GONE;
+ mm_advertise_callback_run(mm_advertise_status, mmdb_manager_rec,
+ mm_advertise_server_cb);
+ mma_group_leave();
+ }
+ /* We don't need the post_config cleanup to run,
+ */
+ apr_pool_cleanup_kill(mmgd->cpool, mmgd, mm_pconfig_cleanup);
+ if (mmgd->database_path) {
+ mmdb_close();
+ apr_dir_remove(mmgd->database_path, NULL);
+ }
+ mmgd = NULL;
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t mm_pconfig_cleanup(void *data)
+{
+ int advertise_run = mm_advertise_run;
+
+ is_mp_running = 0;
+ mm_advertise_run = 0;
+ if (advertise_run && mmdb_manager_rec->advertise) {
+ mmdb_manager_rec->type = MM_ADVERTISE_STATUS;
+ mmdb_manager_rec->status = HTTP_FORBIDDEN;
+ mm_advertise_callback_run(mm_advertise_status, mmdb_manager_rec,
+ mm_advertise_server_cb);
+ }
+
+ if (is_mp_created) {
+ apr_sleep(1000);
+ /* Wait for the parent maintenance thread to finish */
+ while (is_mp_created) {
+ apr_sleep(MM_TM_RESOLUTION);
+ }
+ }
+ if (advertise_run && mmdb_manager_rec->advertise) {
+ mmdb_manager_rec->type = MM_ADVERTISE_STATUS;
+ mmdb_manager_rec->status = HTTP_LOCKED;
+ mm_advertise_callback_run(mm_advertise_status, mmdb_manager_rec,
+ mm_advertise_server_cb);
+ mma_group_leave();
+ }
+ if (mmgd) {
+ /* Remove the process_cleanup.
+ * We need to reattach again because the
+ * module can be reloaded on different address
+ */
+ apr_pool_cleanup_kill(mmgd->ppool, mmgd, mm_process_cleanup);
+ }
+ return APR_SUCCESS;
+}
+
+
+static apr_status_t mm_cconfig_cleanup(void *data)
+{
+
+ is_mc_running = 0;
+
+ while (is_mc_created) {
+ /* Wait for the child maintenance thread to finish */
+ apr_sleep(MM_TM_RESOLUTION);
+ }
+ if (mmgd->database_path) {
+ mmdb_close();
+ }
+ return APR_SUCCESS;
+}
+
+/* Server advertise data provider */
+static apr_status_t advertise_server(mm_advertise_e mode, void *context,
+ char *data, apr_size_t size)
+{
+ apr_size_t n = 0;
+ mm_advertise_srv_t *s = (mm_advertise_srv_t *)context;
+ if (mode == mm_advertise_status)
+ return APR_SUCCESS;
+ n = apr_snprintf(data, size,
+ "X-Manager-Address: %s:%u" CRLF
+ "X-Manager-Url: %s" CRLF
+ "X-Manager-Protocol: %s" CRLF
+ "X-Manager-Version: " MM_MCMP_VERSION_STRING CRLF
+ "X-Manager-Host: %s" CRLF,
+ s->address, s->port,
+ s->handle,
+ s->protocol,
+ s->server->server_hostname);
+ if (n >= size)
+ return APR_EOF;
+ else
+ return APR_SUCCESS;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Post config hook. */
+/* Create management thread in parent and initializes Manager */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_post_config_hook(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ apr_status_t rv;
+ const char *pk = "manager_init_module_tag";
+ const char *lk = "manager_gmutex_name_tag";
+ apr_pool_t *pproc = s->process->pool;
+ apr_thread_t *tp;
+ mm_server_conf_t *mmsc = MM_GETCONF(s);
+#if !defined(WIN32)
+ mode_t mmode;
+#endif
+
+ apr_pool_userdata_get((void *)&mmgd, pk, pproc);
+ if (!mmgd) {
+ if (!(mmgd = apr_pcalloc(pproc, sizeof(mm_global_data_t))))
+ return apr_get_os_error();
+ apr_pool_create(&mmgd->ppool, pproc);
+ apr_pool_userdata_set(mmgd, pk, apr_pool_cleanup_null, pproc);
+ /* First time config phase -- skip. */
+ return OK;
+ }
+#if defined(WIN32)
+ {
+ const char *ppid = getenv("AP_PARENT_PID");
+ if (ppid) {
+ mm_parent_pid = atol(ppid);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "[%" APR_PID_T_FMT " - %" APR_PID_T_FMT
+ "] in child post config hook",
+ getpid(), mm_parent_pid);
+ return OK;
+ }
+ }
+#endif
+
+ /* Initialize parent data */
+ if (!mm_database_root)
+ mm_database_root = ap_server_root_relative(pconf, MM_DEFAULT_DBROOT);
+ if (!mm_lock_filename)
+ mm_lock_filename = apr_pstrcat(pconf, mm_database_root,
+ MM_LOCK_NAME, NULL);
+
+ apr_pool_userdata_get((void *)&mm_manager_mutex, lk, pproc);
+ if (!mm_manager_mutex) {
+ if ((rv = apr_global_mutex_create(&mm_manager_mutex,
+ mm_lock_filename,
+ APR_LOCK_DEFAULT,
+ pproc)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: could not create global mutex: %s",
+ mm_lock_filename);
+ return rv;
+
+ }
+#ifdef AP_NEED_SET_MUTEX_PERMS
+ rv = unixd_set_global_mutex_perms(mm_manager_mutex);
+ if (rv != APR_SUCCESS) {
+ apr_global_mutex_destroy(mm_manager_mutex);
+ mm_manager_mutex = NULL;
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: could not modify global mutex: %s",
+ mm_lock_filename);
+ return rv;
+ }
+#endif
+ apr_pool_userdata_set(mm_manager_mutex, lk, apr_pool_cleanup_null, pproc);
+ }
+ if (!mmgd->database_path) {
+#if !defined(WIN32)
+ mmode = umask(022);
+#endif
+ mmgd->database_path = ap_append_pid(pproc, mm_database_root, "/");
+ rv = apr_dir_make(mmgd->database_path, APR_FPROT_OS_DEFAULT, pconf);
+ if (rv != APR_SUCCESS) {
+ if (!APR_STATUS_IS_EEXIST(rv)) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: could not create database root %s.",
+ mmgd->database_path);
+ return rv;
+ }
+ }
+ }
+#if !defined(WIN32)
+ /* Allow attaching from child processes
+ * when parent is running as root
+ */
+ umask(0);
+#endif
+ if ((rv = mmdb_create(mmgd->database_path, pproc)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: could not create database at %s",
+ mmgd->database_path);
+ return rv;
+ }
+ else
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "mod_manager: shared memory database created at %s",
+ mmgd->database_path);
+#if !defined(WIN32)
+ umask(mmode);
+#endif
+ /* Init database */
+ if (mmgd->generation)
+ mm_run_resource_providers(mmsc, mm_resource_open, pproc);
+ else
+ mm_run_resource_providers(mmsc, mm_resource_init, pproc);
+ if (!(mmdb_manager_rec = asmm_slot(mmdb_table_getn(MMDB_MANAGER), 0))) {
+ rv = apr_get_os_error();
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: Manager database record");
+ return rv;
+ }
+
+ if (!mmgd->generation) {
+ /* Favor dynamic configuration */
+ mmdb_manager_rec->strict = mm_manager_strict;
+ if (mm_advertise_skey) {
+ apr_md5_ctx_t mc;
+ apr_md5_init(&mc);
+ apr_md5_update(&mc, mm_advertise_skey, strlen(mm_advertise_skey));
+ apr_md5_final(mmdb_manager_rec->ssalt, &mc);
+ }
+ }
+
+ /* Check if we have advertise set */
+ if (mm_advertise_mode != mm_advertise_off && mm_advertise_set)
+ mm_advertise_run = 1;
+
+ /* Figure out the advertise address if not set */
+ if (mm_advertise_run && !mm_advertise_srvs) {
+ /* Figure out the Listening address */
+ ap_listen_rec *lr;
+ for (lr = ap_listeners; lr; lr = lr->next) {
+ if (!lr->active)
+ continue;
+ if (IS_INADDR_ANY(lr->bind_addr))
+ continue;
+#if APR_HAVE_IPV6
+ if (IS_IN6ADDR_ANY(lr->bind_addr))
+ continue;
+#endif
+ apr_sockaddr_ip_get(&mm_advertise_srvs, lr->bind_addr);
+ mm_advertise_srvp = lr->bind_addr->port;
+ mm_advertise_srvm = (char *)lr->protocol;
+ if (mm_advertise_srvs &&
+ !strcmp(mm_advertise_srvs, "127.0.0.1") &&
+ !strcmp(mm_advertise_srvs, "::1")) {
+ mm_advertise_srvs = NULL;
+ continue;
+ }
+ else
+ break;
+ }
+ if (!mm_advertise_srvs) {
+ for (lr = ap_listeners; lr; lr = lr->next) {
+ if (!lr->active)
+ continue;
+ if (IS_INADDR_ANY(lr->bind_addr)) {
+ apr_sockaddr_ip_get(&mm_advertise_srvs, lr->bind_addr);
+ mm_advertise_srvp = lr->bind_addr->port;
+ break;
+ }
+ }
+ }
+ if (!mm_advertise_srvs) {
+ /* Use the first one, and hope the admin configured
+ * httpd correctly.
+ */
+ apr_sockaddr_ip_get(&mm_advertise_srvs, ap_listeners->bind_addr);
+ mm_advertise_srvp = ap_listeners->bind_addr->port;
+ mm_advertise_srvm = (char *)ap_listeners->protocol;
+ }
+ }
+ if (mm_advertise_run) {
+ rv = mma_group_join(mm_advertise_adrs, mm_advertise_port, pconf);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ "mod_manager: multicast join failed for %s:%d.",
+ mm_advertise_adrs, mm_advertise_port);
+ mm_advertise_run = 0;
+ }
+ }
+ memset(&mm_advs_server, 0, sizeof(mm_advertise_srv_t));
+
+ if (mm_advertise_run) {
+ server_rec *su = s;
+ server_rec *sr = s;
+ /* Setup Advertise info data */
+ if (mmsc->handle && !strcmp(mmsc->handle, MM_DEFAULT_HANDLE)) {
+ while (sr->next) {
+ mm_server_conf_t *mc = MM_GETCONF(sr->next);
+ sr = sr->next;
+ if (mc->handle_set && mc->handle) {
+ mmsc = mc;
+ su = sr;
+ break;
+ }
+ }
+ }
+ mmdb_manager_rec->advertise_mode = mm_advertise_mode;
+ mmdb_manager_rec->type = MM_ADVERTISE_SERVER;
+ mm_advs_server.address = mm_advertise_srvs;
+ mm_advs_server.port = mm_advertise_srvp;
+ mm_advs_server.protocol = mm_advertise_srvm;
+ mm_advs_server.server = su;
+ if (mmsc->handle_set && mmsc->handle)
+ mm_advs_server.handle = mmsc->handle;
+ else
+ mm_advs_server.handle = mmdb_manager_rec->srvid;
+ mm_register_advertise_callback(pconf, &mm_advs_server,
+ advertise_server);
+ }
+ mmdb_manager_rec->status = HTTP_OK;
+ mmdb_manager_rec->advertise = mm_advertise_run;
+ mmdb_manager_rec->generation = mmgd->generation;
+ /* Create parent management thread */
+ is_mp_running = 1;
+ rv = apr_thread_create(&tp, NULL, mm_mp_thread, s, pconf);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: parent apr_thread_create");
+ return rv;
+ }
+ apr_thread_detach(tp);
+
+ /* Create cleanup pool that will be destroyed first
+ * in future use new apr_pool_pre_cleanup_register from APR 1.3
+ */
+ apr_pool_create(&mmgd->cpool, pconf);
+ apr_pool_cleanup_register(mmgd->cpool, mmgd, mm_pconfig_cleanup,
+ apr_pool_cleanup_null);
+ if (mmgd->generation++) {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ "Manager/%d reinitialized for process %" APR_PID_T_FMT,
+ MM_MMN, getpid());
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ "Manager/%d initialized for process %" APR_PID_T_FMT,
+ MM_MMN, getpid());
+ }
+
+ apr_pool_cleanup_register(mmgd->ppool, mmgd, mm_process_cleanup,
+ apr_pool_cleanup_null);
+ return OK;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Child init hook. */
+/* Create management thread in child and initializes Manager in child */
+/* */
+/*--------------------------------------------------------------------------*/
+static void mm_child_init_hook(apr_pool_t *p, server_rec *s)
+{
+ apr_status_t rv;
+ apr_pool_t *cp;
+ apr_thread_t *tp;
+ mm_server_conf_t *mmsc = MM_GETCONF(s);
+
+#if !defined(WIN32)
+ /* Win32 parent pid was determined in
+ * post config hook.
+ * Use getppid() for posix.
+ */
+ mm_parent_pid = getppid();
+#endif
+ if (mm_parent_pid == -1) {
+#if !defined(WIN32)
+ rv = apr_get_os_error();
+#else
+ rv = APR_EBADF;
+#endif
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: parent pid");
+ return;
+ }
+ mm_child_started = apr_time_now();
+ /* Initialize child data */
+ if (!mmgd)
+ mmgd = apr_pcalloc(p, sizeof(mm_global_data_t));
+
+ if (!mm_database_root)
+ mm_database_root = ap_server_root_relative(p, MM_DEFAULT_DBROOT);
+ mm_lock_filename = apr_pstrcat(p, mm_database_root, MM_LOCK_NAME, NULL);
+ if ((rv = apr_global_mutex_child_init(&mm_manager_mutex,
+ mm_lock_filename,
+ p)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: could not open global mutex: %s",
+ mm_lock_filename);
+ return;
+ }
+ mmgd->database_path = apr_psprintf(p, "%s/%" APR_PID_T_FMT,
+ mm_database_root, mm_parent_pid);
+ if ((rv = mmdb_open(mmgd->database_path, p)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
+ "mod_manager: could not open database at %s.",
+ mmgd->database_path);
+ mmgd->database_path = NULL;
+ return;
+ }
+ /* Init database */
+ mm_run_resource_providers(mmsc, mm_resource_child_init, p);
+ if (!(mmdb_manager_rec = asmm_slot(mmdb_table_getn(MMDB_MANAGER), 0))) {
+ rv = apr_get_os_error();
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: Manager database record missing");
+ return;
+ }
+ /* Remember generation so we can check later
+ * if we are dormant child process.
+ */
+ mm_generation = mmdb_manager_rec->generation;
+ /* Create parent management thread */
+ is_mc_running = 1;
+ rv = apr_thread_create(&tp, NULL, mm_mc_thread, s, p);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
+ "mod_manager: child apr_thread_create");
+ return;
+ }
+ apr_thread_detach(tp);
+ apr_pool_create(&cp, p);
+ apr_pool_cleanup_register(cp, s, mm_cconfig_cleanup,
+ apr_pool_cleanup_null);
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "initialized child %" APR_PID_T_FMT
+ " from parent process %" APR_PID_T_FMT,
+ getpid(), mm_parent_pid);
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Post read request handler hook. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_post_read_request_hook(request_rec *r)
+{
+ const char *path_cmd = NULL;
+ mm_server_conf_t *mmsc = MM_SRVCONF(r);
+
+ if (!is_mc_running)
+ return DECLINED;
+
+ return DECLINED;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Translate name handler hook. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_translate_name_hook(request_rec *r)
+{
+ const char *path_cmd = NULL;
+ mm_server_conf_t *mmsc = MM_SRVCONF(r);
+
+ if (!is_mc_running)
+ return DECLINED;
+
+ return DECLINED;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Map to storage handler hook. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_map_to_storage_hook(request_rec *r)
+{
+ const char *path_cmd = NULL;
+ mm_server_conf_t *mmsc = MM_SRVCONF(r);
+
+ if (!is_mc_running)
+ return DECLINED;
+
+ if (mmdb_manager_rec->generation != mm_generation) {
+ /* XXX: See if this can actually happen or not */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: generation missmatch detected -- "
+ "declining map to storage.");
+ return DECLINED;
+ }
+
+
+ if (mmsc->handle_set && mmsc->handle && mmsc->server == r->server &&
+ !strncmp(r->uri, mmsc->handle, strlen(mmsc->handle))) {
+ /* Check if we have /foo or /foo/ */
+ if (r->uri[strlen(mmsc->handle)] == '\0' ||
+ r->uri[strlen(mmsc->handle)] == '/') {
+ r->handler = mm_handler_name;
+ return OK;
+ }
+ }
+ else if (!strncmp(r->uri, mmdb_manager_rec->srvid,
+ APR_UUID_FORMATTED_LENGTH)) {
+ if (r->uri[APR_UUID_FORMATTED_LENGTH + 1] == '\0' ||
+ r->uri[APR_UUID_FORMATTED_LENGTH + 1] == '/') {
+ r->handler = mm_handler_name;
+ return OK;
+ }
+ }
+
+ /* Stage 1: Find the Host */
+
+ /* Stage 2: Find the Application */
+
+ /* Stage 3: Find the Balancer */
+
+ return DECLINED;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Manager request handler hook. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_handler_manager(request_rec *r)
+{
+ apr_status_t rc;
+ int status = OK;
+ int pi = 0;
+ const char *cmd = NULL;
+ const char *header = NULL;
+ const apr_array_header_t *ca;
+ apr_table_entry_t *ce;
+ apr_table_t *ctb;
+ mm_server_conf_t *mmsc = MM_SRVCONF(r);
+
+ ap_set_content_type(r, "text/plain");
+ /*
+ * If we're only supposed to send header information (HEAD request), we're
+ * already there.
+ */
+ if (r->header_only) {
+ return OK;
+ }
+
+ if (mmsc->handle_set && mmsc->handle)
+ pi = ap_find_path_info(mmsc->handle, r->uri);
+ else
+ pi = ap_find_path_info(mmdb_manager_rec->srvid, r->uri);
+ if (pi > 0) {
+ cmd = r->uri + pi + 1;
+ if (!strlen(cmd))
+ cmd = NULL;
+ }
+ ctb = apr_table_make(r->pool, 15);
+ apr_table_setn(ctb, MMS_COOKIE_COMMAND, "");
+ /* Parse Header */
+ if ((header = apr_table_get(r->headers_in, MM_RESHEADER_NAME))) {
+ if ((rc = mmc_cookie_parse(ctb, header, r->pool)) != APR_SUCCESS) {
+ /* Deal with error in parser */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: parsing " MM_RESHEADER_NAME
+ " header: %s", header);
+ mm_send_response_ex(r, mm_response_error, rc, NULL);
+ return OK;
+ }
+ }
+ /* Parse Query arguments */
+ if (r->args) {
+ if ((status = ap_unescape_url_keep2f(r->args)) != OK) {
+ /* Deal with error in query arguments */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: unescaping request arguments: %s",
+ r->args);
+ return OK;
+ }
+ if ((rc = mmc_cookie_parse(ctb, r->args, r->pool)) != APR_SUCCESS) {
+ /* Deal with error in parser */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: parsing request arguments: %s",
+ r->args);
+ mm_send_response_ex(r, mm_response_error, rc, NULL);
+ return OK;
+ }
+ }
+ /* Always favor the path info command */
+ if (cmd)
+ apr_table_setn(ctb, MMS_COOKIE_COMMAND, cmd);
+ else if ((header = apr_table_get(r->headers_in, MM_CMDHEADER_NAME)))
+ apr_table_setn(ctb, MMS_COOKIE_COMMAND, header);
+
+ cmd = apr_table_get(ctb, MMS_COOKIE_COMMAND);
+ if (*cmd == '\0') {
+ /* No command present.
+ * Report Protocol version and exit
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: " MMS_COOKIE_COMMAND " not present");
+ mm_send_response_ex(r, mm_response_version, 0, NULL);
+ return OK;
+ }
+ if ((mcmp_command_type = mm_mcmp_command_get(cmd)) == mm_mcmp_unknown) {
+ /* Unknown command detected.
+ * Report Protocol version and exit
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown " MMS_COOKIE_COMMAND ": %s", cmd);
+ mm_send_response_ex(r, mm_response_version, 0, NULL);
+ return OK;
+ }
+ apr_table_unset(ctb, MMS_COOKIE_COMMAND);
+ if (mcmp_command_type != mm_mcmp_info) {
+ /* Lock the database for commands
+ * that can change the database
+ */
+ if ((rc = mm_manager_dolock()) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server,
+ "mod_manager: locking database");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ /* Run parser */
+ ca = apr_table_elts(ctb);
+ ce = (apr_table_entry_t *)ca->elts;
+ if (ca->nelts) {
+ /* The first key should be ResourceType
+ * and val is ResourceType name
+ */
+ const char *rt = ce[0].key;
+ const char *rn = ce[0].val;
+ mm_resource_provider_t *rp;
+
+ if (apr_fnmatch_test(rt)) {
+ int rcnt = 0;
+ mm_resource_list_t *rl;
+ rl = mm_list_resource_providers(r->pool);
+ if (!rl) {
+ /* We should have at least one resouce
+ */
+ mm_send_response_ex(r, mm_response_version, 0, NULL);
+ goto cleanup;
+ }
+ while ((rp = rl->provider) != NULL) {
+ int exe_provider = 1;
+ if (rp->id == MMDB_SERVER || rp->id == MMDB_MANAGER) {
+ ap_rvputs(r, "@", rp->name, NULL);
+ if (ca->nelts > 1)
+ ap_rputs(": ", r);
+ else {
+ ap_rputs(CRLF, r);
+ exe_provider = 0;
+ }
+ }
+ if (rp->id == MMDB_APPLICATION)
+ exe_provider = 0;
+ if (exe_provider &&
+ apr_fnmatch(rt, rp->name, MM_FFNMATCH) == APR_SUCCESS) {
+ /* We have a matching resource type */
+ rc = (*rp->func)(mmsc,
+ mcmp_command_type,
+ rn, NULL, 0, NULL,
+ ctb, 1, r);
+ if (rc != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: resource provider: %s",
+ rp->name);
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ goto cleanup;
+ }
+ rcnt++;
+ }
+ if (!rl->next)
+ break;
+ rl = rl->next;
+ }
+ if (!rcnt) {
+ /* No Resources matches.
+ * Report Unknown resource type and exit
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: no resource matches : %s", rt);
+ mm_send_response_ex(r, mm_response_utype, 0, rt, NULL);
+ goto cleanup;
+ }
+ }
+ else if (!(rp = mm_lookup_resource_provider(rt))) {
+ /* Unknown resource detected.
+ * Report Unknown resource type and exit
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown resource type : %s", rt);
+ mm_send_response_ex(r, mm_response_utype, 0, rt, NULL);
+ goto cleanup;
+ }
+ else {
+ rc = (*rp->func)(mmsc, mcmp_command_type,
+ rn, NULL, 0, NULL, ctb, 1, r);
+ if (rc != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server,
+ "mod_manager: resource provider: %s",
+ rp->name);
+ status = HTTP_INTERNAL_SERVER_ERROR;
+ goto cleanup;
+ }
+ }
+ }
+ else {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: missing resource type");
+ }
+ /* Update the advertise mode */
+ if (mmdb_manager_rec->advertise_mode != mm_advertise_off) {
+ mmdb_manager_rec->type = MM_ADVERTISE_STATUS;
+ mmdb_manager_rec->status = HTTP_OK;
+ mmdb_manager_rec->advertise_mode = mm_advertise_status;
+ }
+cleanup:
+ if (mcmp_command_type != mm_mcmp_info) {
+ /* Unlock the Manager */
+ mm_manager_unlock();
+ }
+ return status;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Request handler hook. */
+/* */
+/*--------------------------------------------------------------------------*/
+static int mm_handler_hook(request_rec *r)
+{
+ if (!is_mc_running)
+ return DECLINED;
+ if (mmdb_manager_rec->generation != mm_generation) {
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: generation missmatch detected -- "
+ "declining request.");
+ return DECLINED;
+ }
+ /* Is this for us? */
+ if (!strcasecmp(r->handler, mm_handler_name))
+ return mm_handler_manager(r);
+
+ return DECLINED;
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* List of directives specific to our module. */
+/* */
+/*--------------------------------------------------------------------------*/
+static const command_rec mm_cmds[] =
+{
+ AP_INIT_TAKE1(
+ "ManagerStatus", /* directive name */
+ mm_cmd_status, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Manager status to one of: On | Off | Full"
+ ),
+ AP_INIT_TAKE1(
+ "ManagerDatabaseRoot", /* directive name */
+ mm_cmd_dbroot, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Path where the Manager database will be created"
+ ),
+ AP_INIT_TAKE1(
+ "ManagerHandle", /* directive name */
+ mm_cmd_handle, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF|ACCESS_CONF, /* where available */
+ "Uri on which the Manager will handle directives."
+ ),
+ AP_INIT_FLAG(
+ "ManagerParseStrict", /* directive name */
+ mm_cmd_parse_strict, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "On for strict command parsing mode"
+ ),
+ AP_INIT_TAKE12(
+ "ServerAdvertise", /* directive name */
+ mm_cmd_advertise_m, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Server advertise mode: On | Off [Address]"
+ ),
+ AP_INIT_TAKE1(
+ "AdvertiseGroup", /* directive name */
+ mm_cmd_advertise_g, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Multicast group address"
+ ),
+ AP_INIT_TAKE1(
+ "AdvertiseFrequency", /* directive name */
+ mm_cmd_advertise_f, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Advertise frequency in seconds[.miliseconds]"
+ ),
+ AP_INIT_TAKE1(
+ "AdvertiseSecurityKey", /* directive name */
+ mm_cmd_advertise_k, /* config action routine */
+ NULL, /* argument to include in call */
+ RSRC_CONF, /* where available */
+ "Advertise security key"
+ ),
+ {NULL}
+
+};
+
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* Which functions are responsible for which hooks in the server. */
+/* */
+/*--------------------------------------------------------------------------*/
+static void mm_register_hooks(apr_pool_t *p)
+{
+
+ /* Fixup before and translate and after mod_rewrite.
+ */
+ static const char *const after_rewrite[] = { "mod_rewrite.c", NULL};
+ static const char *const before_rewrite[] = { "mod_rewrite.c", NULL};
+ static const char *const before_proxy[] = { "mod_proxy.c", NULL};
+
+ /* Only the mpm_winnt has child init hook handler.
+ * Make sure that we are called after the mpm child init handler
+ * initializes.
+ */
+ static const char *const after_mpm[] = { "mpm_winnt.c", NULL};
+
+ /* Pre config handling
+ */
+ ap_hook_pre_config(mm_pre_config_hook,
+ NULL,
+ NULL,
+ APR_HOOK_MIDDLE);
+
+ /* Post config handling
+ */
+ ap_hook_post_config(mm_post_config_hook,
+ NULL,
+ NULL,
+ APR_HOOK_LAST);
+
+ /* Child init hook
+ */
+ ap_hook_child_init(mm_child_init_hook,
+ after_mpm,
+ NULL,
+ APR_HOOK_MIDDLE);
+
+ /* Request handler hook
+ */
+ ap_hook_handler(mm_handler_hook,
+ NULL,
+ NULL,
+ APR_HOOK_MIDDLE);
+
+ /* Translate name handler hook
+ */
+ ap_hook_translate_name(mm_translate_name_hook,
+ after_rewrite,
+ NULL,
+ APR_HOOK_FIRST);
+
+ /* Post read request handler hook
+ */
+ ap_hook_post_read_request(mm_post_read_request_hook,
+ NULL,
+ before_proxy,
+ APR_HOOK_FIRST);
+
+ /* Map to storage handler hook
+ */
+ ap_hook_map_to_storage(mm_map_to_storage_hook,
+ NULL,
+ NULL,
+ APR_HOOK_FIRST);
+
+ /* Register resource objecst
+ */
+ mm_register_resource_manager(p);
+ mm_register_resource_server(p);
+ mm_register_resource_app_pool(p);
+ mm_register_resource_balancer(p);
+ mm_register_resource_host(p);
+ mm_register_resource_member(p);
+ mm_register_resource_application(p);
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* */
+/* The list of callback routines and data structures that provide */
+/* the static hooks into our module from the other parts of the server. */
+/* */
+/*--------------------------------------------------------------------------*/
+module AP_MODULE_DECLARE_DATA manager_module =
+{
+ STANDARD20_MODULE_STUFF,
+ NULL, /* per-directory config creator */
+ NULL, /* dir config merger */
+ mm_create_server_config, /* server config creator */
+ mm_merge_server_config, /* server config merger */
+ mm_cmds, /* command table */
+ mm_register_hooks /* set up other request processing hooks */
+};
Property changes on: sandbox/aloha/httpd/modules/manager/mm_module.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_node.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_node.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_node.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,766 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Node object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+static int server_limit = 0;
+static int thread_limit = 0;
+static int max_clients = 0;
+static int max_childs = 0;
+static int max_requests_per_child = 0;
+static int max_threads_per_child = 0;
+
+static const char *member_params[] = {
+ "",
+ "Balancer",
+ "Type",
+ "Address",
+ "Port",
+ "Route",
+ "Domain",
+ "Ping",
+ "MaxConnections",
+ "MinConnections",
+ "MaxClients",
+ "TTL",
+ "LF",
+ "Distance",
+ "Activation",
+ "FlushMode",
+ "FlushTimeout",
+ /* Statistical data */
+ "State",
+ "Error",
+ "Busy",
+ "Connected",
+ "Elected",
+ "StickySessions",
+ "ClientErrors",
+ "NodeErrors",
+ "Trace",
+ "TraceErrors",
+ "Readed",
+ "Transferred",
+ NULL
+};
+
+static const char *get_balancer_name(apr_uint32_t id)
+{
+ mmdb_balancer_t *balancer;
+ asmm_slotmem_t *balancer_db = mmdb_table_getn(MMDB_BALANCER);
+
+ if ((balancer = asmm_slot(balancer_db, id))) {
+ return balancer->name;
+ }
+ return NULL;
+}
+
+static const char *get_flush_name(mm_flush_mode_e mode)
+{
+ switch(mode) {
+ case mm_flush_wait:
+ return "T";
+ break;
+ case mm_flush_auto:
+ return "A";
+ break;
+ }
+ return "N";
+}
+
+static mm_flush_mode_e get_flush_mode(const char *mode)
+{
+ switch(apr_toupper(*mode)) {
+ case 'T':
+ return mm_flush_wait;
+ break;
+ case 'A':
+ return mm_flush_auto;
+ break;
+ }
+ return mm_flush_none;
+}
+
+static apr_status_t add_app_members(apr_uint32_t member_id,
+ apr_uint32_t balancer_id)
+{
+ apr_uint32_t napp = 0;
+ apr_uint32_t nhost = 0;
+ mmdb_host_t *host;
+ mmdb_app_t *app;
+ mmdb_memberapp_t *memberapp;
+ asmm_slotmem_t *host_db = mmdb_table_getn(MMDB_HOST);
+ asmm_slotmem_t *app_db = mmdb_table_getn(MMDB_APPLICATION);
+ asmm_slotmem_t *memberapp_db = mmdb_table_getn(MMDB_MEMBERAPP);
+
+ while ((host = asmm_slot_next(host_db, &nhost))) {
+ if (host->balancer_id != balancer_id)
+ continue;
+ napp = 0;
+ while ((app = asmm_slot_next(app_db, &napp))) {
+ if (app->host_id != (nhost - 1))
+ continue;
+ if (!(memberapp = asmm_salloc(memberapp_db)))
+ return apr_get_os_error();
+ memberapp->app_id = napp - 1;
+ memberapp->member_id = member_id;
+ memberapp->state = app->state;
+ }
+ }
+ return APR_SUCCESS;
+}
+
+static void del_app_members(apr_uint32_t member_id)
+{
+ apr_uint32_t next = 0;
+ mmdb_memberapp_t *memberapp;
+ asmm_slotmem_t *memberapp_db = mmdb_table_getn(MMDB_MEMBERAPP);
+
+ while ((memberapp = asmm_slot_next(memberapp_db, &next))) {
+ if (memberapp->member_id != member_id)
+ continue;
+ asmm_free(memberapp_db, memberapp);
+ }
+}
+
+
+static void rdo_member_info_print(int pi, int pp,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ char buf[512];
+ const char *p;
+
+ if (pp) {
+ ap_rvputs(r, member_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* Balancer */
+ ap_rvputs(r, get_balancer_name(mem->balancer_id), NULL);
+ break;
+ case 2: /* Type */
+ ap_rputs(mm_protocol_name_get(mem->type), r);
+ break;
+ case 3: /* Address */
+ ap_rvputs(r, mem->address, NULL);
+ break;
+ case 4: /* Port */
+ ap_rprintf(r, "%u", mem->port);
+ break;
+ case 5: /* Route */
+ ap_rvputs(r, mem->route, NULL);
+ break;
+ case 6: /* Domain */
+ ap_rvputs(r, mem->domain, NULL);
+ break;
+ case 7: /* Ping */
+ ap_rprintf(r, "%u", mem->ping);
+ break;
+ case 8: /* MaxConnections */
+ ap_rprintf(r, "%u", mem->max_conn);
+ break;
+ case 9: /* MinConnections */
+ ap_rprintf(r, "%u", mem->min_conn);
+ break;
+ case 10: /* MaxClients */
+ ap_rprintf(r, "%u", mem->max_clients);
+ break;
+ case 11: /* TTL */
+ ap_rprintf(r, "%u", mem->ttl);
+ break;
+ case 12: /* LF */
+ ap_rprintf(r, "%u", mem->lf);
+ break;
+ case 13: /* Distance */
+ ap_rprintf(r, "%u", mem->distance);
+ break;
+ case 14: /* Activation */
+ ap_rputs(mm_state_name_get(mem->activation), r);
+ break;
+ case 15: /* FlushMode */
+ ap_rputs(get_flush_name(mem->flush), r);
+ break;
+ case 16: /* FlushTimeout */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(mem->flush_wait));
+ break;
+ case 17: /* State */
+ ap_rputs(mm_state_name_get(mem->state), r);
+ break;
+ case 18: /* Error */
+ if (!(p = mm_strerror(mem->err))) {
+ if (!(p = apr_strerror(mem->err, buf, sizeof(buf))))
+ p = "Unknown Error";
+ }
+ if (pp)
+ ap_rprintf(r, "\"%d: %s\"", mem->err, p);
+ else
+ ap_rprintf(r, "%d: %s", mem->err, p);
+ break;
+ case 19: /* Busy */
+ ap_rprintf(r, "%u", mem->busy);
+ break;
+ case 20: /* Connected */
+ ap_rprintf(r, "%u", mem->connected);
+ break;
+ case 21: /* Elected */
+ ap_rprintf(r, "%u", mem->elected);
+ break;
+ case 22: /* StickySessions */
+ ap_rprintf(r, "%u", mem->ssessions);
+ break;
+ case 23: /* ClientErrors */
+ ap_rprintf(r, "%u", mem->err_client);
+ break;
+ case 24: /* NodeErrors */
+ ap_rprintf(r, "%u", mem->err_node);
+ break;
+ case 25: /* Trace */
+ ap_rprintf(r, "%u", mem->trace);
+ break;
+ case 26: /* TraceErrors */
+ ap_rprintf(r, "%u", mem->err_trace);
+ break;
+ case 27: /* Readed */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->readed);
+ break;
+ case 28: /* Transferred */
+ ap_rprintf(r, "%" APR_UINT64_T_FMT, mem->transferred);
+ break;
+ }
+}
+
+/* Dump Member info */
+static void rdo_member_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (member_params[j]) {
+ if (apr_fnmatch(ce[i].key, member_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_member_info_print(m, wcm, mem, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (member_params[j]) {
+ if (apr_fnmatch(ce[i].key, member_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_member_info_print(j, 1, mem, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_member_info_print(j, 1, mem, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static apr_status_t rdo_member_config_do(int pi,
+ const char *value,
+ mmdb_member_t *mem,
+ request_rec *r)
+{
+ int i;
+
+ switch (pi) {
+ case 2: /* Type */
+ if (mem->state == mm_state_stopped)
+ mem->type = mm_protocol_get(value);
+ else
+ return MME_EPERM;
+ break;
+ case 3: /* Address */
+ if (mem->state == mm_state_stopped)
+ MM_SSAFE_COPY(mem->address, value);
+ else
+ return MME_EPERM;
+ break;
+ case 4: /* Port */
+ if (mem->state == mm_state_stopped)
+ mem->port = atoi(value);
+ else
+ return MME_EPERM;
+ break;
+ case 5: /* Route */
+ MM_SSAFE_COPY(mem->route, value);
+ break;
+ case 6: /* Domain */
+ MM_SSAFE_COPY(mem->domain, value);
+ break;
+ case 7: /* Ping */
+ mem->ping = atoi(value);
+ break;
+ case 8: /* MaxConnections */
+ i = atoi(value);
+ if (i < 1 || i > max_threads_per_child)
+ return MME_EINVAL;
+ else
+ mem->max_conn = i;
+ break;
+ case 9: /* MinConnections */
+ i = atoi(value);
+ if (i < 1 || i > (int)mem->max_conn)
+ return MME_EINVAL;
+ else
+ mem->min_conn = i;
+ break;
+ case 10: /* MaxClients */
+ i = atoi(value);
+ if (i < 1 || i > max_clients)
+ return MME_EINVAL;
+ else
+ mem->max_clients = i;
+ break;
+ case 11: /* TTL */
+ mem->ttl = atoi(value);
+ break;
+ case 12: /* LF */
+ mem->lf = atoi(value);
+ break;
+ case 13: /* Distance */
+ mem->distance = atoi(value);
+ break;
+ case 14: /* Activation */
+ mem->activation = mm_state_get(value);
+ break;
+ case 15: /* FlushMode */
+ mem->flush = get_flush_mode(value);
+ break;
+ case 16: /* FlushTimeout */
+ mem->flush_wait = atoi(value) * APR_TIME_C(1000);
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+/* Configure Member */
+static int rdo_member_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ apr_uint32_t member_id,
+ mmdb_member_t *member,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else {
+ while (member_params[j]) {
+ if (!strcasecmp(ce[i].key, member_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_member_config_do(j, ce[i].val,
+ member, r)) != APR_SUCCESS) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static apr_status_t rdo_member(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int wcm;
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+ apr_uint32_t next = 0;
+ mmdb_member_t *member;
+
+ asmm_slotmem_t *member_db = mmdb_table_getn(MMDB_MEMBER);
+
+ if (!member_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty member name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ }
+ wcm = apr_fnmatch_test(name);
+ while ((member = asmm_slot_next(member_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, member->name,
+ MM_FFNMATCH) != APR_SUCCESS)
+ continue;
+ }
+ else if (strcasecmp(name, member->name))
+ continue;
+ if (cmd_offset < ca->nelts) {
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[cmd_offset].key);
+ if (mp) {
+ apr_status_t rc;
+ if (mp == this_provider) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] recursion not allowed: %s",
+ mm_mcmp_command_name_get(cmd),
+ this_provider->name);
+ return APR_SUCCESS;
+ }
+ rc = (*mp->func)(cfg, cmd,
+ ce[cmd_offset].val, this_provider,
+ next - 1, member,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS) {
+ }
+ wdone++;
+ if (wcm)
+ continue;
+ else
+ break;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm) {
+ ap_rvputs(r, MM_RES_MEMBER "/", member->name, NULL);
+ if (cmd_offset < ca->nelts)
+ ap_rputs(": ", r);
+ else
+ ap_rputs(CRLF, r);
+ }
+ if (cmd_offset < ca->nelts)
+ rdo_member_info(cmd_table, cmd_offset, wcm, member, r);
+ break;
+ case mm_mcmp_enable:
+ member->state = mm_state_active;
+ member->activation = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ member->state = mm_state_disabled;
+ member->activation = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ member->state = mm_state_stopped;
+ member->activation = mm_state_stopped;
+ break;
+ case mm_mcmp_reset:
+ /* Reset statistical data */
+ member->elected = 0;
+ member->ssessions = 0;
+ member->err_client = 0;
+ member->err_node = 0;
+ member->err_trace = 0;
+ member->trace = 0;
+ member->readed = 0;
+ member->transferred = 0;
+ break;
+ case mm_mcmp_delete:
+ if (member->state != mm_state_stopped) {
+ /* Member must be stopped before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Member not stopped: %s",
+ member->name);
+ return APR_SUCCESS;
+ }
+ else {
+ /* Delete Member entry */
+ mmdb_balancer_t *pbal = NULL;
+ if (member->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ member->balancer_id);
+ del_app_members(next - 1);
+ asmm_free(member_db, member);
+ if (pbal && pbal->members)
+ pbal->members--;
+ }
+ break;
+ case mm_mcmp_config:
+ if (prev && prev->id == MMDB_BALANCER) {
+ mmdb_balancer_t *nbal = (mmdb_balancer_t *)prev_rec;
+ if (prev_id != member->balancer_id) {
+ mmdb_balancer_t *pbal = NULL;
+ if (member->balancer_id)
+ pbal = asmm_slot(mmdb_table_getn(MMDB_MEMBER),
+ member->balancer_id);
+ /* Attach the Member to another Balancer */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "mod_manager: Member: %s assigned to "
+ "Balancer: %s",
+ member->name, nbal->name);
+ member->balancer_id = prev_id;
+ nbal->members++;
+ if (pbal && pbal->members)
+ pbal->members--;
+ }
+ }
+ if (rdo_member_config(cfg, cmd_table, cmd_offset,
+ next - 1, member, r))
+ return APR_SUCCESS;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Balancer",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_uint32_t member_id;
+ if (prev && prev->id != MMDB_BALANCER) {
+ mm_send_response_ex(r, mm_response_utype, 0, prev->name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: type %s in not balancer for "
+ "Member: %s",
+ prev->name, name);
+ return APR_SUCCESS;
+ }
+ if (!prev) {
+ /* Use _default_ balancer */
+ prev_id = 0;
+ }
+ /* Add new Member */
+ if (!(member = asmm_salloc_ex(member_db, &member_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY(member->name, name);
+ member->balancer_id = prev_id;
+ member->state = mm_state_stopped;
+ member->activation = mm_state_stopped;
+ member->lf = 1;
+ member->max_conn = max_threads_per_child;
+ member->min_conn = max_threads_per_child;
+ member->max_clients = max_clients;
+ /* Update Member from provided params */
+ if (rdo_member_config(cfg, cmd_table, cmd_offset,
+ member_id, member, r)) {
+ /* There was an error during initial config
+ * Delete member we created
+ */
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: failed creating member: %s",
+ name);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ }
+ if (!member->route[0])
+ strcpy(member->route, member->name);
+ if (!member->address[0])
+ strcpy(member->address, MM_DEFAULT_ADDRESS);
+ if (member->type == mm_protocol_unknown)
+ member->type = MM_DEFAULT_PROTOCOL;
+ if (!member->port) {
+ switch (member->type) {
+ case mm_protocol_ajp:
+ member->port = MM_DEFAULT_AJP_PORT;
+ break;
+ case mm_protocol_http:
+ member->port = MM_DEFAULT_HTTP_PORT;
+ break;
+ case mm_protocol_https:
+ member->port = MM_DEFAULT_HTTPS_PORT;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error,
+ MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: Unknown protocol %d for "
+ "Member: %s",
+ member->type, member->name);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ break;
+ }
+ }
+ if (member->min_conn > member->max_conn)
+ member->min_conn = member->max_conn;
+ member->state = mm_state_stopped;
+ /* Add Applications linked to the Member's Balancer */
+ if (add_app_members(member_id, member->balancer_id) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "mod_manager: adding MemberApplication for: %s",
+ member->name);
+ del_app_members(member_id);
+ asmm_free(member_db, member);
+ return APR_SUCCESS;
+ }
+ if (prev_rec) {
+ ((mmdb_balancer_t *)prev_rec)->members++;
+ }
+ }
+ else {
+ mm_send_response_ex(r, mm_response_utype, 0, MM_RES_MEMBER "/",
+ name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown member: %s", name);
+ return APR_SUCCESS;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ if (!prev)
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_member_init(mm_server_conf_t *cfg)
+{
+
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+ ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DAEMON, &max_requests_per_child);
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_childs);
+ if (max_childs < 1)
+ max_childs = 1;
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+ if (max_threads_per_child < 1)
+ max_threads_per_child = 1;
+ max_clients = max_childs * max_threads_per_child;
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_member(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ case mm_resource_open:
+ case mm_resource_child_init:
+ return rdo_member_init(cfg);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a Member */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t member_provider = {
+ MMDB_MEMBER,
+ MM_RES_MEMBER,
+ rdo_member,
+ ini_member,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_member(apr_pool_t *pool)
+{
+ this_provider = &member_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_node.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_pool.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_pool.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_pool.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,504 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager ApplicationPool object resource routines */
+#include "mm_api.h"
+
+static mm_resource_provider_t *this_provider = NULL;
+static int server_limit = 0;
+static int thread_limit = 0;
+static int max_clients = 0;
+static int max_childs = 0;
+static int max_requests_per_child = 0;
+static int max_threads_per_child = 0;
+
+static const char *app_pool_params[] = {
+ "",
+ "Status",
+ "Busy",
+ "Concurrency",
+ "TimeOut",
+ "Applications",
+ NULL
+};
+
+static void rdo_app_pool_info_print(int pi, int pp,
+ mmdb_app_pool_t *ap,
+ request_rec *r)
+{
+ if (pp) {
+ ap_rvputs(r, app_pool_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* Status */
+ ap_rputs(mm_state_name_get(ap->status), r);
+ break;
+ case 2: /* Busy */
+ ap_rprintf(r, "%d", ap->busy);
+ break;
+ case 3: /* Concurrency */
+ ap_rprintf(r, "%d", ap->concurrency);
+ break;
+ case 4: /* TimeOut */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(ap->timeout));
+ break;
+ case 5: /* Applications */
+ ap_rprintf(r, "%d", ap->applications);
+ break;
+ }
+}
+
+/* Dump ApplicationPool info */
+static void rdo_app_pool_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ int wcm,
+ mmdb_app_pool_t *bal,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (app_pool_params[j]) {
+ if (apr_fnmatch(ce[i].key, app_pool_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (app_pool_params[j]) {
+ if (!strcasecmp(ce[i].key, app_pool_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_app_pool_info_print(m, wcm, bal, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ int sep = 0;
+ /* Multiple params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (app_pool_params[j]) {
+ if (apr_fnmatch(ce[i].key, app_pool_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_app_pool_info_print(j, 1, bal, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (app_pool_params[j]) {
+ if (!strcasecmp(ce[i].key, app_pool_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_app_pool_info_print(j, 1, bal, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static int app_pool_exist(const char *value, mmdb_app_pool_t **ap)
+{
+ apr_uint32_t next = 0;
+ mmdb_app_pool_t *app_pool;
+ asmm_slotmem_t *app_pool_db = mmdb_table_getn(MMDB_APP_POOL);
+
+ while ((app_pool = asmm_slot_next(app_pool_db, &next))) {
+ if (strcasecmp(value, app_pool->name))
+ continue;
+ *ap = app_pool;
+ return 1;
+ }
+ return 0;
+}
+
+static apr_status_t rdo_app_pool_config_do(int pi,
+ const char *value,
+ mmdb_app_pool_t *ap,
+ request_rec *r)
+{
+ switch (pi) {
+ case 1: /* Status */
+ ap->status = mm_state_get(value);
+ break;
+ case 3: /* Concurrency */
+ ap->concurrency = atoi(value);
+ break;
+ case 4: /* TimeOut */
+ ap->timeout = APR_TIME_C(1000) * atoi(value);
+ break;
+ default:
+ return MME_EPERM;
+ break;
+ }
+ return 0;
+}
+
+/* Configure Balancer */
+static int rdo_app_pool_config(mm_server_conf_t *cfg,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ apr_uint32_t app_pool_id,
+ mmdb_app_pool_t *app_pool,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j;
+ apr_status_t rc;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ /* Wildchar params not allowed for config */
+ continue;
+ }
+ else if (!strcasecmp(ce[i].key, MM_RES_APPLICATION)) {
+ /* Configure Application for this ApplicationPool
+ * Add resource if it doesn't exist and link it
+ * to this ApplicationPool
+ */
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[i].key);
+ if (mp) {
+ rc = (*mp->func)(cfg, mm_mcmp_config,
+ ce[i].val, this_provider,
+ app_pool_id, app_pool,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS)
+ return 1;
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, APR_EEXIST, r->server,
+ "mod_manager: resource provider: %s",
+ mp->name);
+ return 1;
+ }
+ break;
+ }
+ else {
+ while (app_pool_params[j]) {
+ if (!strcasecmp(ce[i].key, app_pool_params[j])) {
+ if (!ce[i].val || !*(ce[i].val)) {
+ /* Empty value */
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL,
+ NULL);
+ return 1;
+ }
+ if ((rc = rdo_app_pool_config_do(j, ce[i].val,
+ app_pool, r))) {
+ /* Parameter value error */
+ mm_send_response_ex(r, mm_response_error,
+ rc, NULL);
+ return 1;
+ }
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ return 0;
+}
+
+static apr_status_t create_app_pool(mm_server_conf_t *cfg,
+ const char *name,
+ asmm_slotmem_t *app_pool_db,
+ mmdb_app_pool_t **app_pool,
+ apr_uint32_t *app_pool_id)
+{
+ /* Create ApplicationPool */
+ if (!(*app_pool = asmm_salloc_ex(app_pool_db, app_pool_id)))
+ return apr_get_os_error();
+ MM_SSAFE_COPY((*app_pool)->name, name);
+
+ (*app_pool)->concurrency = max_clients;
+ (*app_pool)->timeout = cfg->main_server->timeout;
+ (*app_pool)->status = mm_state_active;
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_app_pool(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ int wdone = 0;
+ int wcm;
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+ apr_uint32_t next = 0;
+ mmdb_app_pool_t *app_pool;
+ asmm_slotmem_t *app_pool_db = mmdb_table_getn(MMDB_APP_POOL);
+
+ if (!app_pool_db)
+ return APR_ENOMEM;
+ if (!name || !*name) {
+#if MM_FORCE_DEFAULT_NAME_REQ
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] empty ApplicationPool name",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+#else
+ name = MM_DEFAULT_NAME;
+#endif
+ }
+ wcm = apr_fnmatch_test(name);
+ while ((app_pool = asmm_slot_next(app_pool_db, &next))) {
+ if (wcm) {
+ if (apr_fnmatch(name, app_pool->name,
+ MM_FFNMATCH) != APR_SUCCESS)
+ continue;
+ }
+ else if (strcasecmp(name, app_pool->name))
+ continue;
+ if (cmd_offset < ca->nelts) {
+ mm_resource_provider_t *mp = mm_lookup_resource_provider(ce[cmd_offset].key);
+ if (mp) {
+ apr_status_t rc;
+ if (mp == this_provider) {
+ mm_send_response_ex(r, mm_response_error, MME_EINVAL, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] recursion not allowed: %s",
+ mm_mcmp_command_name_get(cmd),
+ this_provider->name);
+ return APR_SUCCESS;
+ }
+ rc = (*mp->func)(cfg, cmd,
+ ce[cmd_offset].val, this_provider,
+ next - 1, app_pool,
+ cmd_table, cmd_offset + 1, r);
+ if (rc != APR_SUCCESS) {
+ }
+ wdone++;
+ if (wcm)
+ continue;
+ else
+ break;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ if (wcm) {
+ ap_rvputs(r, "@" MM_RES_APP_POOL "/", app_pool->name, NULL);
+ if (cmd_offset < ca->nelts)
+ ap_rputs(": ", r);
+ else
+ ap_rputs(CRLF, r);
+ }
+ if (cmd_offset < ca->nelts)
+ rdo_app_pool_info(cmd_table, cmd_offset, wcm, app_pool, r);
+ break;
+ case mm_mcmp_enable:
+ app_pool->status = mm_state_active;
+ break;
+ case mm_mcmp_disable:
+ app_pool->status = mm_state_disabled;
+ break;
+ case mm_mcmp_stop:
+ app_pool->status = mm_state_stopped;
+ break;
+ case mm_mcmp_delete:
+ if (app_pool->status != mm_state_stopped) {
+ /* ApplicationPool must be stopped before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: ApplicationPool not stopped: %s",
+ app_pool->name);
+ return APR_SUCCESS;
+ }
+ else if (app_pool->applications) {
+ /* ApplicationPool must be empty before */
+ mm_send_response_ex(r, mm_response_error, MME_EBUSY, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: ApplicationPool not empty: %s",
+ app_pool->name);
+ return APR_SUCCESS;
+ }
+ else {
+ /* Delete ApplicationPool entries */
+ if (strcmp(app_pool->name, MM_DEFAULT_NAME)) {
+ /* TODO: Remove any dependent objects */
+ asmm_free(app_pool_db, app_pool);
+ }
+ else if (!wcm) {
+ mm_send_response_ex(r, mm_response_error,
+ MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+ r->server,
+ "mod_manager: Cannot delete "
+ MM_DEFAULT_NAME " ApplicationPool");
+ return APR_SUCCESS;
+ }
+ }
+ case mm_mcmp_config:
+ if (rdo_app_pool_config(cfg, cmd_table, cmd_offset,
+ next - 1, app_pool, r))
+ return APR_SUCCESS;
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for "
+ "ApplicationPool",
+ mm_mcmp_command_name_get(cmd));
+ return APR_SUCCESS;
+ break;
+ }
+ wdone++;
+ if (!wcm)
+ break;
+ }
+ if (!wdone) {
+ if (cmd == mm_mcmp_config && !wcm) {
+ apr_status_t rv;
+ apr_uint32_t app_pool_id;
+ /* Add new ApplicationPool */
+ if ((rv = create_app_pool(cfg, name, app_pool_db,
+ &app_pool, &app_pool_id)) != APR_SUCCESS)
+ return rv;
+ /* Update ApplicationPool from provided params */
+ rdo_app_pool_config(cfg, cmd_table, cmd_offset,
+ app_pool_id, app_pool, r);
+ }
+ else {
+ mm_send_response_ex(r, mm_response_utype, 0, MM_RES_APP_POOL "/",
+ name, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: unknown ApplicationPool: %s", name);
+ return APR_SUCCESS;
+ }
+ }
+ switch (cmd) {
+ case mm_mcmp_info:
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t rdo_app_pool_init(mm_server_conf_t *cfg, int child,
+ apr_pool_t *pool)
+{
+ apr_uint32_t app_pool_id;
+ mmdb_app_pool_t *app_pool;
+ asmm_slotmem_t *app_pool_db;
+
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+ ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DAEMON, &max_requests_per_child);
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_childs);
+ if (max_childs < 1)
+ max_childs = 1;
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+ if (max_threads_per_child < 1)
+ max_threads_per_child = 1;
+ max_clients = max_childs * max_threads_per_child;
+
+ if (child)
+ return APR_SUCCESS;
+ if (!(app_pool_db = mmdb_table_getn(MMDB_APP_POOL)))
+ return APR_ENOMEM;
+ /* Create _default_ ApplicationPool */
+ return create_app_pool(cfg, MM_DEFAULT_NAME,
+ app_pool_db,
+ &app_pool,
+ &app_pool_id);
+}
+
+static apr_status_t ini_app_pool(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ return rdo_app_pool_init(cfg, 0, pool);
+ break;
+ case mm_resource_open:
+ case mm_resource_child_init:
+ return rdo_app_pool_init(cfg, 1, pool);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a ApplicationPool */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t app_pool_provider = {
+ MMDB_APP_POOL,
+ MM_RES_APP_POOL,
+ rdo_app_pool,
+ ini_app_pool,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_app_pool(apr_pool_t *pool)
+{
+ this_provider = &app_pool_provider;
+ mm_register_resource_provider(pool, this_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_pool.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_server.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_server.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_server.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,374 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager Server object resource routines */
+#include "mm_api.h"
+
+static const char *server_params[] = {
+ "",
+ "ServerName",
+ "ServerRoot",
+ "ServerVersion",
+ "ServerVersionNumber",
+ "ServerBuilt",
+ "ServerArchitecture",
+ "ServerProcessing",
+ "ServerPlatform",
+ "ThreadsPerChild",
+ "MaxRequestsPerChild",
+ "MaxClients",
+ "Listen",
+ "ListenBackLog",
+ "CurrentTime",
+ "RestartTime",
+ "ServerUpTime",
+ "AccessCount",
+ "BytesServed",
+ "Busy",
+ "LimitRequestFields",
+ "LimitRequestFieldSize",
+ "ConfigurationFile",
+ NULL
+};
+
+static int server_limit = 0;
+static int thread_limit = 0;
+static int max_clients = 0;
+static int max_childs = 0;
+static int max_requests_per_child = 0;
+static int max_threads_per_child = 0;
+
+static apr_off_t get_scoreboard_access()
+{
+ int i, j;
+ worker_score *ws;
+ apr_off_t ac = 0;
+
+ for (i = 0; i < server_limit; i++) {
+ for (j = 0; j < thread_limit; j++) {
+ ws = ap_get_scoreboard_worker(i, j);
+ ac += ws->access_count;
+ }
+ }
+ return ac;
+}
+
+static apr_off_t get_scoreboard_bserved()
+{
+ int i, j;
+ worker_score *ws;
+ apr_off_t bs = 0;
+
+ for (i = 0; i < server_limit; i++) {
+ for (j = 0; j < thread_limit; j++) {
+ ws = ap_get_scoreboard_worker(i, j);
+ bs += ws->bytes_served;
+ }
+ }
+ return bs;
+}
+
+static int get_scoreboard_busy()
+{
+ int i, j, r;
+ worker_score *ws;
+ process_score *ps;
+ int busy = 0;
+
+ for (i = 0; i < server_limit; i++) {
+ ps = ap_get_scoreboard_process(i);
+ if (!ps->quiescing && ps->pid) {
+ for (j = 0; j < thread_limit; j++) {
+ ws = ap_get_scoreboard_worker(i, j);
+ r = ws->status;
+ if (r != SERVER_DEAD &&
+ r != SERVER_STARTING &&
+ r != SERVER_READY &&
+ r != SERVER_IDLE_KILL)
+ busy++;
+ }
+ }
+ }
+ return busy;
+}
+
+static void print_listeners(request_rec *r)
+{
+ int cnt = 0;
+ ap_listen_rec *lr;
+
+ for (lr = ap_listeners; lr; lr = lr->next)
+ cnt++;
+ if (cnt > 1)
+ ap_rputs("\"", r);
+
+ cnt = 0;
+ for (lr = ap_listeners; lr; lr = lr->next) {
+ char *addr;
+ apr_sockaddr_ip_get(&addr, lr->bind_addr);
+ if (cnt++)
+ ap_rputs(" ", r);
+ ap_rprintf(r, "%s:%u", addr, lr->bind_addr->port);
+ }
+ if (cnt > 1)
+ ap_rputs("\"", r);
+
+}
+
+
+static void rdo_server_info_print(int pi, int pp,
+ mm_server_conf_t *cfg,
+ request_rec *r)
+{
+ char b[APR_RFC822_DATE_LEN] = "";
+
+ if (pp) {
+ ap_rvputs(r, server_params[pi], "=", NULL);
+ }
+ switch (pi) {
+ case 1: /* ServerName */
+ MM_MAYBEQ_RPUTS(r, pp, cfg->main_server->server_hostname);
+ break;
+ case 2: /* ServerRoot */
+ MM_MAYBEQ_RPUTS(r, pp, ap_server_root);
+ break;
+ case 3: /* ServerVersion */
+ MM_MAYBEQ_RPUTS(r, pp, ap_get_server_description());
+ break;
+ case 4: /* ServerVersionNumber */
+ ap_rprintf(r, "%u.%u", MODULE_MAGIC_NUMBER_MAJOR,
+ MODULE_MAGIC_NUMBER_MINOR);
+ break;
+ case 5: /* ServerBuilt */
+ MM_MAYBEQ_RPUTS(r, pp, ap_get_server_built());
+ break;
+ case 6: /* ServerArchitecture */
+ ap_rprintf(r, "%ld-bit", 8 * (long) sizeof(void *));
+ break;
+ case 7: /* ServerProcessing */
+ ap_rputs(MPM_NAME, r);
+ break;
+ case 8: /* ServerPlatform */
+ ap_rputs(PLATFORM, r);
+ break;
+ case 9: /* ThreadsPerChild */
+ ap_rprintf(r, "%d", max_threads_per_child);
+ break;
+ case 10: /* MaxRequestsPerChild */
+ ap_rprintf(r, "%d", max_requests_per_child);
+ break;
+ case 11: /* MaxClients */
+ ap_rprintf(r, "%d", max_clients);
+ break;
+ case 12: /* Listen */
+ print_listeners(r);
+ break;
+ case 13: /* ListenBackLog */
+ /* For now use compile-time setting */
+ ap_rprintf(r, "%d", DEFAULT_LISTENBACKLOG);
+ break;
+ case 14: /* CurrentTime */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(apr_time_now()));
+ break;
+ case 15: /* RestartTime */
+ ap_rprintf(r, "%" APR_TIME_T_FMT,
+ apr_time_as_msec(ap_scoreboard_image->global->restart_time));
+ break;
+ case 16: /* ServerUpTime */
+ ap_rprintf(r, "%" APR_TIME_T_FMT, apr_time_as_msec(apr_time_now() -
+ ap_scoreboard_image->global->restart_time));
+ break;
+ case 17: /* AccessCount */
+ ap_rprintf(r, "%" APR_OFF_T_FMT, get_scoreboard_access());
+ break;
+ case 18: /* BytesServed */
+ ap_rprintf(r, "%" APR_OFF_T_FMT, get_scoreboard_bserved());
+ break;
+ case 19: /* Busy */
+ ap_rprintf(r, "%d", get_scoreboard_busy());
+ break;
+ case 20: /* LimitRequestFields */
+ ap_rprintf(r, "%d", cfg->main_server->limit_req_fields);
+ break;
+ case 21: /* LimitRequestFieldSize */
+ ap_rprintf(r, "%d", cfg->main_server->limit_req_fieldsize);
+ break;
+ case 22: /* ConfigurationFile */
+ MM_MAYBEQ_RPUTS(r, pp, ap_conftree->filename);
+ break;
+ }
+}
+
+/* Dump server info */
+static void rdo_server_info(apr_table_t *cmd_table,
+ int cmd_offset,
+ mm_server_conf_t *cfg,
+ request_rec *r)
+{
+ int cnt = 0;
+ int i, j, m = 0;
+ const char *param = NULL;
+ const char *value = NULL;
+
+ const apr_array_header_t *ca = apr_table_elts(cmd_table);
+ apr_table_entry_t *ce = (apr_table_entry_t *)ca->elts;
+
+ /* Step 1: Figure out the number of requested params */
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (server_params[j]) {
+ if (apr_fnmatch(ce[i].key, server_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ cnt++;
+ }
+ j++;
+ }
+ }
+ else {
+ while (server_params[j]) {
+ if (!strcasecmp(ce[i].key, server_params[j])) {
+ m = j;
+ cnt++;
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (!cnt) {
+ /* No params. Just print OK */
+ mm_send_response_ex(r, mm_response_ok, 0, NULL);
+ }
+ else if (cnt == 1 && m) {
+ /* Single param */
+ rdo_server_info_print(m, 0, cfg, r);
+ ap_rputs(CRLF, r);
+ }
+ else {
+ /* Multiple params */
+ int sep = 0;
+ for (i = cmd_offset; i < ca->nelts; i++) {
+ j = 1;
+ if (apr_fnmatch_test(ce[i].key)) {
+ while (server_params[j]) {
+ if (apr_fnmatch(ce[i].key, server_params[j],
+ MM_FFNMATCH) == APR_SUCCESS) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_server_info_print(j, 1, cfg, r);
+ }
+ j++;
+ }
+ }
+ else {
+ while (server_params[j]) {
+ if (!strcasecmp(ce[i].key, server_params[j])) {
+ if (sep++)
+ ap_rputs("; ", r);
+ rdo_server_info_print(j, 1, cfg, r);
+ break;
+ }
+ j++;
+ }
+ }
+ }
+ if (sep)
+ ap_rputs(CRLF, r);
+ }
+}
+
+static apr_status_t rdo_server_init(mm_server_conf_t *cfg)
+{
+
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+ ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DAEMON, &max_requests_per_child);
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_childs);
+ if (max_childs < 1)
+ max_childs = 1;
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &max_threads_per_child);
+ if (max_threads_per_child < 1)
+ max_threads_per_child = 1;
+ max_clients = max_childs * max_threads_per_child;
+ return APR_SUCCESS;
+}
+
+
+static apr_status_t rdo_server(mm_server_conf_t *cfg,
+ mm_mcmp_command_e cmd,
+ const char *name,
+ mm_resource_provider_t *prev,
+ apr_uint32_t prev_id,
+ void *prev_rec,
+ apr_table_t *cmd_table,
+ int cmd_offset,
+ request_rec *r)
+{
+ switch (cmd) {
+ case mm_mcmp_info:
+ rdo_server_info(cmd_table, cmd_offset, cfg, r);
+ break;
+ default:
+ mm_send_response_ex(r, mm_response_error, MME_EPERM, NULL);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ "mod_manager: [%s] not allowed for Server",
+ mm_mcmp_command_name_get(cmd));
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t ini_server(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ switch (op) {
+ case mm_resource_init:
+ case mm_resource_open:
+ case mm_resource_child_init:
+ return rdo_server_init(cfg);
+ break;
+ case mm_resource_close:
+ /* Nothing to do for a Server */
+ break;
+ }
+ return APR_SUCCESS;
+}
+
+static mm_resource_provider_t server_provider = {
+ MMDB_SERVER,
+ MM_RES_SERVER,
+ rdo_server,
+ ini_server,
+ NULL
+};
+
+/* Exported register function */
+void mm_register_resource_server(apr_pool_t *pool)
+{
+ mm_register_resource_provider(pool, &server_provider);
+}
Property changes on: sandbox/aloha/httpd/modules/manager/mm_server.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/mm_util.c
===================================================================
--- sandbox/aloha/httpd/modules/manager/mm_util.c (rev 0)
+++ sandbox/aloha/httpd/modules/manager/mm_util.c 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,997 @@
+/*
+ * ModManager - JBoss Aloha
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * @author Mladen Turk
+ */
+
+/* Manager utility routines */
+#include "mm_api.h"
+
+#ifdef AP_NEED_SET_MUTEX_PERMS
+#include "unixd.h"
+#endif
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h> /* for getpid() */
+#endif
+
+#if HAVE_SYS_SEM_H
+#include <sys/shm.h>
+#if !defined(SHM_R)
+#define SHM_R 0400
+#endif
+#if !defined(SHM_W)
+#define SHM_W 0200
+#endif
+#endif
+
+/** A list of advertise callbacks */
+typedef struct mm_advetrisecb_t mm_advetrisecb_t;
+struct mm_advetrisecb_t {
+ /** The next callback in the list */
+ struct mm_advetrisecb_t *next;
+ /** General purpose storage */
+ const void *data;
+ /** Callback function */
+ mm_advertisefn_t *callback;
+};
+
+/** A list of maintenance callbacks */
+typedef struct mm_maintaincb_t mm_maintaincb_t;
+struct mm_maintaincb_t {
+ /** The next callback in the list */
+ struct mm_maintaincb_t *next;
+ /** General purpose storage */
+ const void *data;
+ /** Callback function */
+ mm_maintainfn_t *callback;
+};
+
+/* Internal case insensitive string hash table */
+typedef struct mm_hash_node_t mm_hash_node_t;
+struct mm_hash_node_t {
+ mm_hash_node_t *next;
+ const void *data;
+ unsigned int ikey;
+ char key[1];
+};
+
+typedef struct mm_hash_t mm_hash_t;
+struct mm_hash_t {
+ apr_pool_t *pool;
+ unsigned int size;
+ mm_hash_node_t **nodes;
+ apr_array_header_t *nlist;
+};
+
+/* Private data */
+static apr_pool_t *mm_register_pool = NULL;
+static mm_advetrisecb_t *mm_advertise_cb = NULL;
+static mm_maintaincb_t *mm_maintain_cb = NULL;
+static mm_hash_t *mm_resource_hash = NULL;
+
+/* Advertise sockets */
+static apr_socket_t *mma_mgroup_socket = NULL;
+static apr_socket_t *mma_listen_socket = NULL;
+static apr_sockaddr_t *mma_mgroup_sa = NULL;
+static apr_sockaddr_t *mma_listen_sa = NULL;
+
+/* Advertise sequence number */
+static volatile apr_uint64_t mma_sequence = 0;
+
+/*
+ * ---------------------------------------------------------------------
+ * begin of hash
+ * ---------------------------------------------------------------------
+ */
+
+/* Make hash size always as 0xFF value */
+#define DEFAULT_HASH_SIZE 256
+
+static unsigned int strhash(const char *string)
+{
+ unsigned int hash = 0;
+
+ while (*string) {
+ hash = hash * 33 + apr_tolower(*string);
+ string ++;
+ }
+ return hash;
+}
+
+static mm_hash_t *hash_create(apr_size_t size, apr_pool_t *pool)
+{
+ mm_hash_t *h;
+ if (!size)
+ size = DEFAULT_HASH_SIZE;
+ else
+ size = APR_ALIGN_DEFAULT(size);
+ h = apr_palloc(pool, sizeof(mm_hash_t));
+ h->nodes = apr_pcalloc(pool, sizeof(mm_hash_node_t *) * size);
+ h->nlist = apr_array_make(pool, size, sizeof(mm_hash_node_t *));
+ h->size = size;
+ h->pool = pool;
+ return h;
+}
+
+static void *hash_insert(mm_hash_t *ht, const char *key, const void *data)
+{
+ unsigned int ikey;
+ unsigned int hkey;
+ mm_hash_node_t **node;
+
+ if (!ht || !key)
+ return NULL;
+ ikey = strhash(key);
+ hkey = ikey % ht->size;
+ if (!ht->nodes[hkey]) {
+ ht->nodes[hkey] = apr_palloc(ht->pool, sizeof(mm_hash_node_t) +
+ strlen(key));
+ strcpy(ht->nodes[hkey]->key, key);
+ ht->nodes[hkey]->ikey = ikey;
+ ht->nodes[hkey]->data = data;
+ ht->nodes[hkey]->next = NULL;
+ node = (mm_hash_node_t **)apr_array_push(ht->nlist);
+ *node = ht->nodes[hkey];
+ }
+ else {
+ mm_hash_node_t *p;
+ for (p = ht->nodes[hkey]; p; p = p->next) {
+ if (p->ikey == ikey && !strcasecmp(p->key, key)) {
+ void *org = (void *)p->data;
+ p->data = data;
+ return org;
+ }
+ }
+ p = apr_palloc(ht->pool, sizeof(mm_hash_node_t) + strlen(key));
+ strcpy(p->key, key);
+ p->ikey = ikey;
+ p->data = data;
+ p->next = ht->nodes[hkey];
+ ht->nodes[hkey] = p;
+ node = (mm_hash_node_t **)apr_array_push(ht->nlist);
+ *node = ht->nodes[hkey];
+ }
+ return NULL;
+}
+
+
+static void *hash_find(mm_hash_t *ht, const char *key)
+{
+ unsigned int ikey;
+ unsigned int hkey;
+
+ if (!ht || !key)
+ return NULL;
+ ikey = strhash(key);
+ hkey = ikey % ht->size;
+
+ if (!ht->nodes[hkey])
+ return NULL;
+ else {
+ mm_hash_node_t *p;
+ for (p = ht->nodes[hkey]; p; p = p->next) {
+ if (p->ikey == ikey && !strcasecmp(p->key, key)) {
+ return (void *)p->data;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void hash_foreach(mm_hash_t *ht, apr_pool_t *pool, void *opaque,
+ void (*callback)(apr_pool_t *, void *, const char *, void *))
+{
+ int i;
+
+ if (!ht || !ht->nlist->nelts)
+ return;
+ for (i = ht->nlist->nelts - 1; i >= 0; i--) {
+ mm_hash_node_t *p = ((mm_hash_node_t **)ht->nlist->elts)[i];
+ (*callback)(pool, opaque, p->key, (void *)p->data);
+ }
+}
+
+void mm_callback_initialize(apr_pool_t *pool)
+{
+ mm_register_pool = pool;
+}
+
+#define MM_ADVERTISE_SERVER_FMT \
+ "HTTP/1.0 %s" CRLF \
+ "Date: %s" CRLF \
+ "Digest: %s" CRLF \
+ "Server: %s" CRLF
+
+static const char *hex = "0123456789abcdef";
+
+apr_status_t mm_advertise_server_cb(void *cd, const char *data)
+{
+ char buf[MM_BSIZE];
+ char dat[APR_RFC822_DATE_LEN];
+ unsigned char msig[APR_MD5_DIGESTSIZE];
+ unsigned char ssig[APR_MD5_DIGESTSIZE * 2 + 1];
+ const char *asl;
+ char *p = buf;
+ int i, c = 0;
+ apr_size_t l = MM_BSIZE - 8;
+ apr_size_t n = 0;
+ apr_md5_ctx_t md;
+
+ mmdb_manager_t *m = (mmdb_manager_t *)cd;
+
+ mma_sequence++;
+ ap_recent_rfc822_date(dat, apr_time_now());
+ asl = ap_get_status_line(m->status);
+
+ /* Create MD5 digest
+ * salt + date + srvid
+ */
+ apr_md5_init(&md);
+ apr_md5_update(&md, m->ssalt, APR_MD5_DIGESTSIZE);
+ apr_md5_update(&md, dat, strlen(dat));
+ apr_md5_update(&md, m->srvid + 1, strlen(m->srvid + 1));
+ apr_md5_final(msig, &md);
+ /* Convert MD5 digest to hex string */
+ for (i = 0; i < APR_MD5_DIGESTSIZE; i++) {
+ ssig[c++] = hex[msig[i] >> 4];
+ ssig[c++] = hex[msig[i] & 0x0F];
+ }
+ ssig[c] = '\0';
+ n = apr_snprintf(p, l, MM_ADVERTISE_SERVER_FMT,
+ asl, dat, ssig, m->srvid + 1);
+ if (m->type == MM_ADVERTISE_SERVER) {
+ l -= n;
+ if (data && *data) {
+ apr_cpystrn(p + n, data, l);
+ n = strlen(buf);
+ }
+ }
+ strcat(p, CRLF);
+ n += 2;
+ return apr_socket_sendto(mma_mgroup_socket,
+ mma_mgroup_sa, 0, buf, &n);
+}
+
+apr_status_t mm_advertise_callback_run(mm_advertise_e mode, void *context,
+ apr_status_t (*callback)(void *, const char *))
+{
+ apr_status_t rv = APR_SUCCESS;
+ mm_advetrisecb_t *c = mm_advertise_cb;
+ char data[MM_BSIZE] = "";
+ char *p = data;
+ apr_size_t n = 0;
+ apr_size_t l = MM_BSIZE - 128;
+
+ while (c) {
+ /* Accumulate data from all callbacks */
+ rv = (*c->callback)(mode, (void *)c->data, p + n, l);
+ if (rv != APR_SUCCESS)
+ break;
+ if ((c = c->next)) {
+ n = strlen(data);
+ l -= n;
+ }
+ }
+ if (rv == APR_SUCCESS)
+ rv = (*callback)(context, data);
+ return rv;
+}
+
+apr_status_t mm_maintain_callback_run(mm_maintain_e mode)
+{
+ apr_status_t rv = APR_SUCCESS;
+ mm_maintaincb_t *c = mm_maintain_cb;
+ while (c) {
+ /* Make sure all callbacks are run,
+ * but preserve the error codes.
+ */
+ apr_status_t rc = (*c->callback)(mode, (void *)c->data);
+ if (rc != APR_SUCCESS)
+ rv = rc;
+ c = c->next;
+ }
+ return rv;
+}
+
+MANAGER_DECLARE(void) mm_register_advertise_callback(apr_pool_t *pool,
+ const void *context,
+ mm_advertisefn_t *callback)
+{
+ mm_advetrisecb_t *c;
+ if (!mm_register_pool)
+ mm_register_pool = pool;
+ c = apr_palloc(mm_register_pool, sizeof(mm_advetrisecb_t));
+ c->data = context;
+ c->callback = callback;
+ c->next = mm_advertise_cb;
+ mm_advertise_cb = c;
+}
+
+MANAGER_DECLARE(void) mm_register_maintain_callback(apr_pool_t *pool,
+ const void *data,
+ mm_maintainfn_t *callback)
+{
+ mm_maintaincb_t *c;
+ if (!mm_register_pool)
+ mm_register_pool = pool;
+ c = apr_palloc(mm_register_pool, sizeof(mm_maintaincb_t));
+ c->data = data;
+ c->callback = callback;
+ c->next = mm_maintain_cb;
+ mm_maintain_cb = c;
+}
+
+MANAGER_DECLARE(void) mm_register_resource_provider(apr_pool_t *pool,
+ mm_resource_provider_t *provider)
+{
+ if (!mm_resource_hash)
+ mm_resource_hash = hash_create(0, pool);
+ hash_insert(mm_resource_hash, provider->name, provider);
+}
+
+MANAGER_DECLARE(mm_resource_provider_t *)mm_lookup_resource_provider(
+ const char *name)
+{
+ return hash_find(mm_resource_hash, name);
+}
+
+static void reslist_cb(apr_pool_t *pool, void *p,
+ const char *key, void *data)
+{
+ mm_resource_list_t *re;
+ mm_resource_list_t **rl = (mm_resource_list_t **)p;
+ re = apr_palloc(pool, sizeof(mm_resource_list_t));
+ re->provider = data;
+ re->next = *rl;
+ *rl = re;
+}
+
+MANAGER_DECLARE(mm_resource_list_t *)mm_list_resource_providers(
+ apr_pool_t *pool)
+{
+ mm_resource_list_t *rl = NULL;
+ hash_foreach(mm_resource_hash, pool, (void *)&rl, reslist_cb);
+ return rl;
+}
+
+struct ri_cb {
+ mm_server_conf_t *sc;
+ mm_resource_op_e op;
+};
+
+static void resinit_cb(apr_pool_t *pool, void *p,
+ const char *key, void *data)
+{
+ struct ri_cb *cb = p;
+ mm_resource_provider_t *rp = data;
+ (*rp->init)(cb->sc, cb->op, pool);
+}
+
+MANAGER_DECLARE(void)mm_run_resource_providers(mm_server_conf_t *cfg,
+ mm_resource_op_e op,
+ apr_pool_t *pool)
+{
+ struct ri_cb cb;
+ cb.sc = cfg;
+ cb.op = op;
+ hash_foreach(mm_resource_hash, pool, (void *)&cb, resinit_cb);
+}
+
+const char *mm_strerror(apr_status_t s)
+{
+ switch (s) {
+ case MME_EPERM:
+ return "Operation not permitted";
+ break;
+ case MME_EINTR:
+ return "Interrupted function call";
+ break;
+ case MME_EBUSY:
+ return "Device or resource busy";
+ break;
+ case MME_ENODEV:
+ return "No such device";
+ break;
+ case MME_EINVAL:
+ return "Invalid Argument";
+ break;
+ case MME_ENOTCONN:
+ return "Not connected";
+ break;
+ }
+ return NULL;
+}
+
+void mm_send_response_ex(request_rec *r, mm_respose_type_e type,
+ apr_status_t s, ...)
+{
+ int vc = 0;
+ char buf[512];
+ const char *p, *line;
+ va_list vl;
+
+ va_start(vl, s);
+
+
+ switch (type) {
+ case mm_response_ok:
+ while ((line = va_arg(vl, const char *)) != NULL) {
+ ap_rputs(line, r);
+ vc++;
+ }
+ if (!vc)
+ ap_rputs("OK", r);
+ ap_rputs(CRLF, r);
+ break;
+ case mm_response_error:
+ if (!(p = mm_strerror(s))) {
+ if (!(p = apr_strerror(s, buf, sizeof(buf))))
+ p = "Unknown Error";
+ }
+ ap_rprintf(r, "?Error: %d; %s" CRLF, s, p);
+ break;
+ case mm_response_version:
+ ap_rputs("?MCMP/" MM_MCMP_VERSION_STRING CRLF, r);
+ break;
+ case mm_response_utype:
+ ap_rputs("?Unknown-Type: ", r);
+ while ((line = va_arg(vl, const char *)) != NULL)
+ ap_rputs(line, r);
+ ap_rputs(CRLF, r);
+ break;
+ case mm_response_uparam:
+ ap_rputs("?Unknown-Parameter: ", r);
+ while ((line = va_arg(vl, const char *)) != NULL)
+ ap_rputs(line, r);
+ ap_rputs(CRLF, r);
+ break;
+ }
+ va_end(vl);
+}
+
+static struct mm_command_spec {
+ const char *name;
+ mm_mcmp_command_e nval;
+} mm_commands_spec[] = {
+ { MM_MCMP_INFO, mm_mcmp_info },
+ { MM_MCMP_CONFIG, mm_mcmp_config },
+ { MM_MCMP_DISABLE, mm_mcmp_disable },
+ { MM_MCMP_ENABLE, mm_mcmp_enable },
+ { MM_MCMP_STOP, mm_mcmp_stop },
+ { MM_MCMP_DELETE, mm_mcmp_delete },
+ { MM_MCMP_EXEC, mm_mcmp_exec },
+ { MM_MCMP_RESET, mm_mcmp_reset },
+ { NULL, 0 }
+};
+
+
+mm_mcmp_command_e mm_mcmp_command_get(const char *cmd)
+{
+ int i = 0;
+ while (mm_commands_spec[i].name) {
+ if (!strcasecmp(cmd, mm_commands_spec[i].name))
+ return mm_commands_spec[i].nval;
+ i++;
+ }
+ return mm_mcmp_unknown;
+}
+
+const char *mm_mcmp_command_name_get(mm_mcmp_command_e cmd)
+{
+ int i = 0;
+ while (mm_commands_spec[i].name) {
+ if (mm_commands_spec[i].nval == cmd)
+ return mm_commands_spec[i].name;
+ i++;
+ }
+ return "(Unknown)";
+}
+
+apr_status_t mma_group_join(const char *addr, apr_port_t port,
+ apr_pool_t *pool)
+{
+ apr_status_t rv;
+
+ if ((rv = apr_sockaddr_info_get(&mma_mgroup_sa, addr,
+ APR_INET, port,
+ APR_UNSPEC, pool)) != APR_SUCCESS)
+ return rv;
+ if ((rv = apr_socket_create(&mma_mgroup_socket,
+ mma_mgroup_sa->family,
+ SOCK_DGRAM,
+ APR_PROTO_UDP,
+ pool)) != APR_SUCCESS)
+ return rv;
+ if ((rv = apr_mcast_join(mma_mgroup_socket, mma_mgroup_sa,
+ NULL, NULL)) != APR_SUCCESS) {
+ apr_socket_close(mma_mgroup_socket);
+ return rv;
+ }
+ if ((rv = apr_mcast_hops(mma_mgroup_socket,
+ MM_ADVERTISE_HOPS)) != APR_SUCCESS) {
+ apr_mcast_leave(mma_mgroup_socket, mma_mgroup_sa,
+ NULL, NULL);
+ apr_socket_close(mma_mgroup_socket);
+ return rv;
+ }
+ return APR_SUCCESS;
+}
+
+void mma_group_leave()
+{
+ if (mma_mgroup_socket) {
+ apr_mcast_leave(mma_mgroup_socket, mma_mgroup_sa,
+ NULL, NULL);
+ apr_socket_close(mma_mgroup_socket);
+ mma_mgroup_socket = NULL;
+ }
+}
+
+typedef struct mmdb_table_desc_t mmdb_table_desc_t;
+struct mmdb_table_desc_t {
+ int id;
+ const char *name;
+ apr_uint32_t blksize;
+ apr_uint32_t nblocks;
+ apr_uint16_t flags;
+ apr_uint16_t maxsections;
+ asmm_slotmem_t *mem;
+ apr_global_mutex_t *lock;
+};
+
+static mmdb_table_desc_t mmdb_default_tables[] = {
+ { MMDB_MANAGER,
+ "Manager",
+ sizeof(mmdb_manager_t),
+ 1,
+ 0,
+ 0,
+ NULL,
+ NULL
+ },
+ { MMDB_HOST,
+ "Host",
+ sizeof(mmdb_host_t),
+ 64,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_HOST_LIST,
+ "HostList",
+ sizeof(mmdb_hostlist_t),
+ 256,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_APP_POOL,
+ "ApplicationPool",
+ sizeof(mmdb_app_pool_t),
+ 16,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_BALANCER,
+ "Balancer",
+ sizeof(mmdb_balancer_t),
+ 16,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_MEMBER,
+ "Member",
+ sizeof(mmdb_member_t),
+ 1,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_APPLICATION,
+ "Application",
+ sizeof(mmdb_app_t),
+ 64,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { MMDB_MEMBERAPP,
+ "MemberApplication",
+ sizeof(mmdb_memberapp_t),
+ 512,
+ ASMM_HAS_LOCK,
+ ASMM_UNLIMITED,
+ NULL,
+ NULL
+ },
+ { 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL
+ }
+};
+
+static apr_global_mutex_t *mmdb_default_tables_lock = NULL;
+static mmdb_owner_instance = 0;
+
+apr_status_t mmdb_close()
+{
+ int i = 0;
+
+ if (mmdb_owner_instance && mmdb_default_tables_lock) {
+ apr_global_mutex_destroy(mmdb_default_tables_lock);
+ }
+ mmdb_default_tables_lock = NULL;
+
+ while (mmdb_default_tables[i].name) {
+ if (mmdb_owner_instance &&
+ mmdb_default_tables[i].lock &&
+ mmdb_default_tables[i].flags & ASMM_OWN_LOCK) {
+ apr_global_mutex_destroy(mmdb_default_tables[i].lock);
+ }
+ mmdb_default_tables[i].lock = NULL;
+ if (mmdb_default_tables[i].mem) {
+ asmm_slotmem_close(mmdb_default_tables[i].mem);
+ mmdb_default_tables[i].mem = NULL;
+ }
+ i++;
+ }
+ return APR_SUCCESS;
+}
+
+apr_status_t mmdb_create(const char *dbpath, apr_pool_t *pool)
+{
+ apr_status_t rv = APR_SUCCESS;
+ const char *pk = "manager_init_database_tag";
+ const char *lk = "manager_init_globlock_tag";
+ char fname[APR_PATH_MAX];
+ int i = 0;
+ mmdb_table_desc_t *database = NULL;
+
+
+ apr_pool_userdata_get((void *)&mmdb_default_tables_lock, lk, pool);
+ apr_pool_userdata_get((void *)&database, pk, pool);
+
+ mmdb_owner_instance = 1;
+ if (database) {
+ while (mmdb_default_tables[i].name) {
+ mmdb_default_tables[i].mem = database[i].mem;
+ mmdb_default_tables[i].lock = database[i].lock;
+ i++;
+ }
+ return APR_SUCCESS;
+ }
+
+ strcpy(fname, dbpath);
+ strcat(fname, "/_mm_lock");
+ if ((rv = apr_global_mutex_create(&mmdb_default_tables_lock,
+ fname,
+ APR_LOCK_DEFAULT,
+ pool)) != APR_SUCCESS)
+ return rv;
+#ifdef AP_NEED_SET_MUTEX_PERMS
+ rv = unixd_set_global_mutex_perms(mmdb_default_tables_lock);
+ if (rv != APR_SUCCESS) {
+ apr_global_mutex_destroy(mmdb_default_tables_lock);
+ mmdb_default_tables_lock = NULL;
+ return rv;
+ }
+#endif
+
+ while (mmdb_default_tables[i].name) {
+ sprintf(fname, "%s/_sm_%04d", dbpath, mmdb_default_tables[i].id);
+ rv = asmm_slotmem_create(&mmdb_default_tables[i].mem,
+ fname,
+ mmdb_default_tables[i].blksize,
+ mmdb_default_tables[i].nblocks,
+ mmdb_default_tables[i].flags,
+ mmdb_default_tables[i].maxsections,
+ pool);
+ if (rv != APR_SUCCESS) {
+ mmdb_default_tables[i].mem = NULL;
+ break;
+ }
+ if (mmdb_default_tables[i].flags & ASMM_OWN_LOCK) {
+ sprintf(fname, "%s/_mm_%04d", dbpath, mmdb_default_tables[i].id);
+ if ((rv = apr_global_mutex_create(&mmdb_default_tables[i].lock,
+ fname,
+ APR_LOCK_DEFAULT,
+ pool)) != APR_SUCCESS) {
+ asmm_slotmem_close(mmdb_default_tables[i].mem);
+ mmdb_default_tables[i].mem = NULL;
+ return rv;
+ }
+#ifdef AP_NEED_SET_MUTEX_PERMS
+ rv = unixd_set_global_mutex_perms(mmdb_default_tables[i].lock);
+ if (rv != APR_SUCCESS) {
+ asmm_slotmem_close(mmdb_default_tables[i].mem);
+ mmdb_default_tables[i].mem = NULL;
+ return rv;
+ }
+#endif
+ asmm_slotmem_lock_set(mmdb_default_tables[i].mem,
+ mmdb_default_tables[i].lock);
+ }
+ else if (mmdb_default_tables[i].flags & ASMM_HAS_LOCK)
+ asmm_slotmem_lock_set(mmdb_default_tables[i].mem,
+ mmdb_default_tables_lock);
+
+ i++;
+ }
+ apr_pool_userdata_set(mmdb_default_tables_lock,
+ lk, apr_pool_cleanup_null, pool);
+ apr_pool_userdata_set(apr_pmemdup(pool, mmdb_default_tables,
+ sizeof(mmdb_default_tables)),
+ pk, apr_pool_cleanup_null, pool);
+ return rv;
+}
+
+apr_status_t mmdb_open(const char *dbpath, apr_pool_t *pool)
+{
+ apr_status_t rv = APR_SUCCESS;
+ char fname[APR_PATH_MAX];
+ int i = 0;
+
+ mmdb_owner_instance = 0;
+ strcpy(fname, dbpath);
+ strcat(fname, "/_mm_lock");
+ if ((rv = apr_global_mutex_child_init(&mmdb_default_tables_lock,
+ fname,
+ pool)) != APR_SUCCESS)
+ return rv;
+ while (mmdb_default_tables[i].name) {
+ sprintf(fname, "%s/_sm_%04d", dbpath, mmdb_default_tables[i].id);
+ rv = asmm_slotmem_open(&mmdb_default_tables[i].mem,
+ fname,
+ pool);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ if (mmdb_default_tables[i].flags & ASMM_OWN_LOCK) {
+ sprintf(fname, "%s/_mm_%04d", dbpath, mmdb_default_tables[i].id);
+ if ((rv = apr_global_mutex_child_init(&mmdb_default_tables[i].lock,
+ fname,
+ pool)) != APR_SUCCESS) {
+ asmm_slotmem_close(mmdb_default_tables[i].mem);
+ mmdb_default_tables[i].mem = NULL;
+ return rv;
+ }
+ asmm_slotmem_lock_set(mmdb_default_tables[i].mem,
+ mmdb_default_tables[i].lock);
+ }
+ else if (mmdb_default_tables[i].flags & ASMM_HAS_LOCK)
+ asmm_slotmem_lock_set(mmdb_default_tables[i].mem,
+ mmdb_default_tables_lock);
+ i++;
+ }
+ return rv;
+}
+
+asmm_slotmem_t *mmdb_table_get(const char *name)
+{
+ int i = 0;
+
+ while (mmdb_default_tables[i].name) {
+ if (!strcasecmp(mmdb_default_tables[i].name, name))
+ return mmdb_default_tables[i].mem;
+ i++;
+ }
+ return NULL;
+}
+
+asmm_slotmem_t *mmdb_table_getn(int id)
+{
+ int i = 0;
+
+ while (mmdb_default_tables[i].name) {
+ if (mmdb_default_tables[i].id == id)
+ return mmdb_default_tables[i].mem;
+ i++;
+ }
+ return NULL;
+}
+
+const char *mmdb_table_name_get(int id)
+{
+ int i = 0;
+
+ while (mmdb_default_tables[i].name) {
+ if (mmdb_default_tables[i].id == id)
+ return mmdb_default_tables[i].name;
+ i++;
+ }
+ return "unknown";
+}
+
+apr_status_t mmdb_maintain(server_rec *s)
+{
+ apr_status_t rv;
+ int i = 0;
+
+ while (mmdb_default_tables[i].name) {
+ rv = asmm_slotmem_maintain(mmdb_default_tables[i].mem);
+ if (rv != APR_SUCCESS)
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ "mod_manager: failed new section request for: %s",
+ mmdb_default_tables[i].name);
+ i++;
+ }
+ return APR_SUCCESS;
+}
+
+const char *mm_state_name_get(mm_state_e state)
+{
+ switch (state) {
+ case mm_state_active:
+ return "A";
+ break;
+ case mm_state_busy:
+ return "B";
+ break;
+ case mm_state_disabled:
+ return "D";
+ break;
+ case mm_state_idle:
+ return "I";
+ break;
+ case mm_state_stopped:
+ return "S";
+ break;
+ case mm_state_error:
+ return "E";
+ break;
+ }
+ return "X";
+}
+
+mm_state_e mm_state_get(const char *sstate)
+{
+
+ switch (apr_toupper(*sstate)) {
+ case 'A':
+ return mm_state_active;
+ break;
+ case 'B':
+ return mm_state_busy;
+ break;
+ case 'D':
+ return mm_state_disabled;
+ break;
+ case 'I':
+ return mm_state_idle;
+ break;
+ case 'S':
+ return mm_state_stopped;
+ break;
+ case 'E':
+ return mm_state_error;
+ break;
+ }
+ return mm_state_unknown;
+}
+
+mm_protocol_e mm_protocol_get(const char *protocol)
+{
+
+ if (!strcasecmp(protocol, "http"))
+ return mm_protocol_http;
+ else if (!strcasecmp(protocol, "https"))
+ return mm_protocol_https;
+ else if (!strcasecmp(protocol, "ajp"))
+ return mm_protocol_ajp;
+ else
+ return mm_protocol_unknown;
+}
+
+const char *mm_protocol_name_get(mm_protocol_e protocol)
+{
+ switch (protocol) {
+ case mm_protocol_ajp:
+ return "ajp";
+ break;
+ case mm_protocol_http:
+ return "http";
+ break;
+ case mm_protocol_https:
+ return "https";
+ break;
+ }
+ return "undefined";
+}
+
+apr_status_t mm_unixd_set_shm_perms(const char *fname)
+{
+#ifdef AP_NEED_SET_MUTEX_PERMS
+#if APR_USE_SHMEM_SHMGET || APR_USE_SHMEM_SHMGET_ANON
+ struct shmid_ds shmbuf;
+ key_t shmkey;
+ int shmid;
+
+ shmkey = ftok(fname, 1);
+ if (shmkey == (key_t)-1) {
+ return errno;
+ }
+ if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) == -1) {
+ return errno;
+ }
+ shmbuf.shm_perm.uid = unixd_config.user_id;
+ shmbuf.shm_perm.gid = unixd_config.group_id;
+ shmbuf.shm_perm.mode = 0600;
+ if (shmctl(shmid, IPC_SET, &shmbuf) == -1) {
+ return errno;
+ }
+ return APR_SUCCESS;
+#else
+ return APR_ENOTIMPL;
+#endif
+#else
+ return APR_ENOTIMPL;
+#endif
+}
+
+#if defined (WIN32)
+void dbprintf(const char *format, ...)
+{
+ va_list args;
+ char buffer[4096];
+ int len;
+
+ va_start(args, format);
+ len = _vsnprintf(buffer, 4096, format, args);
+ va_end(args);
+ if (len > 0) {
+ char tid[4096 + 32];
+ sprintf(tid, "[%04d] %s", GetCurrentThreadId(), buffer);
+ OutputDebugString(tid);
+ }
+}
+#else
+void dbprintf(const char *format, ...)
+{
+ va_list args;
+ char buffer[4096];
+ int len;
+
+ va_start(args, format);
+ len = vsnprintf(buffer, 4096, format, args);
+ va_end(args);
+ if (len > 0) {
+ fprintf(stderr, "mod_manager: [%d\t%d] %s\n",
+ getpid(), getppid(), buffer);
+ fflush(stderr);
+ }
+}
+#endif
Property changes on: sandbox/aloha/httpd/modules/manager/mm_util.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/httpd/modules/manager/modules.mk
===================================================================
--- sandbox/aloha/httpd/modules/manager/modules.mk (rev 0)
+++ sandbox/aloha/httpd/modules/manager/modules.mk 2008-05-28 15:50:29 UTC (rev 1632)
@@ -0,0 +1,5 @@
+mod_manager.la: mm_app.slo mm_asmm.slo mm_balancer.slo mm_cookie.slo mm_host.slo mm_manager.slo mm_member.slo mm_module.slo mm_pool.slo mm_server.slo mm_util.slo
+ $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mm_app.lo mm_asmm.lo mm_balancer.lo mm_cookie.lo mm_host.lo mm_manager.lo mm_member.lo mm_module.lo mm_pool.lo mm_server.lo mm_util.lo $(MOD_MANAGER_LDADD)
+DISTCLEAN_TARGETS = modules.mk
+static =
+shared = mod_manager.la
16 years, 7 months
JBoss Native SVN: r1631 - sandbox/aloha.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:47:29 -0400 (Wed, 28 May 2008)
New Revision: 1631
Added:
sandbox/aloha/build.xml
Log:
Add ant build file
Added: sandbox/aloha/build.xml
===================================================================
--- sandbox/aloha/build.xml (rev 0)
+++ sandbox/aloha/build.xml 2008-05-28 15:47:29 UTC (rev 1631)
@@ -0,0 +1,291 @@
+<?xml version="1.0"?>
+<!-- Build file for ALOHA -->
+<project name="System information gathering hybrid tool Library" default="compile" basedir=".">
+ <!-- Give user a chance to override without editing this file
+ (and without typing -D each time it compiles it
+ -->
+ <property file="${user.home}/.ant.properties" />
+ <property file="${user.home}/build.properties" />
+ <property file="build.properties" />
+ <property file=".ant.properties" />
+
+ <!-- Initialization properties -->
+ <property name="name" value="Aloha core library"/>
+ <property name="title" value="JBoss Aloha core library"/>
+ <property name="version" value="1.0.0"/>
+ <property name="version.number" value="100"/>
+ <property name="project" value="aloha"/>
+ <property name="build.dir" value="./dist"/>
+ <property name="build.src" value="${build.dir}/src"/>
+ <property name="build.dest" value="${build.dir}/bin"/>
+ <property name="src.dir" value="."/>
+ <property name="final.name" value="${project}-${version}"/>
+ <property name="dist.root" value="./dist"/>
+ <property name="ant.home" value="."/>
+
+ <property name="debug" value="off"/>
+ <property name="optimize" value="on"/>
+ <property name="deprecation" value="on"/>
+
+ <property name="docs.src" value="./xdocs"/>
+ <property name="docs.dest" value="${dist.root}/doc"/>
+ <property name="docs.dest.print" value="${dist.root}/doc/printable"/>
+ <property name="test.runner" value="junit.textui.TestRunner"/>
+ <property name="test.entry" value="org.jboss.aloha.TestAll"/>
+ <property name="test.dir" value="${build.dest}/test"/>
+ <property name="examples.dir" value="${build.dest}/examples"/>
+ <property name="example" value="Foo"/>
+ <property name="junit.home" value="./lib"/>
+ <property name="junit.jar" value="${junit.home}/junit-4.3.1.jar"/>
+ <property name="commons-httpclient.home" value="./lib"/>
+ <property name="commons-httpclient.jar" value="${commons-httpclient.home}/commons-httpclient-3.1.jar"/>
+ <property name="commons-logging.home" value="./lib"/>
+ <property name="commons-logging.jar" value="${commons-logging.home}/commons-logging-1.1.1.jar"/>
+ <property name="commons-codec.home" value="./lib"/>
+ <property name="commons-codec.jar" value="${commons-codec.home}/commons-codec-1.3.jar"/>
+
+ <property name="compile.source" value="5"/>
+ <property name="compile.target" value="5"/>
+
+ <!-- The base directory for component sources -->
+ <property name="source.home" value="java"/>
+
+ <!-- Build classpath -->
+ <path id="classpath">
+ <pathelement location="${build.dest}/java"/>
+ <pathelement location="${commons-httpclient.jar}"/>
+ </path>
+
+ <!-- Test classpath -->
+ <path id="test.classpath">
+ <pathelement location="${build.dest}/java"/>
+ <pathelement location="${build.dest}/test"/>
+ <pathelement location="${junit.jar}"/>
+ <pathelement location="${commons-httpclient.jar}"/>
+ <pathelement location="${commons-logging.jar}"/>
+ </path>
+
+ <!-- Examples classpath -->
+ <path id="examples.classpath">
+ <pathelement location="${build.dest}/java"/>
+ <pathelement location="${build.dest}/examples"/>
+ <pathelement location="${commons-httpclient.jar}"/>
+ <pathelement location="${commons-codec.jar}"/>
+ <pathelement location="${commons-logging.jar}"/>
+ </path>
+
+ <!-- =================================================================== -->
+ <!-- prints the environment -->
+ <!-- =================================================================== -->
+ <target name="env">
+ <echo message="java.home = ${java.home}"/>
+ <echo message="user.home = ${user.home}"/>
+ <!--
+ <echo message="java.class.path = ${java.class.path}"/>
+ -->
+ <echo message=""/>
+ </target>
+
+ <target name="prepare" depends="env">
+ <mkdir dir="${build.dir}"/>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Creates the API documentation -->
+ <!-- =================================================================== -->
+ <target name="javadocs" description="Java documentation">
+ <mkdir dir="${docs.dest}"/>
+ <mkdir dir="${docs.dest}/api"/>
+ <javadoc sourcepath="${build.src}/java"
+ destdir="${docs.dest}/api"
+ author="true"
+ version="true"
+ overview="${src.dir}/java/overview.html"
+ packagenames="org.jboss.aloha.*"
+ windowtitle="${title} (Version ${version})"
+ doctitle="<h2>${title}</h2>"
+ bottom="Copyright 2008 Red Hat, Inc.<!--
+JBoss, the OpenSource J2EE webOS
+
+Distributable under LGPL license.
+See terms of license at gnu.org.-->">
+ <classpath refid="classpath"/>
+ </javadoc>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Cleans up the build directory -->
+ <!-- =================================================================== -->
+ <target name="clean">
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Compiles the source directory -->
+ <!-- =================================================================== -->
+ <target name="compile" depends="prepare">
+ <mkdir dir="${build.dest}"/>
+ <mkdir dir="${build.dest}/java"/>
+ <mkdir dir="${build.src}"/>
+ <mkdir dir="${build.src}/java"/>
+ <tstamp>
+ <format property="TODAY" pattern="MMM d yyyy" locale="en"/>
+ <format property="TSTAMP" pattern="hh:mm:ss"/>
+ </tstamp>
+ <!-- Copy static resource files -->
+ <filter token="VERSION" value="${version}"/>
+ <filter token="VERSION_NUMBER" value="${version.number}"/>
+ <filter token="VERSION_BUILT" value="${TODAY} ${TSTAMP}"/>
+ <copy todir="${build.src}/java" filtering="yes">
+ <fileset dir="${src.dir}/java">
+ <include name="**/*.java"/>
+ <include name="**/*.xml"/>
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+
+ <javac srcdir="${build.src}/java"
+ destdir="${build.dest}/java"
+ debug="${debug}"
+ deprecation="${deprecation}"
+ source="${compile.source}"
+ target="${compile.target}"
+ failonerror="false"
+ optimize="${optimize}">
+ <classpath refid="classpath"/>
+ <compilerarg line="-Xmaxerrs 1000"/>
+ </javac>
+ <copy todir="${build.dest}/java" filtering="yes">
+ <fileset dir="${build.src}/java">
+ <include name="**/*.xml"/>
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="compile-only"
+ description="Compile shareable components">
+
+ <javac srcdir="${source.home}"
+ destdir="${build.home}/java"
+ debug="${compile.debug}"
+ source="${compile.source}"
+ target="${compile.target}"
+ deprecation="${compile.deprecation}"
+ optimize="${compile.optimize}">
+ <classpath refid="classpath"/>
+ </javac>
+ <copy todir="${build.home}/java" filtering="on">
+ <fileset dir="${source.home}" excludes="**/*.java"/>
+ </copy>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Compiles the examples directory -->
+ <!-- =================================================================== -->
+ <target name="examples" depends="compile">
+ <mkdir dir="${build.dest}"/>
+ <mkdir dir="${build.dest}/examples"/>
+ <mkdir dir="${build.src}"/>
+ <mkdir dir="${build.src}/examples"/>
+ <tstamp>
+ <format property="TODAY" pattern="MMM d yyyy" locale="en"/>
+ <format property="TSTAMP" pattern="hh:mm:ss"/>
+ </tstamp>
+ <!-- Copy static resource files -->
+ <filter token="VERSION" value="${version}"/>
+ <filter token="VERSION_NUMBER" value="${version.number}"/>
+ <filter token="VERSION_BUILT" value="${TODAY} ${TSTAMP}"/>
+ <copy todir="${build.src}/examples" filtering="yes">
+ <fileset dir="${src.dir}/examples">
+ <include name="**/*.java"/>
+ <include name="**/*.xml"/>
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+
+ <javac srcdir="${build.src}/examples"
+ destdir="${build.dest}/examples"
+ debug="${debug}"
+ source="${compile.source}"
+ target="${compile.target}"
+ deprecation="${deprecation}"
+ optimize="${optimize}">
+ <classpath refid="examples.classpath"/>
+ </javac>
+ <copy todir="${build.dest}/examples" filtering="yes">
+ <fileset dir="${build.src}/examples">
+ <include name="**/*.xml"/>
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- ================================================================== -->
+ <!-- Make the library jar -->
+ <!-- ================================================================== -->
+ <target name="jar" depends="compile"
+ description="Generates the Jar file">
+ <jar
+ destfile="${build.dir}/${final.name}.jar"
+ basedir="${build.dir}/bin/java"
+ excludes="**/*.java">
+ <manifest>
+ <section name="org/jboss/aloha">
+ <attribute name="Specification-Title" value="JBoss Aloha library"/>
+ <attribute name="Specification-Version" value="${version}"/>
+ <attribute name="Specification-Vendor" value="Red Hat, Inc."/>
+ <attribute name="Implementation-Title" value="org.jboss.aloha"/>
+ <attribute name="Implementation-Vendor" value="Red Hat Middleware, LLC"/>
+ <attribute name="Implementation-Vendor-Id" value="org.jboss"/>
+ <attribute name="Implementation-Version" value="${version} (build ${DSTAMP} ${TSTAMP})"/>
+ </section>
+ </manifest>
+ </jar>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Compiles the test directory -->
+ <!-- =================================================================== -->
+ <target name="tests" depends="compile">
+ <mkdir dir="${build.dest}/test"/>
+ <mkdir dir="${build.src}/test"/>
+ <copy todir="${build.src}/test" filtering="yes">
+ <fileset dir="${src.dir}/test">
+ <include name="**/*.java"/>
+ <include name="**/*.xml"/>
+ <include name="**/*.properties"/>
+ </fileset>
+ </copy>
+ <javac srcdir="${build.src}/test"
+ destdir="${build.dest}/test"
+ debug="${debug}"
+ source="${compile.source}"
+ target="${compile.target}"
+ deprecation="${deprecation}"
+ optimize="${optimize}">
+ <classpath refid="test.classpath"/>
+ </javac>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Junit tests -->
+ <!-- =================================================================== -->
+ <target name="test" depends="tests">
+ <echo message="Running ALOHA package tests ..."/>
+ <java dir="${test.dir}" classname="${test.entry}" fork="yes" failonerror="${test.failonerror}">
+ <classpath refid="test.classpath"/>
+ </java>
+ </target>
+
+ <!-- =================================================================== -->
+ <!-- Run Example -->
+ <!-- =================================================================== -->
+ <target name="run" depends="examples">
+ <echo message="Running ALOHA package example ${example} ..."/>
+ <java dir="${examples.dir}" classname="org.jboss.aloha.${example}" fork="yes" failonerror="${test.failonerror}">
+ <classpath refid="examples.classpath"/>
+ </java>
+ </target>
+
+</project>
Property changes on: sandbox/aloha/build.xml
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months
JBoss Native SVN: r1630 - in sandbox/aloha: java and 5 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:47:01 -0400 (Wed, 28 May 2008)
New Revision: 1630
Added:
sandbox/aloha/java/
sandbox/aloha/java/org/
sandbox/aloha/java/org/jboss/
sandbox/aloha/java/org/jboss/aloha/
sandbox/aloha/java/org/jboss/aloha/AdvertiseMode.java
sandbox/aloha/java/org/jboss/aloha/Application.java
sandbox/aloha/java/org/jboss/aloha/ApplicationPool.java
sandbox/aloha/java/org/jboss/aloha/Balancer.java
sandbox/aloha/java/org/jboss/aloha/BalancerMethod.java
sandbox/aloha/java/org/jboss/aloha/BooleanType.java
sandbox/aloha/java/org/jboss/aloha/Command.java
sandbox/aloha/java/org/jboss/aloha/Default.java
sandbox/aloha/java/org/jboss/aloha/GenericResource.java
sandbox/aloha/java/org/jboss/aloha/Globals.java
sandbox/aloha/java/org/jboss/aloha/Host.java
sandbox/aloha/java/org/jboss/aloha/HttpMessage.java
sandbox/aloha/java/org/jboss/aloha/InvalidValueException.java
sandbox/aloha/java/org/jboss/aloha/ManagedServer.java
sandbox/aloha/java/org/jboss/aloha/Manager.java
sandbox/aloha/java/org/jboss/aloha/Member.java
sandbox/aloha/java/org/jboss/aloha/MemberApplication.java
sandbox/aloha/java/org/jboss/aloha/Message.java
sandbox/aloha/java/org/jboss/aloha/MessageFactory.java
sandbox/aloha/java/org/jboss/aloha/MessageProtocol.java
sandbox/aloha/java/org/jboss/aloha/Parameter.java
sandbox/aloha/java/org/jboss/aloha/ParameterType.java
sandbox/aloha/java/org/jboss/aloha/ParameterUpdateCallback.java
sandbox/aloha/java/org/jboss/aloha/ProtocolType.java
sandbox/aloha/java/org/jboss/aloha/Resource.java
sandbox/aloha/java/org/jboss/aloha/ResourceType.java
sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java
sandbox/aloha/java/org/jboss/aloha/ResponseType.java
sandbox/aloha/java/org/jboss/aloha/Server.java
sandbox/aloha/java/org/jboss/aloha/StateMode.java
sandbox/aloha/java/org/jboss/aloha/advertise/
sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseEventType.java
sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseListener.java
sandbox/aloha/java/org/jboss/aloha/advertise/AdvertisedServer.java
sandbox/aloha/java/org/jboss/aloha/advertise/IAdvertiseEvent.java
sandbox/aloha/java/org/jboss/aloha/util/
sandbox/aloha/java/org/jboss/aloha/util/Base64.java
sandbox/aloha/java/org/jboss/aloha/util/Utils.java
sandbox/aloha/java/overview.html
Log:
Add core java classes
Added: sandbox/aloha/java/org/jboss/aloha/AdvertiseMode.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/AdvertiseMode.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/AdvertiseMode.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * AdvertiseMode enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum AdvertiseMode
+{
+ On,
+ Off,
+ Status;
+
+ public static AdvertiseMode valueOfIgnoreCase(String name)
+ {
+ for (AdvertiseMode e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ throw new IllegalArgumentException("Invalid initializer: " + name);
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/AdvertiseMode.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Application.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Application.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Application.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Application resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Application extends Resource
+{
+
+ public Parameter Host = addParameter("Host", true, ParameterType.Resource);
+ public Parameter ApplicationPool = addParameter("ApplicationPool", false, ParameterType.Resource);
+ public Parameter State = addParameter("State", false, ParameterType.State);
+ public Parameter Status = addParameter("Status", false, ParameterType.State);
+
+ public ResourceType getResourceType() { return ResourceType.Application; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return Host.getResource(); }
+
+ private String resourceName;
+
+ private Application()
+ {
+ // Disable creation of unnamed resource
+ }
+
+ public Application(Host host, String name)
+ {
+ super(host.getManagedServer());
+ resourceName = name;
+ if (host != null) {
+ // Reference this Application to the Host
+ host.addApplication(this);
+ try {
+ Host.setValue(host);
+ } catch (Exception e) {
+ // Ignore
+ }
+ try {
+ for (Member m : ((Balancer)host.Balancer.getResource()).getMembers()) {
+ m.addApplication(this);
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+
+ protected Application(ManagedServer managedServer, String name)
+ {
+ this((Host)managedServer.getResource(ResourceType.Host), name);
+ }
+
+ public void onUpdateResource(Parameter p, Resource ov, Resource nv)
+ {
+ if (nv.getResourceType() == ResourceType.ApplicationPool) {
+ // Changing ApplicationPool
+ }
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Application.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ApplicationPool.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ApplicationPool.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ApplicationPool.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * ApplicationPool resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class ApplicationPool extends Resource
+{
+ public Parameter Status = addParameter("Status", false, ParameterType.State);
+ public Parameter Busy = addParameter("Busy", true, ParameterType.Integer);
+ public Parameter Concurrency = addParameter("Concurrency", false, ParameterType.Integer);
+ public Parameter TimeOut = addParameter("TimeOut", false, ParameterType.Long);
+ public Parameter Applications = addParameter("Applications", true, ParameterType.Integer);
+
+
+ public ResourceType getResourceType() { return ResourceType.ApplicationPool; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+
+ private String resourceName;
+
+ private ApplicationPool()
+ {
+ // Disable creation of unlinked resource
+ }
+
+ public ApplicationPool(ManagedServer managedServer, String name)
+ {
+ super(managedServer);
+ resourceName = name;
+ }
+
+ public ApplicationPool(ManagedServer managedServer)
+ {
+ this(managedServer, Default.NAME);
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ApplicationPool.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Balancer.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Balancer.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Balancer.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,120 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Balancer resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Balancer extends Resource
+{
+ public Parameter Status = addParameter("Status", false, ParameterType.State);
+ public Parameter StickySession = addParameter("StickySession", false, ParameterType.Boolean);
+ public Parameter StickySessionCookie = addParameter("StickySessionCookie", false, ParameterType.String);
+ public Parameter StickySessionPath = addParameter("StickySessionPath", false, ParameterType.String);
+ public Parameter StickySessionRemove = addParameter("StickySessionRemove", false, ParameterType.Boolean);
+ public Parameter StickySessionForce = addParameter("StickySessionForce", false, ParameterType.Boolean);
+ public Parameter TimeOut = addParameter("TimeOut", false, ParameterType.Long);
+ public Parameter MaxFailoverAttempts = addParameter("MaxFailoverAttempts", false, ParameterType.Integer);
+ public Parameter AbortIfHeadersSend = addParameter("AbortIfHeadersSend", false, ParameterType.Boolean);
+ public Parameter AbortIfResponseReceived = addParameter("AbortIfResponseReceived",false, ParameterType.Boolean);
+ public Parameter InterstageMethod = addParameter("InterstageMethod", false, ParameterType.BalancerMethod);
+
+
+ public ResourceType getResourceType() { return ResourceType.Balancer; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+ private ManagedServer managedServer;
+
+ private String resourceName;
+ private HashMap<String, Member> memberMap;
+ private HashMap<String, Host> hostMap;
+
+
+ public Collection<Member> getMembers()
+ {
+ return memberMap.values();
+ }
+
+ public void addMember(Member member)
+ {
+ memberMap.put(member.getResourceName(), member);
+ }
+
+ public Member getMember(String name)
+ {
+ return memberMap.get(name);
+ }
+
+ public void removeMember(Member member)
+ {
+ memberMap.remove(member);
+ }
+
+ public Collection<Host> getHosts()
+ {
+ return hostMap.values();
+ }
+
+ public void addHost(Host host)
+ {
+ hostMap.put(host.getResourceName(), host);
+ }
+
+ public Host getHost(String name)
+ {
+ return hostMap.get(name);
+ }
+
+ public void removeHost(Host host)
+ {
+ hostMap.remove(host);
+ }
+
+ private Balancer()
+ {
+ // Disable creation of unlinked resource
+ }
+
+ protected Balancer(ManagedServer managedServer, String name)
+ {
+ super(managedServer);
+ resourceName = name;
+ memberMap = new HashMap<String, Member>();
+ hostMap = new HashMap<String, Host>();
+ }
+
+ protected Balancer(ManagedServer managedServer)
+ {
+ this(managedServer, Default.NAME);
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Balancer.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/BalancerMethod.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/BalancerMethod.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/BalancerMethod.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * BalancerMethod enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum BalancerMethod
+{
+ Unknown( "-"),
+ RoundRobin( "R"),
+ Busyness( "B");
+
+ private String value;
+ private BalancerMethod(String v)
+ {
+ value = v;
+ }
+
+ public String valueOf()
+ {
+ return value;
+ }
+
+ public static BalancerMethod valueOfIgnoreCase(String name)
+ {
+ for (BalancerMethod e : values()) {
+ if (e.value.equalsIgnoreCase(name))
+ return e;
+ else if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ return BalancerMethod.Unknown;
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/BalancerMethod.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/BooleanType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/BooleanType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/BooleanType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * BooleanType enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum BooleanType
+{
+ Yes( true),
+ No( false),
+ Y( true),
+ N( false),
+ On( true),
+ Off( false),
+ True( true),
+ False( false);
+
+ private boolean value;
+ private BooleanType(boolean v)
+ {
+ value = v;
+ }
+
+ public boolean valueOf()
+ {
+ return value;
+ }
+
+ public static BooleanType valueOfIgnoreCase(String name)
+ {
+ for (BooleanType e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ if (Long.parseLong(name) == 0)
+ return BooleanType.False;
+ else
+ return BooleanType.True;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/BooleanType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Command.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Command.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Command.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * Command type enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum Command
+{
+ Info,
+ Enable,
+ Disable,
+ Stop,
+ Delete,
+ Config,
+ Exec,
+ Reset;
+
+ public static Command valueOfIgnoreCase(String name)
+ {
+ for (Command e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ throw new IllegalArgumentException("Invalid initializer: " + name);
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Command.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Default.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Default.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Default.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * Default values
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Default
+{
+
+ /** Default charset used for protocol messages */
+ public static final String CHARSET = "8859_1";
+ public static final String MANAGER_URL = "/server-manager";
+ public static final String NAME = "_default_";
+
+ public static int CONNECT_TIMEOUT = 1000;
+ public static int READ_TIMEOUT = 2000;
+
+ public static final long MANAGER_ID = 1L;
+ public static final long SERVER_ID = 2L;
+
+ private Default()
+ {
+ // Disable creation
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Default.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/GenericResource.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/GenericResource.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/GenericResource.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Generic resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class GenericResource extends Resource
+{
+
+ private ResourceType resourceType = ResourceType.Unknown;
+ private String resourceName;
+
+ public ResourceType getResourceType() { return resourceType; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+ private ManagedServer managedServer;
+
+ public void setResourceType(ResourceType v) { resourceType = v; }
+ public void setResourceName(String v) { resourceName = v; }
+
+ public GenericResource(ManagedServer managedServer, String name)
+ {
+ resourceName = name;
+ this.managedServer = managedServer;
+ }
+
+ public GenericResource(ManagedServer managedServer)
+ {
+ this(managedServer, ResourceType.Unknown.toString());
+ }
+
+ public GenericResource()
+ {
+ this(null);
+ }
+
+ public void addParameter(String name, String value)
+ {
+ Parameter p = new Parameter(name, value);
+ addParameter(p);
+ }
+
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/GenericResource.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Globals.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Globals.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Globals.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * Global constant values
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Globals
+{
+
+ /** MCMP protocol prefix */
+ public static final String MCMP = "MCMP/";
+
+ /** MCMP protocol Unknown-Type warning message prefix */
+ public static final String UNKNOWN_TYPE = "Unknown-Type:";
+
+ /** MCMP protocol Unknown-Resource warning message prefix */
+ public static final String UNKNOWN_RESOURCE = "Unknown-Resource:";
+
+ /** MCMP protocol error message prefix */
+ public static final String ERROR = "Error:";
+
+ /** MCMP protocol Resource Header name */
+ public static final String SERVER_RESOURCE = "X-Server-Resource";
+
+ /** MCMP protocol Command Header name */
+ public static final String SERVER_COMMAND = "X-Server-Command";
+
+ /** MCMP protocol Server Ping name */
+ public static final String SERVER_PING = "X-Server-Ping";
+
+ /** RFC 822 textual Date format used by SimpleDateFormat */
+ public static final String RFC_822_FMT = "EEE, d MMM yyyy HH:mm:ss Z";
+
+ private Globals()
+ {
+ // Disable creation
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Globals.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Host.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Host.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Host.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,126 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Host resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Host extends Resource
+{
+
+ public Parameter Balancer = addParameter("Balancer", false, ParameterType.Resource);
+
+ public Parameter ServerName = addParameter("ServerName", false, ParameterType.String);
+ public Parameter ServerAlias = addParameter("ServerAlias", false, ParameterType.StringArray);
+ public Parameter DocumentRoot = addParameter("DocumentRoot", false, ParameterType.String);
+ public Parameter IsVirtual = addParameter("IsVirtual", false, ParameterType.Boolean);
+ public Parameter KeepAlive = addParameter("KeepAlive", false, ParameterType.Boolean);
+ public Parameter KeepAliveTimeout = addParameter("KeepAliveTimeout", false, ParameterType.Long);
+ public Parameter MaxKeepAliveRequests = addParameter("MaxKeepAliveRequests", false, ParameterType.Integer);
+ public Parameter TimeOut = addParameter("TimeOut", false, ParameterType.Long);
+ public Parameter LimitRequestBody = addParameter("LimitRequestBody", false, ParameterType.Integer);
+ public Parameter Address = addParameter("Address", false, ParameterType.String);
+ public Parameter Port = addParameter("Port", false, ParameterType.Integer);
+ public Parameter Status = addParameter("Status", false, ParameterType.State);
+
+ public ResourceType getResourceType() { return ResourceType.Server; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+
+ private String resourceName;
+ private HashMap<String, Application> applicationMap;
+
+ public Collection<Application> getApplications()
+ {
+ return applicationMap.values();
+ }
+
+ public Application getApplication(String name)
+ {
+ return applicationMap.get(name);
+ }
+
+ public void addApplication(Application application)
+ {
+ applicationMap.put(application.getResourceName(), application);
+ }
+
+ public void removeApplication(Application application)
+ {
+ applicationMap.remove(application);
+ }
+
+ private Host()
+ {
+ // Disable creation of unlinked resource
+ }
+
+ protected Host(ManagedServer managedServer, Balancer balancer, String name)
+ {
+ super(managedServer);
+ resourceName = name;
+ applicationMap = new HashMap<String, Application>();
+ if (balancer != null) {
+ // Reference this Host to the Balancer
+ balancer.addHost(this);
+ try {
+ Balancer.setValue(balancer);
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+
+ protected Host(ManagedServer managedServer, String name)
+ {
+ this(managedServer, (Balancer)managedServer.getResource(ResourceType.Balancer), name);
+ }
+
+ protected Host(ManagedServer managedServer)
+ {
+ this(managedServer, Default.NAME);
+ }
+
+ public void onUpdateResource(Parameter p, Resource ov, Resource nv)
+ {
+ if (nv.getResourceType() == ResourceType.Balancer) {
+ // Changing Balancer for this host
+ Balancer ob = (Balancer)ov;
+ Balancer nb = (Balancer)nv;
+ if (ob != null)
+ ob.removeHost(this);
+ if (nb != null)
+ nb.addHost(this);
+ }
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Host.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/HttpMessage.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/HttpMessage.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/HttpMessage.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
+
+import java.net.URL;
+import java.net.URLEncoder;
+import java.net.HttpURLConnection;
+
+import java.net.ProtocolException;
+import java.net.MalformedURLException;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the HTTP protocol Message to remote Web Server
+ * instance using MCMP protocol
+ *
+ * @author Mladen Turk
+ *
+ */
+public class HttpMessage extends Message
+{
+
+ private static final String GET = "GET";
+ private static final String OK = "OK";
+ private static final String ERR_500 = "?Error: 502; Internal Server Error";
+ private static final String ERR_502 = "?Error: 502; Bad Gateway";
+ private static final String ERR_505 = "?Error: 505; HTTP Version not supported";
+ private static final String ERR_400 = "?Error: 400; Bad Request";
+ private static final String ERR_403 = "?Error: 403; Forbidded";
+ private static final String ERR_404 = "?Error: 404; Not Found";
+ private static final String ERR_405 = "?Error: 405; Method Not Allowed";
+ private int responseCode = 0;
+ private String responseDesc = "";
+
+ /**
+ * Creates an empty Message
+ */
+ public HttpMessage()
+ {
+ }
+
+ protected Message getInstance()
+ {
+ return this;
+ }
+
+ /**
+ * Return HTTP response code
+ */
+ public int getResponseCode()
+ {
+ return responseCode;
+ }
+
+ public String getResponse(String query)
+ {
+ HttpURLConnection conn;
+ try {
+ URL url = new URL(getMessageUrl());
+ conn = (HttpURLConnection)url.openConnection();
+ conn.setRequestMethod(GET);
+ } catch (MalformedURLException u) {
+ responseCode = HttpURLConnection.HTTP_BAD_REQUEST;
+ return ERR_400;
+ } catch (ProtocolException e) {
+ responseCode = HttpURLConnection.HTTP_BAD_METHOD;
+ return ERR_405;
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_FORBIDDEN;
+ return ERR_403;
+ }
+ conn.setAllowUserInteraction(false);
+ conn.setUseCaches(false);
+ conn.setDoInput(true);
+ conn.setDoOutput(false);
+ conn.setRequestProperty(Globals.SERVER_RESOURCE, query);
+ if (authorization != null) {
+ // Add Authorization header
+ conn.setRequestProperty("Authorization", authorization);
+ }
+
+ try {
+ conn.setConnectTimeout(connectTimeout);
+ conn.setReadTimeout(readTimeout);
+ conn.connect();
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_BAD_GATEWAY;
+ return ERR_502;
+ }
+ try {
+ responseCode = conn.getResponseCode();
+ responseDesc = conn.getResponseMessage();
+ } catch (IOException x) {
+ responseCode = HttpURLConnection.HTTP_VERSION;
+ conn.disconnect();
+ return ERR_505;
+ }
+
+ if (responseCode != HttpURLConnection.HTTP_OK) {
+ StringBuffer eb = new StringBuffer("?Error: ");
+ eb.append(responseCode);
+ eb.append("; ");
+ eb.append(responseDesc);
+ return eb.toString();
+ }
+
+ InputStream is;
+ try {
+ is = conn.getInputStream();
+ } catch (IOException e) {
+ responseCode = HttpURLConnection.HTTP_INTERNAL_ERROR;
+ conn.disconnect();
+ return ERR_500;
+ }
+ StringBuffer s = new StringBuffer();
+ int rd;
+ byte [] bb = new byte[1024];
+ try {
+ while ((rd = is.read(bb)) > 0) {
+ s.append(new String(bb, 0, rd, Default.CHARSET));
+ if (rd < 1024)
+ break;
+ }
+ } catch (Exception e) {
+ // Ignore. Return what we've got so far.
+ }
+ String r = s.toString();
+ if (s.length() == 0)
+ return OK;
+ else
+ return r;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/HttpMessage.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/InvalidValueException.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/InvalidValueException.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/InvalidValueException.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/** InvalidValueException
+ *
+ * @author Mladen Turk
+ *
+ */
+public class InvalidValueException extends Exception {
+
+ public InvalidValueException()
+ {
+ super();
+ }
+
+ public InvalidValueException(String msg)
+ {
+ super(msg);
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/InvalidValueException.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ManagedServer.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ManagedServer.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ManagedServer.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.LinkedList;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Represents the remote Web Server instance
+ *
+ * @author Mladen Turk
+ *
+ */
+public class ManagedServer
+{
+
+ private boolean initialized = false;
+ private Manager systemManager;
+ private Server systemServer;
+ private Host defaultHost;
+ private Balancer defaultBalancer;
+ private ApplicationPool defaultAppPool;
+
+ private HashMap<String, Host> hostMap;
+ private HashMap<String, Balancer> balancerMap;
+ private HashMap<String, ApplicationPool> appPoolMap;
+
+ /**
+ * Creates the empty instance of the ManagedServer
+ */
+ public ManagedServer()
+ {
+ hostMap = new HashMap<String, Host>();
+ balancerMap = new HashMap<String, Balancer>();
+ appPoolMap = new HashMap<String, ApplicationPool>();
+
+ // Default Resource objects
+ systemManager = new Manager(this);
+ systemServer = new Server(this);
+ defaultHost = new Host(this);
+ defaultBalancer = new Balancer(this);
+ defaultAppPool = new ApplicationPool(this);
+
+ hostMap.put(Default.NAME, defaultHost);
+ balancerMap.put(Default.NAME, defaultBalancer);
+ appPoolMap.put(Default.NAME, defaultAppPool);
+
+ }
+
+ public Collection<Host> getHosts()
+ {
+ return hostMap.values();
+ }
+
+ public Collection<Balancer> getBalancers()
+ {
+ return balancerMap.values();
+ }
+
+ public Collection<ApplicationPool> getApplicationPools()
+ {
+ return appPoolMap.values();
+ }
+
+ /**
+ * Gets the Resource object
+ * @param type ResourceType to get
+ */
+ public Resource getResource(ResourceType type)
+ {
+ if (type == ResourceType.Manager)
+ return systemManager;
+ else if (type == ResourceType.Server)
+ return systemServer;
+ else if (type == ResourceType.Host)
+ return defaultHost;
+ else if (type == ResourceType.Balancer)
+ return defaultBalancer;
+ else if (type == ResourceType.ApplicationPool)
+ return defaultAppPool;
+ else
+ return new GenericResource(this);
+ }
+
+ /**
+ * Gets the Resource object
+ * @param name Name of the Resource object to get
+ * @param type ResourceType to get
+ */
+ public Resource getResource(String name, ResourceType type)
+ {
+ if (name == null || name.equalsIgnoreCase(Default.NAME))
+ return getResource(type);
+ else if (type == ResourceType.Host) {
+ Host host = hostMap.get(name);
+ if (host == null) {
+ host = new Host(this, name);
+ hostMap.put(name, host);
+ }
+ return host;
+ }
+ else if (type == ResourceType.Balancer) {
+ Balancer balancer = balancerMap.get(name);
+ if (balancer == null) {
+ balancer = new Balancer(this, name);
+ balancerMap.put(name, balancer);
+ }
+ return balancer;
+ }
+ else if (type == ResourceType.ApplicationPool) {
+ ApplicationPool appPool = appPoolMap.get(name);
+ if (appPool == null) {
+ appPool = new ApplicationPool(this, name);
+ appPoolMap.put(name, appPool);
+ }
+ return appPool;
+ }
+ else
+ return new GenericResource(this, name);
+ }
+
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ManagedServer.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Manager.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Manager.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Manager.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,67 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Manager resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Manager extends Resource
+{
+ public Parameter ProtocolVersion = addParameter("ProtocolVersion", true, ParameterType.String);
+ public Parameter ServerId = addParameter("ServerId", true, ParameterType.String);
+ public Parameter Advertise = addParameter("Advertise", true, ParameterType.Boolean);
+ public Parameter AdvertiseMode = addParameter("AdvertiseMode", true, ParameterType.AdvertiseMode);
+ public Parameter Status = addParameter("Status", true, ParameterType.Integer);
+ public Parameter Strict = addParameter("Strict", false, ParameterType.Boolean);
+ public Parameter CaseInsensitive = addParameter("CaseInsensitive", false, ParameterType.Boolean);
+ public Parameter SecurityKey = addParameter("SecurityKey", false, ParameterType.String);
+
+
+ public ResourceType getResourceType() { return ResourceType.Manager; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+
+ private String resourceName = "Manager";
+
+ private Manager()
+ {
+ // Disable creation of unlinked resource
+ }
+
+ protected Manager(ManagedServer managedServer)
+ {
+ super(managedServer, Default.MANAGER_ID);
+ }
+}
+
+
+
Property changes on: sandbox/aloha/java/org/jboss/aloha/Manager.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Member.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Member.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Member.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,126 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Member resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Member extends Resource
+{
+ public Parameter Balancer = addParameter("Balancer", true, ParameterType.Resource);
+
+ public Parameter Type = addParameter("Type", false, ParameterType.ProtocolType);
+ public Parameter Address = addParameter("Address", false, ParameterType.String);
+ public Parameter Port = addParameter("Port", false, ParameterType.Integer);
+ public Parameter Route = addParameter("Route", false, ParameterType.String);
+ public Parameter Ping = addParameter("Ping", false, ParameterType.Integer);
+ public Parameter MaxConnections = addParameter("MaxConnections", false, ParameterType.Integer);
+ public Parameter MinConnections = addParameter("MinConnections", false, ParameterType.Integer);
+ public Parameter MaxClients = addParameter("MaxClients", false, ParameterType.Integer);
+ public Parameter TTL = addParameter("TTL", false, ParameterType.Integer);
+ public Parameter LF = addParameter("LF", false, ParameterType.Integer);
+ public Parameter Distance = addParameter("Distance", false, ParameterType.Integer);
+ public Parameter Activation = addParameter("Activation", false, ParameterType.State);
+ public Parameter FlushMode = addParameter("FlushMode", false, ParameterType.Char);
+ public Parameter FlushTimeout = addParameter("FlushTimeout", false, ParameterType.Long);
+ // Statistical Data
+ public Parameter State = addParameter("State", true, ParameterType.State);
+ public Parameter Error = addParameter("Error", true, ParameterType.String);
+ public Parameter Busy = addParameter("Busy", true, ParameterType.Integer);
+ public Parameter Connected = addParameter("Connected", true, ParameterType.Integer);
+ public Parameter Elected = addParameter("Elected", true, ParameterType.Integer);
+ public Parameter StickySessions = addParameter("StickySessions", true, ParameterType.Integer);
+ public Parameter ClientErrors = addParameter("ClientErrors", true, ParameterType.Integer);
+ public Parameter NodeErrors = addParameter("NodeErrors", true, ParameterType.Integer);
+ public Parameter Trace = addParameter("Trace", true, ParameterType.Integer);
+ public Parameter TraceErrors = addParameter("TraceErrors", true, ParameterType.Integer);
+ public Parameter Readed = addParameter("Readed", true, ParameterType.Long);
+ public Parameter Transferred = addParameter("Transferred", true, ParameterType.Long);
+
+
+ public ResourceType getResourceType() { return ResourceType.Member; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return Balancer.getResource(); }
+
+ private String resourceName;
+ private HashMap<String, MemberApplication> applicationMap;
+
+ private Member()
+ {
+ // Disable creation of unnamed resource
+ }
+
+ protected Member(Balancer balancer, String name)
+ {
+ resourceName = name;
+ applicationMap = new HashMap<String, MemberApplication>();
+ if (balancer != null) {
+ // Reference this Member to the Balancer
+ balancer.addMember(this);
+ try {
+ Balancer.setValue(balancer);
+ } catch (Exception e) {
+ // Ignore
+ }
+ try {
+ for (Host h : balancer.getHosts()) {
+ for (Application a : h.getApplications()) {
+ /* Add existing Applications */
+ addApplication(a);
+ }
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ }
+
+ protected Member(ManagedServer managedServer, String name)
+ {
+ this((Balancer)managedServer.getResource(ResourceType.Balancer), name);
+ }
+
+ public Collection<MemberApplication> getApplications()
+ {
+ return applicationMap.values();
+ }
+
+ public void addApplication(Application application)
+ {
+ MemberApplication ma = new MemberApplication(this, application);
+ applicationMap.put(application.getResourceName(), ma);
+ }
+}
+
+
+
Property changes on: sandbox/aloha/java/org/jboss/aloha/Member.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/MemberApplication.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/MemberApplication.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/MemberApplication.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * MemberApplication resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class MemberApplication extends Resource
+{
+
+ public Parameter Member = addParameter("Member", true, ParameterType.Resource);
+ public Parameter Application = addParameter("Application", true, ParameterType.Resource);
+
+ public Parameter State = addParameter("State", false, ParameterType.State);
+ // Statistical Data
+ public Parameter Busy = addParameter("Busy", true, ParameterType.Integer);
+ public Parameter Transactions = addParameter("Transactions", true, ParameterType.Integer);
+ public Parameter ClientErrors = addParameter("ClientErrors", true, ParameterType.Integer);
+ public Parameter NodeErrors = addParameter("NodeErrors", true, ParameterType.Integer);
+ public Parameter Readed = addParameter("Readed", true, ParameterType.Long);
+ public Parameter Transferred = addParameter("Transferred", true, ParameterType.Long);
+
+ public ResourceType getResourceType() { return ResourceType.Application; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return member; }
+
+ private String resourceName;
+ private Member member;
+ private Application application;
+
+ private MemberApplication()
+ {
+ // Disable creation of unnamed resource
+ }
+
+ public MemberApplication(Member member, Application application)
+ {
+ this.member = member;
+ this.application = application;
+ resourceName = application.getResourceName();
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/MemberApplication.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Message.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Message.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Message.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,125 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.jboss.aloha.util.*;
+
+/**
+ * Represents the Message send to remote Web Server instance
+ * using MCMP protocol
+ *
+ * @author Mladen Turk
+ *
+ */
+public abstract class Message
+{
+
+ private MessageProtocol protocol = MessageProtocol.Http;
+ private Command cmd = Command.Info;
+
+ private String host = "localhost";
+ private int port = 0;
+ private String url = Default.MANAGER_URL;
+ protected int connectTimeout = Default.CONNECT_TIMEOUT;
+ protected int readTimeout = Default.READ_TIMEOUT;
+ protected String authorization = null;
+
+ /**
+ * Creates an empty connection to ManagedServer
+ */
+ public Message()
+ {
+ }
+
+ protected abstract int getResponseCode();
+ protected abstract String getResponse(String query);
+ protected abstract Message getInstance();
+
+ public void setProtocol(MessageProtocol v) { protocol = v; }
+
+ public void setProtocol(String v)
+ throws IllegalArgumentException
+ {
+ protocol = MessageProtocol.valueOfIgnoreCase(v);
+ }
+
+ public MessageProtocol getProtocol() { return protocol; }
+
+
+ public void setCommand(Command v) { cmd = v; }
+ public Command getCommand() { return cmd; }
+
+ public void setHost(String v) { host = v; }
+ public String getHost() { return host; }
+
+ public void setPort(int v) { port = v; }
+ public int getPort() { return port; }
+
+ public void setManagerUrl(String v) { url = v; }
+ public String getManagerUrl() { return url; }
+
+ public void setConnectTimeout(int v) { connectTimeout = v; }
+ public int getConnectTimeout() { return connectTimeout; }
+
+ public void setReadTimeout(int v) { readTimeout = v; }
+ public int getReadTimeout() { return readTimeout; }
+
+ public String getAuthorization() { return authorization; }
+
+ /**
+ * Sets the Basic Authorization credentials
+ */
+ public void setAuthorization(String username, String password)
+ {
+ if (username != null && password != null)
+ authorization = "Basic " + Base64.encode(username + ":" + password);
+ }
+
+ /**
+ * Sets the Authorization credentials
+ */
+ public void setAuthorization(String authorization)
+ {
+ this.authorization = authorization;
+ }
+
+ public String getMessageUrl()
+ {
+ StringBuffer sb = new StringBuffer(protocol.name().toLowerCase());
+ sb.append("://");
+ sb.append(host);
+ if (port > 0) {
+ sb.append(':');
+ sb.append(port);
+ }
+ sb.append(url);
+ sb.append('/');
+ sb.append(cmd.name());
+ return sb.toString();
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Message.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/MessageFactory.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/MessageFactory.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/MessageFactory.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import org.jboss.aloha.util.*;
+
+/**
+ * MessageFactory
+ *
+ * @author Mladen Turk
+ *
+ */
+public class MessageFactory
+{
+
+ private MessageProtocol protocol = MessageProtocol.Http;
+ private ResponseBodyParser parser = new ResponseBodyParser();
+ private Message message;
+ private String host = "localhost";
+ private int port = 0;
+ private String url = Default.MANAGER_URL;
+ protected int connectTimeout = Default.CONNECT_TIMEOUT;
+ protected int readTimeout = Default.READ_TIMEOUT;
+ protected String authorization = null;
+
+ /**
+ * Creates an empty connection to ManagedServer
+ */
+ public MessageFactory(Message message)
+ {
+ this.message = message;
+ }
+
+ public void setProtocol(MessageProtocol v) { protocol = v; }
+
+ public void setProtocol(String v)
+ throws IllegalArgumentException
+ {
+ protocol = MessageProtocol.valueOfIgnoreCase(v);
+ }
+
+ public MessageProtocol getProtocol() { return protocol; }
+
+
+ public void setHost(String v) { host = v; }
+ public String getHost() { return host; }
+
+ public void setPort(int v) { port = v; }
+ public int getPort() { return port; }
+
+ public void setManagerUrl(String v) { url = v; }
+ public String getManagerUrl() { return url; }
+
+ public void setConnectTimeout(int v) { connectTimeout = v; }
+ public int getConnectTimeout() { return connectTimeout; }
+
+ public void setReadTimeout(int v) { readTimeout = v; }
+ public int getReadTimeout() { return readTimeout; }
+
+ public String getAuthorization() { return authorization; }
+
+ /**
+ * Sets the Basic Authorization credentials
+ */
+ public void setAuthorization(String username, String password)
+ {
+ if (username != null && password != null)
+ authorization = "Basic " + Base64.encode(username + ":" + password);
+ }
+
+ /**
+ * Sets the Authorization credentials
+ */
+ public void setAuthorization(String authorization)
+ {
+ this.authorization = authorization;
+ }
+
+ public Message getMessage()
+ {
+ Message msg = message.getInstance();
+
+ msg.setProtocol(protocol);
+ msg.setHost(host);
+ msg.setPort(port);
+ msg.setManagerUrl(url);
+ msg.setConnectTimeout(connectTimeout);
+ msg.setReadTimeout(readTimeout);
+ msg.setAuthorization(authorization);
+
+ return msg;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/MessageFactory.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/MessageProtocol.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/MessageProtocol.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/MessageProtocol.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * MessageProtocol enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum MessageProtocol
+{
+ Http,
+ Https;
+
+ public static MessageProtocol valueOfIgnoreCase(String name)
+ {
+ for (MessageProtocol e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ throw new IllegalArgumentException("Invalid initializer: " + name);
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/MessageProtocol.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Parameter.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Parameter.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Parameter.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,468 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.Locale;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+
+/**
+ * Parameter object
+ *
+ * @author Mladen Turk
+ *
+ */
+public class Parameter
+{
+
+ private SimpleDateFormat df = new SimpleDateFormat(Globals.RFC_822_FMT, Locale.US);
+ private boolean readOnly = false;
+ private boolean modified = false;
+ private boolean updated = false;
+ private boolean initset = false;
+ private String name;
+ private Resource holder = null;
+ private String vS = "";
+ private String [] sA = { ""};
+ private int [] iA = { 0 };
+ private Date vD = new Date(0);
+ private int vI = 0;
+ private char vC = '\0';
+ private long vL = 0L;
+ private BooleanType bT = BooleanType.False;
+ private AdvertiseMode aM = AdvertiseMode.Off;
+ private BalancerMethod bM = BalancerMethod.Unknown;
+ private StateMode sM = StateMode.Unknown;
+ private Resource vR = null;
+ private ProtocolType pT = ProtocolType.Ajp;
+ private ParameterType type;
+
+ private Parameter()
+ {
+ // Disable creation
+ }
+
+ public Parameter(Resource holder, String name, boolean readOnly, ParameterType type)
+ {
+ this.holder = holder;
+ this.name = name;
+ this.readOnly = readOnly;
+ this.type = type;
+ }
+
+ public Parameter(String name, boolean readOnly, ParameterType type)
+ {
+ this(null, name, readOnly, type);
+ }
+
+ public Parameter(String name, boolean readOnly, ParameterType type,
+ String defaultValue)
+ {
+ this(name, readOnly, type);
+ putValue(defaultValue);
+ }
+
+ public Parameter(String name, String value)
+ {
+ this(name, false, ParameterType.String, value);
+ initset = true;
+ }
+
+ public boolean isReadOnly()
+ {
+ return readOnly;
+ }
+
+ protected boolean isModified()
+ {
+ return modified;
+ }
+
+ protected boolean isUpdated()
+ {
+ return updated;
+ }
+
+ protected void clearModifiedFlag()
+ {
+ modified = false;
+ }
+
+ protected void clearUpdatedFlag()
+ {
+ updated = false;
+ }
+
+ protected boolean equals(String name)
+ {
+ return this.name.equalsIgnoreCase(name);
+ }
+
+ protected boolean equals(Parameter other)
+ {
+ return this.name.equalsIgnoreCase(other.name);
+ }
+
+ private void canModify()
+ throws IllegalAccessException
+ {
+ if (!initset) {
+ initset = true;
+ return;
+ }
+ if (readOnly) {
+ throw new IllegalAccessException("Cannot update: " + name);
+ }
+ else {
+ modified = true;
+ }
+ }
+
+ public void setValue(Parameter value)
+ throws IllegalAccessException
+ {
+ canModify();
+ putValue(value.getValue());
+ }
+
+ public void setValue(int value)
+ throws IllegalAccessException
+ {
+ canModify();
+ vI = value;
+ }
+
+ public void setValue(char value)
+ throws IllegalAccessException
+ {
+ canModify();
+ vC = Character.toUpperCase(value);
+ }
+
+ public void setValue(boolean value)
+ throws IllegalAccessException
+ {
+ canModify();
+ if (value)
+ bT = BooleanType.True;
+ else
+ bT = BooleanType.False;
+ }
+
+ public void setValue(long value)
+ throws IllegalAccessException
+ {
+ canModify();
+ vL = value;
+ if (type == ParameterType.Date ||
+ type == ParameterType.Rfc822Date)
+ vD = new Date(value);
+ }
+
+ public void setValue(Date value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null) {
+ vD = value;
+ vL = value.getTime();
+ }
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(AdvertiseMode value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ aM = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(BalancerMethod value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ bM = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(ProtocolType value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ pT = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(StateMode value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ sM = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(BooleanType value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ bT = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(Resource value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null && value != vR) {
+ if (holder != null) {
+ holder.onUpdateResource(this, vR, value);
+ }
+ vR = value;
+ }
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(String value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null) {
+ vS = value;
+ if (type == ParameterType.StringArray)
+ sA = value.split("\\s+");
+ }
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void setValue(String [] value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ sA = value;
+ else
+ throw new InvalidValueException(name);
+ }
+ public void setValue(int [] value)
+ throws IllegalAccessException, InvalidValueException
+ {
+ canModify();
+ if (value != null)
+ iA = value;
+ else
+ throw new InvalidValueException(name);
+ }
+
+ public void putValue(Parameter value)
+ {
+ putValue(value.getValue());
+ }
+
+ public void putValue(String value)
+ {
+ try {
+ if (value == null || value.length() == 0) {
+ // Ignore
+ return;
+ }
+ else if (type == ParameterType.String) {
+ vS = value;
+ }
+ else if (type == ParameterType.StringArray) {
+ vS = value;
+ sA = value.split("\\s+");
+ }
+ else if (type == ParameterType.Char) {
+ vC = Character.toUpperCase(value.charAt(0));
+ }
+ else if (type == ParameterType.Integer) {
+ vI = Integer.parseInt(value);
+ }
+ else if (type == ParameterType.IntegerArray) {
+ vS = value;
+ sA = vS.split("\\.");
+ iA = new int[sA.length];
+ for (int i = 0; i < iA.length; i++)
+ iA[i] = Integer.parseInt(sA[i]);
+ }
+ else if (type == ParameterType.Long) {
+ vL = Long.parseLong(value);
+ }
+ else if (type == ParameterType.Date) {
+ vL = Long.parseLong(value);
+ vD = new Date(vL);
+ }
+ else if (type == ParameterType.Rfc822Date) {
+ try {
+ vD = df.parse(value);
+ } catch (ParseException e) {
+ vD = new Date(0);
+ }
+ vL = vD.getTime();
+ }
+ else if (type == ParameterType.AdvertiseMode) {
+ try {
+ aM = AdvertiseMode.valueOfIgnoreCase(value);
+ } catch (IllegalArgumentException e) {
+ // Ignore
+ }
+ }
+ else if (type == ParameterType.BalancerMethod) {
+ bM = BalancerMethod.valueOfIgnoreCase(value);
+ }
+ else if (type == ParameterType.ProtocolType) {
+ pT = ProtocolType.valueOfIgnoreCase(value);
+ }
+ else if (type == ParameterType.Boolean) {
+ bT = BooleanType.valueOfIgnoreCase(value);
+ }
+ else if (type == ParameterType.State) {
+ sM = StateMode.valueOfIgnoreCase(value);
+ }
+ updated = true;
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getValue()
+ {
+ StringBuffer sb = new StringBuffer("");
+ if (type == ParameterType.String) {
+ sb.append(vS);
+ }
+ else if (type == ParameterType.StringArray) {
+ sb.append(sA[0]);
+ for (int i = 1; i < sA.length; i++) {
+ sb.append(' ');
+ sb.append(sA[i]);
+ }
+ }
+ else if (type == ParameterType.Integer) {
+ sb.append(vI);
+ }
+ else if (type == ParameterType.IntegerArray) {
+ sb.append(iA[0]);
+ for (int i = 1; i < iA.length; i++) {
+ sb.append('.');
+ sb.append(iA[i]);
+ }
+ }
+ else if (type == ParameterType.Char) {
+ sb.append(vC);
+ }
+ else if (type == ParameterType.Long) {
+ sb.append(vL);
+ }
+ else if (type == ParameterType.Date) {
+ sb.append(vL);
+ }
+ else if (type == ParameterType.Rfc822Date) {
+ sb.append(df.format(vD));
+ }
+ else if (type == ParameterType.AdvertiseMode) {
+ sb.append(aM);
+ }
+ else if (type == ParameterType.BalancerMethod) {
+ sb.append(bM);
+ }
+ else if (type == ParameterType.ProtocolType) {
+ sb.append(pT);
+ }
+ else if (type == ParameterType.Boolean) {
+ sb.append(bT);
+ }
+ else if (type == ParameterType.Resource) {
+ sb.append(vR.getResourceName());
+ }
+ else if (type == ParameterType.State) {
+ sb.append(sM.valueOf());
+ }
+ return sb.toString();
+ }
+
+ public String getString() { return vS; }
+ public String [] getStringArray() { return sA; }
+ public char getChar() { return vC; }
+ public int getInteger() { return vI; }
+ public int [] getIntegerArray() { return iA; }
+ public long getLong() { return vL; }
+ public Date getDate() { return vD; }
+ public AdvertiseMode getAdvertiseMode() { return aM; }
+ public BalancerMethod getBalancerMethod() { return bM; }
+ public BooleanType getBooleanType() { return bT; }
+ public ProtocolType getProtocolType() { return pT; }
+ public boolean getBoolean() { return bT.valueOf(); }
+ public StateMode getStateMode() { return sM; }
+ public Resource getResource() { return vR; }
+
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(name);
+ sb.append('=');
+ String v = getValue();
+ if ((v.indexOf(' ') >= 0) || (v.indexOf(';') >= 0)) {
+ sb.append('"');
+ sb.append(v);
+ sb.append('"');
+ }
+ else
+ sb.append(v);
+ return sb.toString();
+ }
+
+ public String toAttribute()
+ {
+ StringBuffer sb = new StringBuffer(name);
+ sb.append("=\"");
+ sb.append(getValue());
+ sb.append('"');
+ return sb.toString();
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Parameter.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ParameterType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ParameterType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ParameterType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * Resource parameter types
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum ParameterType
+{
+ String,
+ StringArray,
+ Integer,
+ IntegerArray,
+ Char,
+ Boolean,
+ State,
+ Long,
+ Date,
+ Rfc822Date,
+ BalancerMethod,
+ Resource,
+ ProtocolType,
+ AdvertiseMode;
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ParameterType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ParameterUpdateCallback.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ParameterUpdateCallback.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ParameterUpdateCallback.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,38 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * ParameterUpdate callback interface
+ *
+ * @author Mladen Turk
+ *
+ */
+public interface ParameterUpdateCallback
+{
+
+ public void onUpdateResource(Parameter p, Resource ov, Resource nv);
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ParameterUpdateCallback.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ProtocolType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ProtocolType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ProtocolType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * ProtocolType enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum ProtocolType
+{
+ Ajp,
+ Http,
+ Https;
+
+ public static ProtocolType valueOfIgnoreCase(String name)
+ {
+ for (ProtocolType e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ throw new IllegalArgumentException("Invalid initializer: " + name);
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ProtocolType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Resource.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Resource.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Resource.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,197 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.LinkedList;
+import org.jboss.aloha.util.*;
+
+/**
+ * Core Resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public abstract class Resource implements ParameterUpdateCallback
+{
+ private long id;
+ private ManagedServer managedServer;
+ private LinkedList<Parameter> parameterList = new LinkedList<Parameter>();
+
+ protected Parameter addParameter(String name, boolean readOnly, ParameterType type)
+ {
+ Parameter p = new Parameter(this, name, readOnly, type);
+ parameterList.add(p);
+ return p;
+ }
+
+ protected void addParameter(Parameter p)
+ {
+ parameterList.add(p);
+ }
+
+ /**
+ * Creates system Resource with designated Id
+ */
+ protected Resource(ManagedServer managedServer, long id)
+ {
+ this.id = id;
+ this.managedServer = managedServer;
+ }
+
+ protected Resource(ManagedServer managedServer)
+ {
+ this(managedServer, Utils.Id());
+ }
+
+ protected Resource()
+ {
+ this(null, Utils.Id());
+ }
+
+ public abstract ResourceType getResourceType();
+ public abstract String getResourceName();
+ public abstract Resource getResourceParent();
+
+ public ManagedServer getManagedServer() { return managedServer; }
+
+ public void onUpdateResource(Parameter p, Resource ov, Resource nv)
+ {
+ // Implemented in derived classes
+ }
+
+ /**
+ * Get the unique Id for this Resource generated at creation time
+ */
+ public long Id() { return id; }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer(getClass().getSimpleName());
+ sb.append(" ResourceType=\"");
+ sb.append(getResourceType());
+ sb.append('"');
+ sb.append(" ResourceId=\"");
+ sb.append(Utils.hex(id));
+ sb.append('"');
+ sb.append(" ResourceName=\"");
+ sb.append(getResourceName());
+ sb.append('"');
+ for (Parameter p : parameterList) {
+ sb.append(' ');
+ sb.append(p.toAttribute());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns True if any of the updateable parameters
+ * has been modified
+ */
+ public boolean isModified()
+ {
+ for (Parameter p : parameterList) {
+ if (!p.isReadOnly() &&
+ p.isModified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns True if any of the parameters
+ * has been updated
+ */
+ public boolean isUpdated()
+ {
+ for (Parameter p : parameterList) {
+ if (p.isUpdated()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Clear modification flags for all Parameters
+ * This method should be invoked after the WebServer
+ * has been updated
+ */
+ public void clearModifiedFlag()
+ {
+ for (Parameter p : parameterList) {
+ p.clearModifiedFlag();
+ }
+ }
+
+ /**
+ * Clear update flags for all Parameters
+ * This method should be invoked after the Resource
+ * is used
+ */
+ public void clearUpdatedFlag()
+ {
+ for (Parameter p : parameterList) {
+ p.clearUpdatedFlag();
+ }
+ }
+
+ public String getUpdateString()
+ {
+ StringBuffer sb = new StringBuffer(getResourceName());
+ for (Parameter p : parameterList) {
+ if (!p.isReadOnly() &&
+ p.isModified()) {
+ sb.append("; ");
+ sb.append(p);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Sets the name=value pair<br/>
+ * This method shuld be invoked from the Parser to update the
+ * parameters received from the mod_manager.
+ * @param name Parameter name
+ * @param value Parameter value. The parameter value will be converted
+ * from String to the corresponding native type.
+ */
+ public void putValue(String name, String value)
+ {
+ for (Parameter p : parameterList) {
+ if (p.equals(name)) {
+ p.putValue(value);
+ break;
+ }
+ }
+ }
+
+ public LinkedList<Parameter> getParameters()
+ {
+ return parameterList;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Resource.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ResourceType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ResourceType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ResourceType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * ResourceType enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum ResourceType
+{
+ Unknown,
+ Manager,
+ Server,
+ ApplicationPool,
+ Balancer,
+ Member,
+ Host,
+ Application;
+
+ public static ResourceType valueOfIgnoreCase(String name)
+ {
+ for (ResourceType e : values()) {
+ if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ return ResourceType.Unknown;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ResourceType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,269 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.Locale;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+
+import java.util.LinkedList;
+
+/**
+ * Parse the body of the response HTTP MCMP message.
+ * The message body is text/plain with ISO_8895_1 character set.
+ *
+ * @author Mladen Turk
+ *
+ */
+public class ResponseBodyParser
+{
+ private static int EIO = 5;
+ private static int EINVAL = 22;
+ private static String CRLF = "\r\n";
+
+ private int errorCode = 0;
+ private String errorDescription = "No error";
+ private LinkedList<String> bodyLines = new LinkedList<String>();
+ private ResponseType responseType = ResponseType.Unparsed;
+
+ private LinkedList<GenericResource> grL = new LinkedList<GenericResource>();
+
+
+ private void splitLines(String body)
+ {
+ if (body == null || body.length() < 1)
+ return;
+ String [] lines = body.split(CRLF);
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i].trim();
+ if (line.length() > 0) {
+ bodyLines.add(line);
+ }
+ }
+ }
+
+ public void clear()
+ {
+ errorCode = 0;
+ errorDescription = "No error";
+ responseType = ResponseType.Empty;
+ bodyLines.clear();
+ grL.clear();
+ }
+
+ public void parse(String body)
+ {
+ clear();
+ splitLines(body);
+ if (bodyLines.size() > 0) {
+ parseFirstLine();
+ if (responseType == ResponseType.Ok) {
+ for (int i = 1; i < bodyLines.size(); i ++) {
+ parseLine(bodyLines.get(i));
+ }
+ }
+ }
+ }
+
+ public ResponseBodyParser()
+ {
+ }
+
+ public ResponseBodyParser(String body)
+ {
+ parse(body);
+ }
+
+ public ResponseBodyParser(byte[] body)
+ {
+ try {
+ String bstr = new String(body, Default.CHARSET);
+ bodyLines = new LinkedList<String>();
+ parse(bstr);
+ } catch (UnsupportedEncodingException e) {
+ // Ignore
+ }
+ }
+
+ public ResponseType getResponseType() { return responseType; }
+ public int getErrorCode() { return errorCode; }
+ public String getErrorDescription() { return errorDescription; }
+
+ public int numLines()
+ {
+ return bodyLines.size();
+ }
+
+ private void parseFirstLine()
+ {
+ try {
+ String line = bodyLines.getFirst();
+ if (line.charAt(0) == '?') {
+ if (line.startsWith(Globals.ERROR, 1)) {
+ responseType = ResponseType.Error;
+ String ep = line.substring(Globals.ERROR.length() + 1).trim();
+ String [] ee = ep.split(";\\s*");
+ if (ee.length == 2) {
+ ee[1] = ee[1].trim();
+ try {
+ errorCode = Integer.parseInt(ee[0]);
+ errorDescription = ee[1];
+ if (errorDescription.length() == 0) {
+ errorDescription = "Unknown error " + ee[0];
+ }
+ } catch (NumberFormatException x) {
+ errorCode = EINVAL;
+ errorDescription = "Invalid errror code " + ee[0];
+ }
+ }
+ else {
+ errorCode = EINVAL;
+ if (ep.length() == 0) {
+ errorDescription = "Invalid error format";
+ }
+ else
+ errorDescription = "Unknown error " + ep;
+ }
+ }
+ else if (line.startsWith(Globals.MCMP, 1)) {
+ responseType = ResponseType.ProtocolError;
+ errorDescription = line.substring(Globals.MCMP.length() + 1).trim();
+ }
+ else if (line.startsWith(Globals.UNKNOWN_TYPE, 1)) {
+ responseType = ResponseType.UnknownType;
+ errorDescription = line.substring(Globals.UNKNOWN_TYPE.length() + 1).trim();
+ }
+ else if (line.startsWith(Globals.UNKNOWN_RESOURCE, 1)) {
+ responseType = ResponseType.UnknownResource;
+ errorDescription = line.substring(Globals.UNKNOWN_RESOURCE.length() + 1).trim();
+ }
+ else {
+ responseType = ResponseType.UnknownError;
+ errorCode = EINVAL;
+ errorDescription = line.substring(1).trim();
+ }
+ }
+ else if (line.equalsIgnoreCase("OK")) {
+ responseType = ResponseType.Ok;
+ }
+ else {
+ parseLine(line);
+ }
+ } catch (Exception e) {
+ errorCode = EIO;
+ responseType = ResponseType.UnknownError;
+ errorDescription = e.getMessage();
+ }
+ }
+
+ private void parseLine(String line)
+ {
+ if (line.charAt(0) == '?') {
+ // Ignore if not the first line
+ return;
+ }
+ else if (line.equalsIgnoreCase("OK")) {
+ // Ignore OK lines
+ return;
+ }
+ try {
+ responseType = ResponseType.Ok;
+ GenericResource gr = new GenericResource();
+ if (line.charAt(0) == '@') {
+ // First part is 'Resouce[/Name]: '
+ String [] ee = line.substring(1).split(":\\s+", 2);
+ int ps = ee[0].indexOf('/');
+ if (ps > 0) {
+ gr.setResourceType(ResourceType.valueOfIgnoreCase(ee[0].substring(0, ps)));
+ gr.setResourceName(ee[0].substring(ps + 1));
+ }
+ else {
+ gr.setResourceType(ResourceType.valueOfIgnoreCase(ee[0]));
+ gr.setResourceName(ee[0]);
+ }
+ if (ee.length == 2)
+ line = ee[1].trim();
+ else
+ line = null;
+ }
+ if (line != null) {
+ String [] el = line.split(";\\s+");
+ for (int i = 0; i < el.length; i++) {
+ if (el[i].length() == 0) {
+ // Skip empty lines
+ continue;
+ }
+ // ParameterName=[["]ParameterValue["]]
+ String [] pva = el[i].split("=", 2);
+ String pn = pva[0].trim();
+ String pv = null;
+ if (pva.length == 2) {
+ if (pva[1].length() > 1 && pva[1].charAt(0) == '"') {
+ pv = pva[1].substring(1, pva[1].length() - 1);
+ }
+ else
+ pv = pva[1];
+ }
+ if (bodyLines.size() == 1 && pv == null && el.length == 1)
+ gr.addParameter("?", pn);
+ else
+ gr.addParameter(pn, pv);
+ }
+ }
+ grL.add(gr);
+ } catch (Exception e) {
+ errorCode = EINVAL;
+ responseType = ResponseType.UnknownError;
+ errorDescription = e.getMessage();
+ }
+
+ }
+
+ public LinkedList<GenericResource> getResources()
+ {
+ return grL;
+ }
+
+ public boolean isOk()
+ {
+ return responseType == ResponseType.Ok ||
+ responseType == ResponseType.Empty;
+ }
+
+ public boolean isEmpty()
+ {
+ return responseType == ResponseType.Empty;
+ }
+
+ public boolean isError()
+ {
+ return errorCode != 0;
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ResponseBodyParser.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/ResponseType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/ResponseType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/ResponseType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * Response type enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum ResponseType
+{
+ Unparsed,
+ Empty,
+ Ok,
+ ProtocolError,
+ Error,
+ UnknownError,
+ UnknownType,
+ UnknownResource;
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/ResponseType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/Server.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/Server.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/Server.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Server resource object
+ *
+ * @author Mladen Turk
+ *
+ */
+public final class Server extends Resource
+{
+ public Parameter ServerName = addParameter("ServerName", true, ParameterType.String);
+ public Parameter ServerRoot = addParameter("ServerRoot", true, ParameterType.String);
+ public Parameter ServerVersion = addParameter("ServerVersion", true, ParameterType.String);
+ public Parameter ServerVersionNumber = addParameter("ServerVersionNumber", true, ParameterType.IntegerArray);
+ public Parameter ServerBuilt = addParameter("ServerBuilt", true, ParameterType.String);
+ public Parameter ServerArchitecture = addParameter("ServerArchitecture", true, ParameterType.String);
+ public Parameter ServerProcessing = addParameter("ServerProcessing", true, ParameterType.String);
+ public Parameter ServerPlatform = addParameter("ServerPlatform", true, ParameterType.String);
+ public Parameter ThreadsPerChild = addParameter("ThreadsPerChild", true, ParameterType.Integer);
+ public Parameter MaxRequestsPerChild = addParameter("MaxRequestsPerChild", true, ParameterType.Integer);
+ public Parameter MaxClients = addParameter("MaxClients", true, ParameterType.Integer);
+ public Parameter Listen = addParameter("Listen", true, ParameterType.StringArray);
+ public Parameter ListenBackLog = addParameter("ListenBackLog", true, ParameterType.Integer);
+ public Parameter CurrentTime = addParameter("CurrentTime", true, ParameterType.Date);
+ public Parameter RestartTime = addParameter("RestartTime", true, ParameterType.Date);
+ public Parameter ServerUpTime = addParameter("ServerUpTime", true, ParameterType.Long);
+ public Parameter AccessCount = addParameter("AccessCount", true, ParameterType.Long);
+ public Parameter BytesServed = addParameter("BytesServed", true, ParameterType.Long);
+ public Parameter Busy = addParameter("Busy", true, ParameterType.Integer);
+ public Parameter LimitRequestFields = addParameter("LimitRequestFields", true, ParameterType.Integer);
+ public Parameter LimitRequestFieldSize = addParameter("LimitRequestFieldSize", true, ParameterType.Integer);
+ public Parameter ConfigurationFile = addParameter("ConfigurationFile", true, ParameterType.String);
+
+ public ResourceType getResourceType() { return ResourceType.Server; }
+ public String getResourceName() { return resourceName; }
+ public Resource getResourceParent() { return null; }
+
+ private String resourceName = "Server";
+
+ private Server()
+ {
+ // Disable creation of unlinked resource
+ }
+
+ protected Server(ManagedServer managedServer)
+ {
+ super(managedServer, Default.SERVER_ID);
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/Server.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/StateMode.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/StateMode.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/StateMode.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+/**
+ * StateMode enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public enum StateMode
+{
+ Unknown( "-"),
+ Active( "A"),
+ Busy( "B"),
+ Disabled( "D"),
+ Idle( "I"),
+ Stopped( "S"),
+ Error( "E");
+
+ private String value;
+ private StateMode(String v)
+ {
+ value = v;
+ }
+
+ public String valueOf()
+ {
+ return value;
+ }
+
+ public static StateMode valueOfIgnoreCase(String name)
+ {
+ for (StateMode e : values()) {
+ if (e.value.equalsIgnoreCase(name))
+ return e;
+ else if (e.name().equalsIgnoreCase(name))
+ return e;
+ }
+ return StateMode.Unknown;
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/StateMode.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseEventType.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseEventType.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseEventType.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.advertise;
+
+/**
+ * Set what type of event the AdvertiseEvent signals.
+ * @param type The type of event. One of:
+ * <PRE>
+ * ON_NEW_SERVER -- New AdvertisedServer detected
+ * ON_STATUS_CHANGE -- AdvertisedServer server changed status
+ * </PRE>
+ */
+public enum AdvertiseEventType
+{
+ /** New AdvertisedServer detected */
+ ON_NEW_SERVER( 0),
+ /** AdvertisedServer server changed status */
+ ON_STATUS_CHANGE( 1);
+
+ private int value;
+ private AdvertiseEventType(int v)
+ {
+ value = v;
+ }
+
+ public int valueOf()
+ {
+ return value;
+ }
+
+ public static AdvertiseEventType valueOf(int value)
+ {
+ for (AdvertiseEventType e : values()) {
+ if (e.value == value)
+ return e;
+ }
+ throw new IllegalArgumentException("Invalid initializer: " + value);
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseEventType.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseListener.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseListener.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseListener.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,453 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.advertise;
+
+import java.io.IOException;
+
+import java.net.InetAddress;
+import java.net.SocketAddress;
+import java.net.DatagramPacket;
+import java.net.MulticastSocket;
+import java.net.NetworkInterface;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Locale;
+import java.util.HashMap;
+import java.util.Collection;
+
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.security.NoSuchAlgorithmException;
+
+
+/** AdvertiseListener
+ * Listens for Advertise messages from mod_cluster
+ *
+ * @author Mladen Turk
+ *
+ */
+public class AdvertiseListener
+{
+ /** Default port for listening Advertise messages.
+ */
+ public static int DEFAULT_PORT = 23364;
+ /** Default Multicast group address for listening Advertise messages.
+ */
+ public static String DEFAULT_GROUP = "224.0.1.105";
+
+ private static String RFC_822_FMT = "EEE, d MMM yyyy HH:mm:ss Z";
+ private int advertisePort = DEFAULT_PORT;
+ private String groupAddress = DEFAULT_GROUP;
+ private MulticastSocket ms;
+ private SimpleDateFormat df;
+ private boolean listening = true;
+ private boolean initialized = false;
+ private boolean running = false;
+ private boolean paused = false;
+ private boolean daemon = true;
+ private byte [] secure = new byte[16];
+ private String securityKey = null;
+ private MessageDigest md = null;
+
+ private HashMap<String, AdvertisedServer> servers;
+
+ private IAdvertiseEvent eventHandler;
+ private Thread workerThread;
+
+
+ private static void digestString(MessageDigest md, String s)
+ {
+ int len = s.length();
+ byte [] b = new byte[len];
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c < 127)
+ b[i] = (byte)c;
+ else
+ b[i] = '?';
+ }
+ md.update(b);
+ }
+
+ private AdvertiseListener()
+ {
+ // Do not allow creation
+ }
+
+ /** Create AdvertiseListener instance
+ * @param eventHandler The event handler that will be used for
+ * status and new server notifications.
+ */
+ public AdvertiseListener(IAdvertiseEvent eventHandler)
+ {
+ df = new SimpleDateFormat(RFC_822_FMT, Locale.US);
+ servers = new HashMap<String, AdvertisedServer>();
+ this.eventHandler = eventHandler;
+ }
+
+ /**
+ * The default is true - the control thread will be
+ * in daemon mode. If set to false, the control thread
+ * will not be daemon - and will keep the process alive.
+ */
+ public void setDaemon(boolean b)
+ {
+ daemon = b;
+ }
+
+ public boolean getDaemon()
+ {
+ return daemon;
+ }
+
+ /** Set Advertise security key
+ * @param key The key to use.<br/>
+ * Security key must match the AdvertiseKey
+ * on the advertised server.
+ */
+ public void setSecurityKey(String key)
+ throws NoSuchAlgorithmException
+ {
+ securityKey = key;
+ if (md == null)
+ md = MessageDigest.getInstance("MD5");
+ }
+
+ /** Set Advertise port
+ * @param port The UDP port to use.
+ */
+ public void setAdvertisePort(int port)
+ {
+ advertisePort = port;
+ }
+
+ public int getAdvertisePort()
+ {
+ return advertisePort;
+ }
+
+ /** Set Advertise Multicaset group address
+ * @param address The IP or host address to use.
+ */
+ public void setGroupAddress(String address)
+ {
+ groupAddress = address;
+ }
+
+ /** Get Advertise Multicaset group address
+ */
+ public String getGroupAddress()
+ {
+ return groupAddress;
+ }
+
+ /** Get Collection of all AdvertisedServer instances.
+ */
+ public Collection<AdvertisedServer> getServers()
+ {
+ return servers.values();
+ }
+
+ /** Get AdvertiseServer server.
+ * @param name Server name to get.
+ */
+ public AdvertisedServer getServer(String name)
+ {
+ return servers.get(name);
+ }
+
+ /** Remove the AdvertisedServer from the collection.
+ * @param server Server to remove.
+ */
+ public void removeServer(AdvertisedServer server)
+ {
+ servers.remove(server);
+ }
+
+ private void init()
+ throws IOException
+ {
+ ms = new MulticastSocket(advertisePort);
+ ms.setTimeToLive(16);
+ ms.joinGroup(InetAddress.getByName(groupAddress));
+ initialized = true;
+ }
+
+ private void interruptDatagramReader()
+ {
+ if (!initialized)
+ return;
+ try {
+ // Restrict to localhost.
+ ms.setTimeToLive(0);
+ DatagramPacket dp = new DatagramPacket(secure, secure.length,
+ InetAddress.getByName(groupAddress),
+ advertisePort);
+ ms.send(dp);
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+
+ /** Start the Listener, creating listener thread.
+ */
+ public void start()
+ throws IOException
+ {
+ if (!initialized) {
+ init();
+ }
+ if (!running) {
+ SecureRandom random = new SecureRandom();
+ random.nextBytes(secure);
+ secure[0] = 0;
+ running = true;
+ paused = false;
+ listening = true;
+ AdvertiseListenerWorker aw = new AdvertiseListenerWorker();
+ workerThread = new Thread(aw);
+ workerThread.setDaemon(daemon);
+ workerThread.start();
+ }
+ }
+
+ /**
+ * Pause the listener, which will make it stop accepting new advertise
+ * messages.
+ */
+ public void pause()
+ {
+ if (running && !paused) {
+ paused = true;
+ interruptDatagramReader();
+ }
+ }
+
+
+ /**
+ * Resume the listener, which will make it start accepting new advertise
+ * messages again.
+ */
+ public void resume()
+ {
+ if (running && paused) {
+ // Genererate new private secure
+ SecureRandom random = new SecureRandom();
+ random.nextBytes(secure);
+ secure[0] = 0;
+ paused = false;
+ }
+ }
+
+
+ /**
+ * Stop the endpoint. This will cause all processing threads to stop.
+ */
+ public void stop()
+ {
+ if (running) {
+ running = false;
+ interruptDatagramReader();
+ workerThread = null;
+ }
+ }
+
+
+ /**
+ * Deallocate listener and close sockets.
+ */
+ public void destroy()
+ throws Exception
+ {
+ if (running) {
+ stop();
+ }
+ if (initialized) {
+ ms.leaveGroup(InetAddress.getByName(groupAddress));
+ ms.close();
+ initialized = false;
+ ms = null;
+ }
+ }
+
+ private boolean verifyDigest(String digest, String server, String date)
+ {
+ if (md == null)
+ return true;
+ md.reset();
+ digestString(md, securityKey);
+ digestString(md, date);
+ digestString(md, server);
+ byte [] our = md.digest();
+ byte [] dst = new byte[digest.length() * 2];
+ for (int i = 0, j = 0; i < digest.length(); i++) {
+ char ch = digest.charAt(i);
+ dst[j++] = (byte)((ch >= 'A') ? ((ch & 0xdf) - 'A') + 10 : (ch - '0'));
+ }
+ return true;
+ }
+
+ /**
+ * True if listener is accepting the advetise messages.<br/>
+ * If false it means that listener is experiencing some
+ * network problems if running.
+ */
+ public boolean isListening()
+ {
+ return listening;
+ }
+
+
+ // ------------------------------------ AdvertiseListenerWorker Inner Class
+ private class AdvertiseListenerWorker implements Runnable
+ {
+
+ protected AdvertiseListenerWorker()
+ {
+ // Nothing
+ }
+ /**
+ * The background thread that listens for incoming Advertise packets
+ * and hands them off to an appropriate AdvertiseEvent handler.
+ */
+ public void run() {
+ byte[] buffer = new byte[512];
+ // Loop until we receive a shutdown command
+ while (running) {
+ // Loop if endpoint is paused
+ while (paused) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ try {
+ DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
+ ms.receive(dp);
+ if (!running)
+ break;
+ byte [] data = dp.getData();
+ boolean intr = false;
+ if (dp.getLength() == secure.length) {
+ int i;
+ for (i = 0; i < secure.length; i++) {
+ if (data[i] != secure[i])
+ break;
+ }
+ if (i == secure.length)
+ intr = true;
+ }
+ if (intr)
+ continue;
+ String s = new String(data, 0, dp.getLength(), "8859_1");
+ if (!s.startsWith("HTTP/1."))
+ continue;
+
+ String [] headers = s.split("\r\n");
+ String date_str = null;
+ Date date = null;
+ int status = 0;
+ String status_desc = null;
+ String digest = null;
+ String server_name = null;
+ AdvertisedServer server = null;
+ boolean added = false;
+ for (int i = 0; i < headers.length; i++) {
+ if (i == 0) {
+ String [] sline = headers[i].split(" ", 3);
+ if (sline == null || sline.length != 3)
+ break;
+ status = Integer.parseInt(sline[1]);
+ if (status < 100)
+ break;
+ status_desc = sline[2];
+ }
+ else {
+ String [] hdrv = headers[i].split(": ", 2);
+ if (hdrv == null || hdrv.length != 2)
+ break;
+ if (hdrv[0].equals("Date")) {
+ date_str = hdrv[1];
+ try {
+ date = df.parse(date_str);
+ } catch (ParseException e) {
+ date = new Date();
+ }
+ }
+ else if (hdrv[0].equals("Digest")) {
+ digest = hdrv[1];
+ }
+ else if (hdrv[0].equals("Server")) {
+ server_name = hdrv[1];
+ server = servers.get(server_name);
+ if (server == null) {
+ server = new AdvertisedServer(server_name);
+ added = true;
+ }
+ }
+ else if (server != null) {
+ server.setParameter(hdrv[0], hdrv[1]);
+ }
+ }
+ }
+ if (server != null && status > 0) {
+ if (md != null) {
+ /* We need a digest to match */
+ if (!verifyDigest(digest, server_name, date_str)) {
+ System.out.println("Digest mismatch");
+ continue;
+ }
+ }
+ server.setDate(date);
+ boolean rc = server.setStatus(status, status_desc);
+ if (added) {
+ servers.put(server_name, server);
+ // Call the new server callback
+ eventHandler.onEvent(AdvertiseEventType.ON_NEW_SERVER, server);
+ }
+ else if (rc) {
+ // Call the status change callback
+ eventHandler.onEvent(AdvertiseEventType.ON_STATUS_CHANGE, server);
+ }
+ }
+ listening = true;
+ } catch (IOException e) {
+ // Do not blow the CPU in case of communication error
+ listening = false;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException x) {
+ // Ignore
+ }
+ }
+ }
+ }
+ }
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertiseListener.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertisedServer.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/advertise/AdvertisedServer.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/advertise/AdvertisedServer.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.advertise;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Collection;
+
+/**
+ * Advertised server instance
+ *
+ * @author Mladen Turk
+ *
+ */
+public class AdvertisedServer
+{
+ private String server;
+ private Date date;
+ private int status;
+ private String status_desc;
+ private HashMap<String, String> headers;
+
+ /** Manager-Address header */
+ public static String MANAGER_ADDRESS = "X-Manager-Address";
+ /** Manager-Url header */
+ public static String MANAGER_URL = "X-Manager-Url";
+ /** Manager-Protocol header */
+ public static String MANAGER_PROTOCOL = "X-Manager-Protocol";
+ /** Manager-Version header */
+ public static String MANAGER_VERSION = "X-Manager-Version";
+ /** Manager-Host header */
+ public static String MANAGER_HOST = "X-Manager-Host";
+
+ private AdvertisedServer()
+ {
+ // Disable creation.
+ }
+
+ protected AdvertisedServer(String server)
+ {
+ this.server = server;
+ headers = new HashMap<String, String>();
+ }
+
+ protected boolean setStatus(int status, String desc)
+ {
+ boolean rv = false;
+ status_desc = desc;
+ if (this.status == 0 ) {
+ // First time
+ this.status = status;
+ }
+ else if (this.status != status) {
+ this.status = status;
+ rv = true;
+ }
+ return rv;
+ }
+
+ /** Set the Date of the last Advertise message
+ */
+ protected void setDate(Date date)
+ {
+ this.date = date;
+ }
+
+ /** Set the Header
+ */
+ protected void setParameter(String name, String value)
+ {
+ headers.put(name, value);
+ }
+
+ /** Get Date of the last Advertise message
+ */
+ public Date getDate()
+ {
+ return date;
+ }
+
+ /** Get Status code of the last Advertise message
+ */
+ public int getStatusCode()
+ {
+ return status;
+ }
+
+ /** Get Status description of the last Advertise message
+ */
+ public String getStatusDescription()
+ {
+ return status_desc;
+ }
+
+ /** Get Advertise parameter
+ */
+ public String getParameter(String name)
+ {
+ return headers.get(name);
+ }
+
+ public String toString()
+ {
+ return server;
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/advertise/AdvertisedServer.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/advertise/IAdvertiseEvent.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/advertise/IAdvertiseEvent.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/advertise/IAdvertiseEvent.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.advertise;
+
+/**
+ * Advertise Event interface
+ *
+ * @author Mladen Turk
+ *
+ */
+public interface IAdvertiseEvent
+{
+
+ /** Callback for AdvertiseServer.
+ * @param type AdvertiseEventType caused by this event.
+ * @param server AdvertisedServer causing this event.
+ */
+ public void onEvent(AdvertiseEventType type, AdvertisedServer server);
+
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/advertise/IAdvertiseEvent.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/util/Base64.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/util/Base64.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/util/Base64.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,98 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.util;
+
+import java.io.UnsupportedEncodingException;
+import org.jboss.aloha.*;
+
+/**
+ * Base64 encoding enumeration
+ *
+ * @author Mladen Turk
+ *
+ */
+public class Base64
+{
+
+ private Base64()
+ {
+ // Disable creation
+ }
+
+ private static final char[] basis64 = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+ };
+
+ /**
+ * Encode byte array using Base64 encoding
+ */
+ public static String encode(byte [] data, int offset, int len)
+ {
+ int i;
+ StringBuffer sb = new StringBuffer();
+ for (i = 0; i < len - 2; i += 3) {
+ sb.append(basis64[(data[offset + i] >> 2) & 0x3F]);
+ sb.append(basis64[((data[offset + i] & 0x3) << 4) |
+ ((int)(data[offset + i + 1] & 0xF0) >> 4)]);
+ sb.append(basis64[((data[offset + i + 1] & 0xF) << 2) |
+ ((int)(data[offset + i + 2] & 0xC0) >> 6)]);
+ sb.append(basis64[data[offset + 2] & 0x3F]);
+
+ }
+ if (i < len) {
+ sb.append(basis64[(data[offset + i] >> 2) & 0x3F]);
+ if (i == (len - 1)) {
+ sb.append(basis64[((data[offset + i] & 0x3) << 4)]);
+ sb.append('=');
+ }
+ else {
+ sb.append(basis64[((data[offset + i] & 0x3) << 4) |
+ ((int) (data[offset + i + 1] & 0xF0) >> 4)]);
+ sb.append(basis64[((data[offset + i + 1] & 0xF) << 2)]);
+ }
+ sb.append('=');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Encode String using Base64 encoding
+ */
+ public static String encode(String string)
+ {
+ try {
+ byte [] data = string.getBytes(Default.CHARSET);
+ return encode(data, 0, data.length);
+ } catch (UnsupportedEncodingException e) {
+ return "";
+ }
+ }
+}
Property changes on: sandbox/aloha/java/org/jboss/aloha/util/Base64.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/org/jboss/aloha/util/Utils.java
===================================================================
--- sandbox/aloha/java/org/jboss/aloha/util/Utils.java (rev 0)
+++ sandbox/aloha/java/org/jboss/aloha/util/Utils.java 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha.util;
+
+import java.io.PrintStream;
+import java.util.Random;
+
+/**
+ * General purpose utilities.
+ *
+ * @author Mladen Turk
+ */
+public final class Utils
+{
+
+ private Utils()
+ {
+ // Private to prevent creation.
+ }
+
+ private static long counter = 1024L;
+ private static long timer = System.currentTimeMillis();
+ private static Random rnd = new Random(timer);
+
+ /**
+ * Returns the unique 64 bit id.
+ * Values lower then 1024 are reseved for system ID's.
+ */
+ public static long Id()
+ {
+ long id;
+ synchronized (Utils.class) {
+ id = counter++;
+ }
+ return id;
+ }
+
+ public static void generateRandom(byte[] dst)
+ {
+ rnd.nextBytes(dst);
+ }
+
+ public static String hex(byte val)
+ {
+ String h = Integer.toHexString(val);
+ if (h.length() == 1)
+ h = "0" + h;
+ return h;
+ }
+
+ public static String hex(short val)
+ {
+ String h = Integer.toHexString(val);
+ return ("0000" + h).substring(h.length());
+ }
+
+ public static String hex(int val)
+ {
+ String h = Integer.toHexString(val);
+ return ("00000000" + h).substring(h.length());
+ }
+
+ public static String hex(long val)
+ {
+ String h = Long.toHexString(val);
+ return ("0000000000000000" + h).substring(h.length());
+ }
+
+ public static String dumpBuffer(byte[] data, int offset, int len)
+ {
+ int i;
+ int p = offset;
+
+ if (offset >= data.length)
+ return null;
+ StringBuffer sb = new StringBuffer();
+ sb.append(hex((short)offset));
+ sb.append(": ");
+ for (i = 0; i < 16; i++) {
+ if (i < data.length) {
+ sb.append(hex(data[offset+i]));
+ if (i == 7)
+ sb.append("|");
+ else
+ sb.append(" ");
+ }
+ else {
+ sb.append(" ");
+ }
+ }
+ sb.append(" | ");
+ for (i = offset; i < offset + 16; i++) {
+ if (i < data.length) {
+ if (!Character.isISOControl((char)data[i]))
+ sb.append(new Character((char)data[i]));
+ else
+ sb.append(".");
+ }
+ }
+ return sb.toString();
+ }
+
+ public static void dumpBuffer(byte[] data, int offset, int len, PrintStream out)
+ {
+ out.println(dumpBuffer(data, offset, len));
+ }
+
+}
+
Property changes on: sandbox/aloha/java/org/jboss/aloha/util/Utils.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/java/overview.html
===================================================================
--- sandbox/aloha/java/overview.html (rev 0)
+++ sandbox/aloha/java/overview.html 2008-05-28 15:47:01 UTC (rev 1630)
@@ -0,0 +1,35 @@
+<!--
+ ALOHA
+
+ Copyright(c) 2008 Red Hat Middleware, LLC,
+ and individual contributors as indicated by the @authors tag.
+ See the copyright.txt in the distribution for a
+ full listing of individual contributors.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library in the file COPYING.LIB;
+ if not, write to the Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+-->
+<html>
+<head>
+<title>Overview Documentation for Aloha</title>
+</head>
+<body bgcolor="white">
+ <p>
+ The <em>Aloha</em> component.
+ </p>
+
+</body>
+</html>
Property changes on: sandbox/aloha/java/overview.html
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months
JBoss Native SVN: r1629 - in sandbox/aloha: examples and 3 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:43:55 -0400 (Wed, 28 May 2008)
New Revision: 1629
Added:
sandbox/aloha/examples/
sandbox/aloha/examples/org/
sandbox/aloha/examples/org/jboss/
sandbox/aloha/examples/org/jboss/aloha/
sandbox/aloha/examples/org/jboss/aloha/AdvertiseExample.java
Log:
Add some example code
Added: sandbox/aloha/examples/org/jboss/aloha/AdvertiseExample.java
===================================================================
--- sandbox/aloha/examples/org/jboss/aloha/AdvertiseExample.java (rev 0)
+++ sandbox/aloha/examples/org/jboss/aloha/AdvertiseExample.java 2008-05-28 15:43:55 UTC (rev 1629)
@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import org.jboss.aloha.advertise.*;
+
+public class AdvertiseExample
+{
+
+ public class AdvertiseEventHandler implements IAdvertiseEvent
+ {
+
+ public AdvertiseEventHandler()
+ {
+ // Nothing
+ }
+ public void onEvent(AdvertiseEventType type, AdvertisedServer server)
+ {
+ if (type == AdvertiseEventType.ON_NEW_SERVER) {
+ System.out.println("\rNew Server detected: " + server);
+ System.out.print("Enter command> ");
+ }
+ else {
+ if (server.getStatusCode() == 410) {
+ System.out.println("\rServer: " + server + " shudown!");
+ System.out.print("Enter command> ");
+ }
+ else {
+ System.out.println("\rServer: " + server + " status: " + server.getStatusCode());
+ System.out.print("Enter command> ");
+ }
+ }
+ }
+
+ }
+
+ public AdvertiseListener listener;
+ public AdvertiseExample()
+ {
+ AdvertiseEventHandler eh = new AdvertiseEventHandler();
+ listener = new AdvertiseListener(eh);
+ }
+
+ public static void main(String [] args) {
+ try {
+ int ch;
+ AdvertiseExample ex = new AdvertiseExample();
+ ex.listener.setGroupAddress("234.5.6.7");
+ ex.listener.setSecurityKey("foo");
+
+ ex.listener.start();
+ byte [] ib = new byte[1024];
+ while (true) {
+ System.out.print("Enter command> ");
+ int len = System.in.read(ib);
+ if (len < 0)
+ break;
+ if (ib[len - 1] == '\n')
+ len--;
+ if (ib[len - 1] == '\r')
+ len--;
+ String cmd = new String(ib, 0, len);
+ if (cmd.charAt(0) == 'q' || cmd.charAt(0) == 'Q') {
+ ex.listener.destroy();
+ break;
+ }
+ else if (cmd.equalsIgnoreCase("stop")) {
+ ex.listener.stop();
+ }
+ else if (cmd.equalsIgnoreCase("destroy")) {
+ ex.listener.destroy();
+ }
+ else if (cmd.equalsIgnoreCase("start")) {
+ ex.listener.start();
+ }
+ else if (cmd.equalsIgnoreCase("pause")) {
+ ex.listener.pause();
+ }
+ else if (cmd.equalsIgnoreCase("resume")) {
+ ex.listener.resume();
+ }
+ else if (cmd.equalsIgnoreCase("list")) {
+ System.out.println("Adverised servers:");
+ for (AdvertisedServer s : ex.listener.getServers()) {
+ System.out.println(s + "@" +
+ s.getParameter(AdvertisedServer.MANAGER_HOST) +
+ " status: " + s.getStatusCode() + " " +
+ s.getStatusDescription());
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+}
Property changes on: sandbox/aloha/examples/org/jboss/aloha/AdvertiseExample.java
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months
JBoss Native SVN: r1628 - in sandbox/aloha: test and 3 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:42:16 -0400 (Wed, 28 May 2008)
New Revision: 1628
Added:
sandbox/aloha/test/
sandbox/aloha/test/org/
sandbox/aloha/test/org/jboss/
sandbox/aloha/test/org/jboss/aloha/
sandbox/aloha/test/org/jboss/aloha/TestAll.java
sandbox/aloha/test/org/jboss/aloha/TestParameter.java
sandbox/aloha/test/org/jboss/aloha/TestResponseBodyParser.java
Log:
Add basic test code
Added: sandbox/aloha/test/org/jboss/aloha/TestAll.java
===================================================================
--- sandbox/aloha/test/org/jboss/aloha/TestAll.java (rev 0)
+++ sandbox/aloha/test/org/jboss/aloha/TestAll.java 2008-05-28 15:42:16 UTC (rev 1628)
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import junit.framework.*;
+
+/**
+ */
+public class TestAll extends TestCase
+{
+
+ public TestAll(String testName)
+ {
+ super(testName);
+ }
+
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite();
+ // Fundamentals
+ suite.addTest(TestParameter.suite());
+ suite.addTest(TestResponseBodyParser.suite());
+ return suite;
+ }
+
+ public static void main(String args[])
+ {
+ String[] testCaseName = { TestAll.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+}
Property changes on: sandbox/aloha/test/org/jboss/aloha/TestAll.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/test/org/jboss/aloha/TestParameter.java
===================================================================
--- sandbox/aloha/test/org/jboss/aloha/TestParameter.java (rev 0)
+++ sandbox/aloha/test/org/jboss/aloha/TestParameter.java 2008-05-28 15:42:16 UTC (rev 1628)
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import java.util.Date;
+import junit.framework.*;
+
+/**
+ * Parameter Test.
+ *
+ */
+public class TestParameter extends TestCase
+{
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(TestParameter.class);
+ return suite;
+ }
+
+ public void testInit()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", null);
+ assertEquals("Value ", "", p.getValue());
+ }
+
+ public void testString()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", false, ParameterType.String);
+ assertEquals("Value ", "", p.getValue());
+ assertEquals("String ", "Foo=", p.toString());
+ p.setValue("1 2");
+ assertEquals("Value ", "1 2", p.getValue());
+ assertEquals("String ", "Foo=\"1 2\"", p.toString());
+ }
+
+ public void testStringArray()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", false, ParameterType.StringArray);
+ assertEquals("Value ", "", p.getStringArray()[0]);
+ assertEquals("String ", "Foo=", p.toString());
+ p.setValue("1 2:3");
+ assertEquals("Value ", "1 2:3", p.getValue());
+ assertEquals("String ", "Foo=\"1 2:3\"", p.toString());
+ assertEquals("Value[1] ", "2:3", p.getStringArray()[1]);
+ }
+
+ public void testInteger()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", false, ParameterType.Integer);
+ assertEquals("Value ", 0, p.getInteger());
+ assertEquals("String ", "Foo=0", p.toString());
+ p.setValue("1 2");
+ assertEquals("Value ", "0", p.getValue());
+ p.setValue(-1);
+ assertEquals("String ", "Foo=-1", p.toString());
+ }
+
+ public void testBoolean()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", false, ParameterType.Boolean);
+ assertFalse(p.getBoolean());
+ assertEquals("String ", "Foo=False", p.toString());
+ p.putValue("oN");
+ assertEquals("Type ", BooleanType.On, p.getBooleanType());
+ assertTrue(p.getBoolean());
+ p.putValue("y");
+ assertEquals("String ", "Foo=Y", p.toString());
+ assertTrue(p.getBoolean());
+ p.setValue(BooleanType.No);
+ assertEquals("Type ", BooleanType.No, p.getBooleanType());
+ assertFalse(p.getBoolean());
+ }
+
+ public void testReadOnly()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", true, ParameterType.Boolean);
+ p.putValue("off");
+ assertEquals("Type", BooleanType.Off, p.getBooleanType());
+ assertFalse(p.getBoolean());
+ try {
+ p.setValue(BooleanType.Yes);
+ assertTrue(p.getBoolean());
+ p.setValue(BooleanType.No);
+ assertEquals("Reached ", "should not", "did");
+ } catch (IllegalAccessException e) {
+ assertTrue(p.getBoolean());
+ }
+ }
+
+ public void testDate()
+ throws Exception
+ {
+ Parameter p;
+ p = new Parameter("Foo", false, ParameterType.Date);
+ p.setValue(1000L);
+ assertEquals("Date", new Date(1000L), p.getDate());
+ p = new Parameter("Foo", false, ParameterType.Rfc822Date);
+ p.setValue(1000L);
+ assertEquals("Date", new Date(1000L), p.getDate());
+ p.putValue("Thu, 1 Jan 1970 00:00:02 GMT");
+ assertEquals("Date", new Date(2000L), p.getDate());
+ assertEquals("Date", 2000L, p.getLong());
+ }
+
+
+}
Property changes on: sandbox/aloha/test/org/jboss/aloha/TestParameter.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/test/org/jboss/aloha/TestResponseBodyParser.java
===================================================================
--- sandbox/aloha/test/org/jboss/aloha/TestResponseBodyParser.java (rev 0)
+++ sandbox/aloha/test/org/jboss/aloha/TestResponseBodyParser.java 2008-05-28 15:42:16 UTC (rev 1628)
@@ -0,0 +1,160 @@
+/*
+ *
+ * Copyright(c) 2008 Red Hat Middleware, LLC,
+ * and individual contributors as indicated by the @authors tag.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file COPYING.LIB;
+ * if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+package org.jboss.aloha;
+
+import junit.framework.*;
+
+/**
+ * ResponseBodyParser Test.
+ *
+ */
+public class TestResponseBodyParser extends TestCase
+{
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite(TestResponseBodyParser.class);
+ return suite;
+ }
+
+ public void testEmptyLine()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("");
+ assertEquals("ResponseType", ResponseType.Empty, p.getResponseType());
+ p = new ResponseBodyParser("\r\n");
+ assertEquals("ResponseType", ResponseType.Empty, p.getResponseType());
+ assertTrue(p.isOk());
+ }
+
+ public void testErrorLine()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("?");
+ assertTrue(p.isError());
+ p = new ResponseBodyParser("?Error");
+ assertTrue(p.isError());
+ p = new ResponseBodyParser("?Error:");
+ assertTrue(p.isError());
+ p = new ResponseBodyParser("?Error: 1");
+ assertEquals("Error code", 22, p.getErrorCode());
+ p = new ResponseBodyParser("?Error: 1;");
+ assertEquals("Error code", 22, p.getErrorCode());
+ p = new ResponseBodyParser("?Error: ; Description");
+ assertEquals("Error code", 22, p.getErrorCode());
+ p = new ResponseBodyParser("?Error: 1; Description");
+ assertEquals("Error code", 1, p.getErrorCode());
+ }
+
+ public void testProtocolError()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("?MCMP/1.0");
+ assertTrue(p.getResponseType() == ResponseType.ProtocolError);
+ assertEquals("Error description", "1.0", p.getErrorDescription());
+ }
+
+ public void testUnknownTypeError()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("?Unknown-Type:");
+ assertTrue(p.getResponseType() == ResponseType.UnknownType);
+ p = new ResponseBodyParser("?Unknown-Type: Foo");
+ assertEquals("Unknown-Type", "Foo", p.getErrorDescription());
+ }
+
+ public void testUnknownResourceError()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("?Unknown-Resource:");
+ assertTrue(p.getResponseType() == ResponseType.UnknownResource);
+ p = new ResponseBodyParser("?Unknown-Resource: Foo");
+ assertEquals("Unknown-Resource", "Foo", p.getErrorDescription());
+ }
+
+ public void testOk()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("OK");
+ assertTrue(p.isOk());
+ }
+
+ public void testLines()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("\r\nOK");
+ assertTrue(p.isOk());
+ }
+
+ public void testParam()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("A");
+ assertTrue(p.isOk());
+ Parameter v;
+ v = p.getResources().get(0).getParameters().get(0);
+ assertEquals("Parameter name", "?", v.getName());
+ assertEquals("Parameter value", "A", v.getValue());
+ p = new ResponseBodyParser("A=B");
+ assertTrue(p.isOk());
+ v = p.getResources().get(0).getParameters().get(0);
+ assertEquals("Parameter name", "A", v.getName());
+ assertEquals("Parameter value", "B", v.getValue());
+ p = new ResponseBodyParser("A=B; ; ; C=\"D:B\"");
+ assertTrue(p.isOk());
+ v = p.getResources().get(0).getParameters().get(1);
+ assertEquals("Parameter name", "C", v.getName());
+ assertEquals("Parameter value", "D:B", v.getValue());
+ }
+
+ public void testResource()
+ throws Exception
+ {
+ ResponseBodyParser p;
+ p = new ResponseBodyParser("OK\r\n?Error\r\n@Member: Foo=Bar");
+ assertTrue(p.isOk());
+ GenericResource r;
+ Parameter v;
+ r = p.getResources().get(0);
+ assertEquals("Resource Type", ResourceType.Member, r.getResourceType());
+ v = r.getParameters().get(0);
+ assertEquals("Parameter name", "Foo", v.getName());
+ assertEquals("Parameter value", "Bar", v.getValue());
+ p = new ResponseBodyParser("@Host/_default_");
+ assertTrue(p.isOk());
+ r = p.getResources().get(0);
+ assertEquals("Resource Type", ResourceType.Host, r.getResourceType());
+ assertEquals("Resource Name", "_default_", r.getResourceName());
+
+ }
+
+}
Property changes on: sandbox/aloha/test/org/jboss/aloha/TestResponseBodyParser.java
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months
JBoss Native SVN: r1627 - in sandbox/aloha: lib and 1 other directory.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:40:11 -0400 (Wed, 28 May 2008)
New Revision: 1627
Added:
sandbox/aloha/lib/
sandbox/aloha/lib/LICENSE.txt
sandbox/aloha/lib/commons-codec-1.3.jar
sandbox/aloha/lib/commons-httpclient-3.1.jar
sandbox/aloha/lib/commons-logging-1.1.1.jar
sandbox/aloha/lib/junit-4.3.1.jar
Log:
Add dependency libraries
Added: sandbox/aloha/lib/LICENSE.txt
===================================================================
--- sandbox/aloha/lib/LICENSE.txt (rev 0)
+++ sandbox/aloha/lib/LICENSE.txt 2008-05-28 15:40:11 UTC (rev 1627)
@@ -0,0 +1,176 @@
+ 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
Property changes on: sandbox/aloha/lib/LICENSE.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/lib/commons-codec-1.3.jar
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/lib/commons-codec-1.3.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/lib/commons-httpclient-3.1.jar
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/lib/commons-httpclient-3.1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/lib/commons-logging-1.1.1.jar
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/lib/commons-logging-1.1.1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/lib/junit-4.3.1.jar
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/lib/junit-4.3.1.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
16 years, 7 months
JBoss Native SVN: r1626 - in sandbox: aloha and 3 other directories.
by jbossnative-commits@lists.jboss.org
Author: mladen.turk(a)jboss.com
Date: 2008-05-28 11:37:46 -0400 (Wed, 28 May 2008)
New Revision: 1626
Added:
sandbox/aloha/
sandbox/aloha/docs/
sandbox/aloha/docs/ActiveTransaction.vsd
sandbox/aloha/docs/BasicDataModel.vsd
sandbox/aloha/docs/CommErr.png
sandbox/aloha/docs/CommErr.vsd
sandbox/aloha/docs/ConfigAppDataFlow.vsd
sandbox/aloha/docs/ConfigBalancerDataFlow.vsd
sandbox/aloha/docs/ConfigHostDataFlow.vsd
sandbox/aloha/docs/ConfigMemberDataFlow.vsd
sandbox/aloha/docs/ConnErrorDataFlow.vsd
sandbox/aloha/docs/ConnPoolDataFlow.vsd
sandbox/aloha/docs/EmptyConfig.png
sandbox/aloha/docs/EmptyConfig.vsd
sandbox/aloha/docs/GeneralTopology.png
sandbox/aloha/docs/GeneralTopology.vsd
sandbox/aloha/docs/InitConfig.png
sandbox/aloha/docs/InitConfig.vsd
sandbox/aloha/docs/ManyToMany.png
sandbox/aloha/docs/ManyToMany.vsd
sandbox/aloha/docs/NewApplication.png
sandbox/aloha/docs/NewApplication.vsd
sandbox/aloha/docs/NodeDown.png
sandbox/aloha/docs/NodeDown.vsd
sandbox/aloha/docs/NodeNew.png
sandbox/aloha/docs/NodeNew.vsd
sandbox/aloha/docs/NodeRemove.png
sandbox/aloha/docs/NodeRemove.vsd
sandbox/aloha/docs/OneToMany.png
sandbox/aloha/docs/OneToMany.vsd
sandbox/aloha/docs/OneToOne.png
sandbox/aloha/docs/OneToOne.vsd
sandbox/aloha/docs/StartupHostDataFlow.vsd
sandbox/aloha/docs/UPingErrorDataFlow.vsd
sandbox/aloha/docs/UpdateConfig.png
sandbox/aloha/docs/UpdateConfig.vsd
sandbox/aloha/docs/globaltopo.dia
sandbox/aloha/docs/globaltopo.png
sandbox/aloha/docs/html/
sandbox/aloha/docs/html/images/
sandbox/aloha/docs/html/images/add.gif
sandbox/aloha/docs/html/images/bdbm.png
sandbox/aloha/docs/html/images/code.gif
sandbox/aloha/docs/html/images/commnew.png
sandbox/aloha/docs/html/images/commshutdown.png
sandbox/aloha/docs/html/images/commstop.png
sandbox/aloha/docs/html/images/configappdf.png
sandbox/aloha/docs/html/images/configbalancerdf.png
sandbox/aloha/docs/html/images/configdeploy.png
sandbox/aloha/docs/html/images/confighostdf.png
sandbox/aloha/docs/html/images/configinit.png
sandbox/aloha/docs/html/images/configmemberdf.png
sandbox/aloha/docs/html/images/configupdate.png
sandbox/aloha/docs/html/images/configzero.png
sandbox/aloha/docs/html/images/connconcepts.png
sandbox/aloha/docs/html/images/connerr.png
sandbox/aloha/docs/html/images/connerrordf.png
sandbox/aloha/docs/html/images/connpooldf.png
sandbox/aloha/docs/html/images/design.gif
sandbox/aloha/docs/html/images/docs.gif
sandbox/aloha/docs/html/images/fix.gif
sandbox/aloha/docs/html/images/genarch.png
sandbox/aloha/docs/html/images/jboss_logo.gif
sandbox/aloha/docs/html/images/jbossweblogo.gif
sandbox/aloha/docs/html/images/m2m.png
sandbox/aloha/docs/html/images/mcmpclass.png
sandbox/aloha/docs/html/images/mcmpclasssm.png
sandbox/aloha/docs/html/images/o2m.png
sandbox/aloha/docs/html/images/o2o.png
sandbox/aloha/docs/html/images/starthostdf.png
sandbox/aloha/docs/html/images/update.gif
sandbox/aloha/docs/html/images/upingdf.png
sandbox/aloha/docs/html/images/void.gif
sandbox/aloha/docs/html/index.html
sandbox/aloha/docs/html/modcluster.html
sandbox/aloha/docs/html/style.css
sandbox/aloha/docs/mcmp-class.dia
sandbox/aloha/docs/mcmp-class.png
sandbox/aloha/docs/rfc5501.txt
Log:
Add Aloha docs
Added: sandbox/aloha/docs/ActiveTransaction.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ActiveTransaction.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/BasicDataModel.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/BasicDataModel.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/CommErr.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/CommErr.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/CommErr.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/CommErr.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConfigAppDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConfigAppDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConfigBalancerDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConfigBalancerDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConfigHostDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConfigHostDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConfigMemberDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConfigMemberDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConnErrorDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConnErrorDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ConnPoolDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ConnPoolDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/EmptyConfig.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/EmptyConfig.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/EmptyConfig.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/EmptyConfig.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/GeneralTopology.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/GeneralTopology.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/GeneralTopology.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/GeneralTopology.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/InitConfig.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/InitConfig.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/InitConfig.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/InitConfig.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/ManyToMany.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ManyToMany.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/ManyToMany.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/ManyToMany.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/NewApplication.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NewApplication.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/NewApplication.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NewApplication.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/NodeDown.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeDown.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/NodeDown.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeDown.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/NodeNew.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeNew.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/NodeNew.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeNew.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/NodeRemove.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeRemove.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/NodeRemove.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/NodeRemove.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/OneToMany.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/OneToMany.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/OneToMany.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/OneToMany.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/OneToOne.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/OneToOne.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/OneToOne.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/OneToOne.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/StartupHostDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/StartupHostDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/UPingErrorDataFlow.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/UPingErrorDataFlow.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/UpdateConfig.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/UpdateConfig.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/UpdateConfig.vsd
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/UpdateConfig.vsd
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/globaltopo.dia
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/globaltopo.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/globaltopo.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/globaltopo.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/add.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/add.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/bdbm.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/bdbm.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/code.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/code.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/commnew.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/commnew.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/commshutdown.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/commshutdown.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/commstop.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/commstop.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configappdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configappdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configbalancerdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configbalancerdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configdeploy.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configdeploy.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/confighostdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/confighostdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configinit.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configinit.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configmemberdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configmemberdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configupdate.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configupdate.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/configzero.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/configzero.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/connconcepts.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/connconcepts.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/connerr.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/connerr.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/connerrordf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/connerrordf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/connpooldf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/connpooldf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/design.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/design.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/docs.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/docs.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/fix.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/fix.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/genarch.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/genarch.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/jboss_logo.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/jboss_logo.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/jbossweblogo.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/jbossweblogo.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/m2m.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/m2m.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/mcmpclass.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/mcmpclass.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/mcmpclasssm.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/mcmpclasssm.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/o2m.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/o2m.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/o2o.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/o2o.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/starthostdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/starthostdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/update.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/update.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/images/upingdf.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/upingdf.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/html/images/void.gif
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/html/images/void.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/html/index.html
===================================================================
--- sandbox/aloha/docs/html/index.html (rev 0)
+++ sandbox/aloha/docs/html/index.html 2008-05-28 15:37:46 UTC (rev 1626)
@@ -0,0 +1,11 @@
+<html>
+<head>
+ <title>JBoss™ ModCluster</title>
+ <link type="text/css" rel="stylesheet" href="./style.css"/>
+ <meta value="Mladen Turk" name="author"/>
+ <meta value="mturk(a)redhat.com" name="email"/>
+</head>
+<body>
+ This page intentionally left blank.
+</body>
+</html>
\ No newline at end of file
Property changes on: sandbox/aloha/docs/html/index.html
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/docs/html/modcluster.html
===================================================================
--- sandbox/aloha/docs/html/modcluster.html (rev 0)
+++ sandbox/aloha/docs/html/modcluster.html 2008-05-28 15:37:46 UTC (rev 1626)
@@ -0,0 +1,858 @@
+<html>
+<head>
+ <title>JBoss™ ModCluster</title>
+ <link type="text/css" rel="stylesheet" href="./style.css"/>
+ <meta value="Mladen Turk" name="author"/>
+ <meta value="mturk(a)redhat.com" name="email"/>
+</head>
+<body>
+ <img src="./images/jboss_logo.gif">
+ <br/><br/><br/>
+ <h2>1. ModCluster - Technology overview</h2>
+
+ <p>ModCluster is next generation clustering solution for connecting native
+ web servers and application servers.
+ The major advantage of ModCluster is dynamic configuration that is done
+ by ModClusterService and propagated to all web servers.
+ </p>
+ <p>ModClusterService is dedicated application embedded inside Application Server
+ or an stand-alone application. It's main duty is to configure and manage front-end
+ web server(s) and to track various objects in application server(s).
+ </p>
+ <img src="./images/o2m.png">
+ <p class="image"><strong>Figure 1.</strong> Typical configuration with Web server in front of
+ multiple application servers.
+ </p>
+ <br/>
+ <p>ModClusterService connects to the ModCluster using HTTP or HTTPS protocol
+ and both configures and monitors Apache Httpd Web server.
+ </p>
+ <p>ModClusterService is capable of managing multiple Web servers in front.
+ Any number of web servers and be defined. Their status are checked at regular
+ intervals and ModClusterService can act accordingly
+ </p>
+ <img src="./images/m2m.png">
+ <p class="image"><strong>Figure 2.</strong> Multiple Web servers in front of
+ multiple application servers.
+ </p>
+ <br/><br/>
+ <h2>1.2. Graceful node shutdown</h2>
+ <p>When an Application Server Stop event is received from one of the Nodes
+ that are member of the cluster, or direct command to Stop the server is
+ made by Administrator the ModClusterService informs all Web Servers he is
+ aware being operable to Stop serving new requests.
+ </p>
+ <img src="./images/commstop.png">
+ <p class="image"><strong>Figure 3.</strong> Node Stop event handling.
+ </p>
+ <p>Existing requests that have session affinity information present will
+ still continue to be served by that particular node. This allows to
+ gracefully shutdown particular node for maintenance.
+ </p>
+ <br/><br/>
+ <h2>1.3. Node disable</h2>
+ <p>Unlike graceful shutdown, Disable immediately shutdowns the connections from
+ web servers to that particular node.
+ </p>
+ <img src="./images/commshutdown.png">
+ <p class="image"><strong>Figure 4.</strong> Node Disable event handling.
+ </p>
+ <p>This operation is usually issued after graceful shutdown and after
+ all active sessions timed out, or it can be used as a way of putting Nodes
+ down in case there is session replication in place among application servers,
+ meaning that users will not loose their sessions.
+ </p>
+ <br/><br/>
+ <h2>1.4. Communication errors</h2>
+ <p>If there is communication error between particular web server and one of the
+ Application servers the ModClusterService will be informed about that on next
+ regular status interval query.
+ </p>
+ <img src="./images/connerr.png">
+ <p class="image"><strong>Figure 5.</strong> Communication error handling.
+ </p>
+ <p>Reasons for communication errors can be caused by many reasons.
+ The ModCluster service will figure out the reason, and if the reason
+ is unrecoverable it will inform all other Web servers that one of the
+ nodes is down. Multiple handling scenarios can then be employed from
+ setting up the fail-over node, to informing the administrator via e-mail
+ </p>
+ <br/><br/>
+ <h2>1.5. Node discovery</h2>
+ <p>ModeClusterServices uses JBossClustering to discover new nodes that
+ have joined the cluster. In case of such event the front-end Web servers
+ are informed about that and node configuration is added.
+ </p>
+ <img src="./images/commnew.png">
+ <p class="image"><strong>Figure 6.</strong> Node discovery handling.
+ </p>
+ <br/><br/>
+ <br/><br/>
+ <h2>2. ModCluster - Basic design</h2>
+ <p>ModCluster basic design is shown on the following picture
+ </p>
+ <img src="./images/genarch.png">
+ <p class="image"><strong>Figure 7.</strong> Basic Architecture.
+ </p>
+ <p>Shared memory is used to dynamically configure the Apache Httpd so it can
+ use zero-configuration presumption of ModCluster.
+ The core engine for ModClusterProxy is <strong>mod_proxy</strong>, and
+ supported Apache Httpd versions are <strong>2.2.3</strong> and up.
+ </p>
+ <br/><br/>
+ <h2>2.1. Startup</h2>
+ <p>Upon startup ModCluster service uses configuration and connects to the
+ Apache Httpd Web server that has loaded ModCluster native module.
+ </p>
+ <img src="./images/configzero.png">
+ <p class="image"><strong>Figure 8.</strong> ModCluster startup.
+ </p>
+ <p>Apache Httpd server on startup has empty configuration, so any
+ user request will produce 404 until ModClusterService configures the
+ ModCluster.
+ </p>
+ <br/><br/>
+ <h2>2.2. Initial Configuration</h2>
+ <p>ModClusterService discovers the members of the cluster and all
+ additional information like defined Hosts and deployed Applications.
+ </p>
+ <img src="./images/configinit.png">
+ <p class="image"><strong>Figure 9.</strong> ModCluster initialization.
+ </p>
+ <p>ModClusterService has the full view of the cluster that
+ is managed, so it can decide what configuration will be send
+ to the Web server. It can use some sort of GUI or any other
+ type of configuration for that purpose.
+ </p>
+ <br/><br/>
+ <h2>2.3. Undeploying applications</h2>
+ <p>When the undeploy event is received from the particular
+ Node that information is send to the Web server.
+ </p>
+ <img src="./images/configupdate.png">
+ <p class="image"><strong>Figure 10.</strong> Undeploy/Stop Application.
+ </p>
+ <p>ModCluster can handle undeploy events in various ways depending
+ on the instructions received from ModClusterService.
+ If the Undeploy will be followed by Deploy (Redeploy event)
+ it may queue the requests until the application is deployed
+ again.
+ </p>
+ <br/><br/>
+ <h2>2.4. Deploying new applications</h2>
+ <p>When the deploy event is received from the particular
+ Node that information is send to the Web server.
+ </p>
+ <img src="./images/configdeploy.png">
+ <p class="image"><strong>Figure 11.</strong> Deploying New applications.
+ </p>
+ <p>When new application is deployed to the cluster that information
+ is send to all web servers and is ready to be used.
+ ModClusterManager adds that information to the shared memory,
+ and ModClusterProxy can use that info to route the requests
+ to the newly deployed application.
+ </p>
+ <br/><br/>
+ <br/><br/>
+ <h2>3. ModCluster Management Protocol -- MCMP/1.0</h2>
+ <p>ModCluster uses HTTP/1.1 protocol for the management of clustering
+ properties, creation and management of cluster nodes, application
+ name space manipulation, and load balancing.
+ Complete description of the protocol can be found in the RFC-like form
+ at <a href="http://jira.jboss.com/jira/secure/attachment/12319781/rfc5501.txt">JBoss Jira</a>.
+ </p>
+ <p>ModClusterManager parses HTTP requests at the predefined location.
+ By default, the listening location is <code>/modclustermanager</code>.
+ However the administrator can for increased security use different
+ naming and protect this url inside Apache Httpd <code>Location</code> directive:
+ </p>
+ <pre>
+ <Location /manager>
+ SetHandler ModClusterManagerHandler
+ Order Deny,Allow
+ Allow from 192.168.0
+ </Location>
+ </pre>
+ <p>For even more enhanced security certain operations can be limited, allowing
+ multiple MCMP capable clients to gather data and only certain to manage
+ the ModCluster.
+ </p>
+ <pre>
+ <Location /manager/info>
+ SetHandler ModClusterManagerHandler
+ Order Deny,Allow
+ Allow from All
+ </Location>
+ </pre>
+ <pre>
+ <Location /manager/config>
+ SetHandler ModClusterManagerHandler
+ Order Deny,Allow
+ Allow from 192.168.0
+ </Location>
+ </pre>
+ </p>
+ <p>Major protocol presumption is the single header value named
+ <code>Server-Resource</code> that <b>must</b> be present for each
+ management request.
+ <br/>
+ The format of the <code>Server-Resource</code> header variable
+ corresponds to the HTTP State Management Mechanism <code>rfc2109</code>,
+ or commonly known as Cookie specification.
+ </p>
+ <p>This allows to go beyond request query size limitations and also there
+ is no need for additional query parameter encoding that would have to
+ be used for query like processing.
+ </p>
+ <p>Each management request produces reply with <code>text/plain</code>
+ mime type, and manager uses the body of the reply as an response
+ to the management request
+ </p>
+ <br/><br/>
+ <h2>3.1. Protocol commands</h2>
+ <p>Each management request must define operation or command that ModCluster must
+ accomplish. If the operation is successful the ModCluster responds with
+ <code>OK</code> and sends any additional data for that command.
+ </p>
+ <p>Commands that MCMP protocol supports are:
+ <ul>
+ <li><strong>INFO</strong>
+ command causes the manager to gather the information about
+ the specific resource on the server.
+ </li>
+ <br/>
+ <li><strong>ENABLE</strong>
+ command causes the manager to enable the specific resource
+ on the server.
+ </li>
+ <br/>
+ <li><strong>DISABLE</strong>
+ command causes the manager to disable the specific resource
+ on the server.
+ Depending on the resource object type the DISABLE command has different
+ consequences. For Node object it will disable further acceptance of
+ the request that does not carry the session affinity mark information,
+ while preserving the ones that carry
+ the session affinity mark.
+ </li>
+ <br/>
+ <li><strong>STOP</strong>
+ command causes the manager to stop the specific resource
+ on the server.
+ </li>
+ <br/>
+ <li><strong>DELETE</strong>
+ command causes the manager to completely remove the specific
+ resource on the server.
+ </li>
+ <li><strong>CONFIG</strong>
+ command causes the manager to create or update the specific
+ resource on the server.
+ </li>
+ </ul>
+ </p>
+ <p>Commands are case insensitive and can be send to the manager in various ways:
+ <ul>
+ <li>As query argument<br/>
+ <pre>
+ GET /modclustermanager?info HTTP/1.1
+ Host: localhost
+ Server-Resource: Host/foo
+ </pre>
+ </li>
+ <li>As <code>Server-Command</code> header<br/>
+ <pre>
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: info
+ Server-Resource: Host/foo
+ </pre>
+ </li>
+ </ul>
+ </li>
+ <li>As <code>Command</code> section inside <code>Server-Resource</code><br/>
+ <pre>
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Resource: Command=info; Host/foo
+ </pre>
+ </li>
+ <li>As last part or Url path<br/>
+ <pre>
+ GET /modclustermanager/info HTTP/1.1
+ Server-Resource: Host/foo
+ </pre>
+ </li>
+ </ul>
+ </p>
+ <br/><br/>
+ <h2>3.2. Info command</h2>
+ <p>Info command is used to gather the info about the web server resources.
+ Each resource carries his own set of attributes that are contained in
+ the response message one line at a time
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager?info HTTP/1.1
+ Host: localhost
+ Server-Resource: Server
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 193
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ ServerName localhost@localdomain
+ ServerRoot /usr/local/http
+ ServerVersion Apache/2.2.8 (Unix)
+ ServerBuilt Jan 18 2008 00:37:19
+ ServerArchitecture 32-bit
+ ThreadsPerChild 64
+ MaxRequestsPerChild 0
+ </pre>
+ <p>If the single resource attribute is requested then the only
+ the single line with attribute value is replied
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager?info HTTP/1.1
+ Host: localhost
+ Server-Resource: Server; ThreadsPerChild
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 2
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ 64
+ </pre>
+ <br/><br/>
+ <h2>3.3. Enable command</h2>
+ <p>Enable command is used to enable specific resource.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Enable
+ Server-Resource: Member/foo
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK
+ </pre>
+ <p>If the enable is attempted for non existing resource then
+ the error message is replied
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Enable
+ Server-Resource: Member/foo
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 27
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ ?Unknown-Type: Member/foo
+ </pre>
+ <br/><br/>
+ <h2>3.4. Disable command</h2>
+ <p>Disable command has the same format as Enable command.
+ The only difference is that disable command disables the
+ resource making it unavailable for any new processing.
+ </p>
+ <br/><br/>
+ <h2>3.5. Stop command</h2>
+ <p>Stop command has the same format as Enable command.
+ The only difference is that stop command disables the
+ resource for any all processing.
+ </p>
+ <p>If the Enable, Disable or Stop commands are attempted on
+ the resource object that doesn't support that operation
+ the error message is returned
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Stop
+ Server-Resource: Server
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 36
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ ?Error: 1; Operation not permitted
+ </pre>
+ <br/><br/>
+ <h2>3.6. Delete command</h2>
+ <p>Delete command deletes the resource from the shared memory.
+ However some resources can be delete only if they have been
+ previously stopped by Stop command.
+ In case the object like Application was not stopped previously
+ the error message is returned
+ </p>
+ <pre>
+ ?Error: 16; Device or resource busy
+ </pre>
+ <br/><br/>
+ <h2>3.6. Config command</h2>
+ <p>Config command updates or creates a new resource if it's not
+ already created.
+ </p>
+ <p>The resource is activated after the command is executed if all
+ needed attributes are present.
+ For example if Config creates a new Member it is not activated
+ until all the required parameters are set.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Member/node1
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK|Id
+ </pre>
+ <p>If this was a new Member object added it will not be activated
+ until protocol and communication parameters are set. The returned
+ value in that case will not be <code>OK</code> but rather the
+ internal database record number or <code>Id</code> or the new Member.
+ ModClusterService can then use that Id for referencing the Member
+ insted using its name.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Member/node1; Type=ajp, Activation=A
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK
+ </pre>
+ <p>The latest directive will activate the node1 because all required
+ parameter are set. By default the Address parameter for Node is
+ <code>localhost</code> and port default to <code>8009</code> because of
+ ajp type.
+ </p>
+ <br/><br/>
+ <br/><br/>
+ <h2>4. Objects</h2>
+ <p>Diagram on the Figure 12. shows all objects that are managed
+ inside ModCluster
+ </p>
+ <a href="./images/mcmpclass.png">
+ <img src="./images/mcmpclasssm.png" border="0" alt="Click for the full image">
+ </a>
+ <p class="image"><strong>Figure 12.</strong> ModCluster UML diagram.
+ </p>
+ <br/><br/>
+ <h2>4.1. Database model</h2>
+ <p>Diagram on the Figure 13. shows basic database model for few core objects
+ </p>
+ <img src="./images/bdbm.png">
+ <p class="image"><strong>Figure 13.</strong> Object database model.
+ </p>
+ <p>Database is stored in shared memory so that it is directly accessible by all
+ child processes in Web server. Each table is stored in separate shared memory
+ and each record is of fixed size. This makes memory usage not fully optimized,
+ but allows very fast record access.
+ </p>
+ <p>Each table <code>Id</code> field is not actually stored in the table, but rather
+ it represents the record number in the table. Referencing tables contain that
+ record number as foreign record key. The tables are not indexed, however some
+ tables are backed up by in-memory hash table for faster access.
+ Before each request, inside request post processing phase, ModCluster module
+ checks the atomic time stamps of each table, and if they do not match the
+ internal hash table index is recreated. This allows both optimal key based
+ access and does not require full blown backed database.
+ </p>
+ <p>Internal Hash tables are created on demand, and the cause for their creation is
+ the size of the table and length of the key value. Those options are compile time
+ defined, and in general the table is not indexed unless its size gets really big
+ (thousands of records). In most use cases those numbers won't be that large, and
+ simple sequential scan is used instead.
+ </p>
+ <br/><br/>
+ <h2>4.2. Host table initialization</h2>
+ <p>Diagram on the Figure 14. shows the data flow diagram of Host tables that is
+ executed on Web server startup.
+ </p>
+ <img src="./images/starthostdf.png">
+ <p class="image"><strong>Figure 14.</strong> Web server startup.
+ </p>
+ <p>When the Web server is started or fully restarted it contains empty configuration
+ as shown on the Figure 9. However Host and Server tables are created on the startup
+ containing objects that are defined inside native Web server configuration.
+ </p>
+ <p>Host table is loaded with all virtual host definitions by default.
+ However the administrator of the web server can use specific directives
+ in case the Web server is used for large ISP providers with thousands of
+ Virtual Host definitions.
+ The only reason for using those directives is for limiting the memory
+ usage if there will be no need to map requests from each Virtual Host to the
+ Application server cluster. Two configuration directives exist for this
+ reason <code>ModClusterHostCopy</code> and <code>ModClusterEnable</code>
+ The first directive if set to <code>Off</code> will not create any Host
+ object except default Host, and the second if defined inside Virtual Host
+ and set to <code>On</code>will create Host record for that virtual host.
+ </p>
+ <br/><br/>
+ <h2>4.3. Host configuration</h2>
+ <p>Diagram on the Figure 15. shows the data flow diagram of Host tables when
+ the <strong>Config</strong> command is executed.
+ </p>
+ <img src="./images/confighostdf.png">
+ <p class="image"><strong>Figure 15.</strong> Host object configuration.
+ </p>
+ <p>Host configuration operates on two main levels, Host itself and Alias.
+ Host object contains actual data and is stored directly in HostList table.
+ Both Host and Alias are stored in Host table, with later having table
+ self reference key to the Host.
+ This allows to have a single table for both Host and Aliases, but since
+ Aliases are dependent on the Host, any operation on the Host will propagate
+ to all its aliases. HostList table is helper table because Host and its
+ Aliases always point to the same data. Their only difference is in the
+ name, so this table is used to lower down the overall memory usage.
+ </p>
+ <p>Host Config like any other config directive can operate on wildchar
+ principle, meaning that it will be executed for all Host objects matching
+ the given expression. Expression evaluator is modified <code>fnmatch</code>
+ Posix function, available from the Apache APR library.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Host/www.*.com; KeepAlive=Off
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK
+ </pre>
+ <p>The upper example will disable <code>KeepAlive</code> in Web Server
+ for all virtual host requests matching <code>www.*.com</code>. The Command
+ will actually set the <code>KeepAlive</code> attribute to <code>Off</code>
+ for each Host table entry. Since the operation is performed on Host table
+ and KeepAlive attribute is held in HostList table this attribute will be
+ applied for both Host and all of his Aliases. Likewise if one of the Aliases
+ matches the <code>www.*.com</code> pattern it will cause the attribute change
+ in both parent Host and all other Aliases for that Host.
+ </p>
+ <br/><br/>
+ <h2>4.4. Application configuration</h2>
+ <p>Diagram on the Figure 16. shows the data flow diagram of Application table when
+ the <strong>Config</strong> command is executed.
+ </p>
+ <img src="./images/configappdf.png">
+ <p class="image"><strong>Figure 16.</strong> Application object configuration.
+ </p>
+ <p>Applications are contained inside Host object and cannot live outside the
+ Host as stand-alone entity. If the Host was not provided with the Config
+ command default Host is selected. Default host <code>_default_</code> is
+ the Web servers default host that matches the Server object ServerName attribute.
+ </p>
+ <p>Application name uniquely identifies application within Host and it defaults
+ to <code>Url</code> field. However the application can be referenced by name
+ attribute as convenient method for accessing application object. Application
+ command SubType is always url unless enclosed inside underscore characters
+ <code>'_'</code> in which case SubType is assumed to be application name not its url.
+ There is no need to add the leading slash for the Application Url because it is assumed.
+ </p>
+ <p>When new Host object is created default Application with empty Url is created
+ for that Host as well, but it is initially disabled. This Application object
+ corresponds to Application server Default Context. This Application has
+ empty Url that corresponds to Application server Context object with
+ <code>path=""</code>. Its name is internally set to <code>_default_</code>,
+ and can be later referenced as <code>Application/_default_</code>.
+ If later used as part of Application Config command the ModCluster will not need
+ to create that object again, so this is basically performance optimization.
+ </p>
+ <p>Operations on the Application object can be performed using wildchar causing
+ execution on all applications matching the expression. However attributes for
+ such operation must not be application object unique.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Host/www.*.com; Application/*/production; State=S
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK
+ </pre>
+ <p>The upper example set State of all Applications to <code>S (Stopped)</code>
+ which Url matches <code>/*/production</code> and which are contained
+ in Hosts which ServerName matches <code>www.*.com</code>.
+ </p>
+ <p>Returned value for newly created applications is its numeric record <code>Id</code>
+ and can be later used when referencing object if the SubType is enclosed
+ inside braces. The Id of each object within its type is guaranteed to be
+ unique, so this allows to have multiple objects sharing the same name
+ while still being uniquely identified inside ModCluster.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Application/(1234); State=S
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK
+ </pre>
+ <br/><br/>
+ <h2>4.5. Member configuration</h2>
+ <p>Diagram on the Figure 17. shows the data flow diagram of Member table when
+ the <strong>Config</strong> command is executed.
+ </p>
+ <img src="./images/configmemberdf.png">
+ <p class="image"><strong>Figure 17.</strong> Member object configuration.
+ </p>
+ <p>Member object corresponds to the physical Application server instance.
+ Actually it corresponds to the <code>Connector</code> element in Application
+ Server configuration and represents the physical connection to the
+ Application server. The reason for such design comes from old mod_jk and
+ mod_proxy limitations using Ajp connections. They have tendency for high
+ connection count, so this enable to create fail-over to the same physical
+ Application Server instance but on other usually Http connector.
+ </p>
+ <p>Like on any other Resource object the operations on the Member object can
+ be done using wildchar causing to execute the Config on all Members matching
+ the given expression. Of course this is like for Application or Host object limited
+ only to the non unique attributes
+ </p>
+ <p>Member can be assigned to Balancer object, and if not explicitly specified
+ when added it will be added to the default Balancer object that is created
+ on startup. Member can be referenced by multiple Balancer objects allowing
+ different balancer algorithms on application name space basis.
+ </p>
+ <br/><br/>
+ <h2>4.6. Balancer configuration</h2>
+ <p>Diagram on the Figure 18. shows the data flow diagram of Balancer table when
+ the <strong>Config</strong> command is executed.
+ </p>
+ <img src="./images/configbalancerdf.png">
+ </a>
+ <p class="image"><strong>Figure 18.</strong> Balancer object configuration.
+ </p>
+ <p>Balancer object is responsible for routing requests to one of its Member
+ objects. On system startup a single default Balancer object is created
+ and it is used for all Members unless explicitly specified during Member
+ configuration. Members can be referenced by multiple balancers but not
+ by default and some other balancers. If the member is referenced from
+ non default Balancer it will be removed from the default Balancer object.
+ </p>
+ <p>Balancer can contain reference to Application objects and Host objects.
+ Host object is special kind of relationship resulting in referencing
+ all Application objects contained inside Host object. This allows that
+ new Applications deployed inside specific Host get automatically referenced
+ by the specified Balancer object.
+ </p>
+ <pre>
+ ModClusterService -> ModClusterManager
+
+ GET /modclustermanager HTTP/1.1
+ Host: localhost
+ Server-Command: Config
+ Server-Resource: Balancer/productionCluster; Host/production.*; Member/node[1-7];
+
+
+ ModClusterManager -> ModClusterService
+
+ HTTP/1.1 200 OK
+ Server: Apache/2.2.8 (Unix)
+ Content-Length: 4
+ Keep-Alive: timeout=5, max=100
+ Connection: Keep-Alive
+ Content-Type: text/plain
+
+ OK|Id
+ </pre>
+ <p>The upper example will create (if it wasn't alread, returning Id of the newly created)
+ Balancer object and add reference to it for all Applications that are
+ contained in each Host which name matches the <code>production.*</code>
+ expression, and add reference to Member objects which name matches
+ the <code>node[1-7]</code> expression. As can be seen that simple Config
+ command can result in large number of internal objects created and referenced.
+ Deploying new applications to any <code>production.*</code> Host will automatically
+ reference that Application to this Balancer object.
+ </p>
+ <br/><br/>
+ <h2>4.7. Connection Pool configuration</h2>
+ <p>Diagram on the Figure 19. shows the data flow diagram of Connection Pool
+ the <strong>Config</strong> command for Member is executed.
+ </p>
+ <img src="./images/connpooldf.png">
+ <p class="image"><strong>Figure 19.</strong> Connection Pool management.
+ </p>
+ <p>For each Member if not specifically configured during
+ creation ModCluster creates a pool of empty connections with maximum size
+ equal to Web server's maximum limit. For threaded servers this value
+ equals to <code>MaxThreadsPerChild</code> configuration directive in Apache
+ Httpd. This pool is created for each child process the Web server
+ creates for serving requests. Updating this value and dynamically changing
+ it from already set or default value is done both by Configure
+ Member command and by maintenance thread or on first request, which ever
+ comes first. If the value is lower then already defined, all extra
+ connections that doesn't currently serve requests are closed. If then
+ extra connections are currently serving requests, they are closed when
+ those request are finished.
+ </p>
+ <br/><br/>
+ <br/><br/>
+ <h2>5. Communication Error Handling</h2>
+ <p>Diagram on the Figure 20. shows how ModProxy deducts connection errors.
+ </p>
+ <img src="./images/connerrordf.png">
+ <p class="image"><strong>Figure 20.</strong> Connection Error algorithm.
+ </p>
+ <p>ModCluster uses <code>Ping/Pong</code> feature of the <code>Ajp</code>
+ protocol or modified <code>OPTIONS</code> request for <code>Http</code>
+ protocol to verify the physical connection state before sending actual request
+ to the Member itself. This allows to fail over to another cluster Member
+ if the member has connection errors.
+ However various actions can be done when such error occurs, from
+ simply failing over to another node, to reconnect attempts, or any
+ combination of them.
+ </p>
+ <p>For Http(s) protocol needs to be developed special <code>OPTIONS</code>
+ filter that will allow <code>HTTP/1.1 with KeepAlive</code>.
+ <em>Default Tomcat implementation doesn't allow KeepAlive for OPTIONS request
+ so this either needs to get revised or create a new Filter for
+ ModCluster usage</em>.
+ </p>
+ <p>ModCluster will mark the Member as in Error state only when there is no
+ active connections present. In other case it will cause the same
+ behavior as for Connection Poll busyness. The reason for such behavior is
+ probability that Application Server cannot accept any new connections
+ since there is already some number of requests currently executing.
+ </p>
+ <br/><br/>
+ <h2>5.1. Unattended Connection Monitoring</h2>
+ <p>Diagram on the Figure 21. shows how ModProxy monitors the connections
+ for availability.
+ </p>
+ <img src="./images/upingdf.png">
+ <p class="image"><strong>Figure 21.</strong> Connection state monitoring.
+ </p>
+ <p>Maintenance thread that is created inside each Web server child process
+ on regular time interval checks the health of all connections in the
+ Connection poll. He does that only for connections that are not
+ active (currently serving requests) and which were inactive for a
+ certain amount of time. This solves two major problems found in mod_jk
+ and current mod_proxy. Firewall shutting down inactive connections and
+ burst load delays.
+ </p>
+ <p>In case the Member was in error state ModCluster will try to reconnect
+ to the Application server creating new connection if needed. This is
+ major difference compared with mod_jk and mod_proxy and is called
+ <b>Active Recovery</b>.
+ <br/>
+ <br/>
+ <img src="./images/connconcepts.png">
+ <p class="image"><strong>Figure 22.</strong> Connection states.
+ <p>Connection between ModCluster and Application server has two major states
+ <code>Active Request</code> and <code>Active Transaction</code>.
+ During Active Request state management thread cannot access the Connection
+ and it is presumed as active. Active Transaction can contain multiple
+ Request cycles. The KeepAliveTimeout depends on two things, if not set
+ directly for a Connector it inherits the KeepAliveTimeout of the Web server,
+ corresponding to the client timeout. If set it usually corresponds to the
+ connectionTimeout of the Application server's Connector. ModCluster can
+ close the connection if there were no Active Requests inside this time
+ interval. There is no need to check the connections since we are sure it
+ was already closed by the Application server.
+ </p>
+</body>
+</html>
\ No newline at end of file
Property changes on: sandbox/aloha/docs/html/modcluster.html
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/docs/html/style.css
===================================================================
--- sandbox/aloha/docs/html/style.css (rev 0)
+++ sandbox/aloha/docs/html/style.css 2008-05-28 15:37:46 UTC (rev 1626)
@@ -0,0 +1,220 @@
+html {
+ font-size: 11px;
+}
+
+body {
+ background-color: #ffffff;
+ padding: 0 1em 0 0;
+ font-family: Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+h1 {
+ padding: 0.2em;
+ margin: 0;
+ background-color: inherit;
+ text-decoration: none;
+ font-size: 1.6em;
+ font-weight: bold;
+}
+
+h2 {
+ padding: 0.2em 0 0.2em 0.7em;
+ margin: 0 ;
+ text-decoration: none;
+ font-size: 1.4em;
+ font-weight: bold;
+}
+
+h2 a,
+h2 a:hover,
+h2 a:active {
+ color: inherit;
+ background-color: inherit;
+ text-decoration: none;
+}
+
+h3 {
+ background-color: inherit;
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 1.2em;
+ padding: 0;
+ margin: 0 ;
+}
+
+h4 {
+ background-color: inherit;
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 1.1em;
+ padding: 0;
+ margin: 0 ;
+}
+
+/* margin adjustment */
+h3 + *, h4 + * {
+ margin-top: 0;
+}
+
+strong {
+ font-weight: bold;
+}
+
+q, em, var {
+ font-style: italic;
+}
+
+p.image {
+ font-size: 0.8em;
+ font-style: italic;
+}
+
+/* fixup IE & Opera
+ * otherwise they forget to inherit
+ * the computed font-size value
+ */
+table, code {
+ font-size: 1em;
+}
+
+a:link,
+a:visited,
+a:active {
+ color: #0073c7;
+ background-color: inherit;
+}
+
+a:link:hover,
+a:visited:hover {
+ color: #0073c7;
+ background-color: inherit;
+}
+
+div.screen {
+ background-color: #000000;
+ font-size: 1em;
+ color: #ffffff;
+ margin: 1em 2em 1em 1em;
+}
+
+div.example {
+ background-color: #e5ecf3;
+ color: #000000;
+ padding: 0.5em;
+ margin: 1em 2em 1em 1em;
+}
+
+div.warn {
+ color: #ed2e38;
+}
+
+pre, code {
+ font-family: Andale Mono, Courier New, Courier, monospace;
+ font-weight: normal;
+ font-style: normal;
+ font-size: 1em;
+}
+em.screen {
+ font-weight: normal;
+ font-style: normal;
+ font-size: 1em;
+ color: #c0c0c0;
+}
+p.screen {
+ background-color: #000000;
+ border-style: none;
+ color: #c0c0c0;
+ margin-left: 0.5em;
+ margin-right: 0px;
+ text-align: left;
+ font-size: 1em;
+}
+b.screen {
+ font-weight: normal;
+ font-style: normal;
+ color: #c0c0c0;
+ font-size: 1em;
+}
+
+b.note {
+ font-weight: normal;
+ font-style: italic;
+ color: #c0c0c0;
+ font-size: 1em;
+}
+
+code.screen {
+ font-family: Andale Mono, Courier New, Courier, monospace;
+ background-color: #000000;
+ border-style: none;
+ color: #c0c0c0;
+ margin-left: 0.5em;
+ margin-right: 0px;
+ text-align: left;
+}
+b.code {
+ font-family: Andale Mono, Courier New, Courier, monospace;
+ font-weight: normal;
+ font-style: normal;
+ font-size: 1em;
+ color: #023264;
+}
+p.todo {
+ background-color: #ffffff;
+ border-style: none;
+ color: #ed2e38;
+ text-align: justify;
+ font-size: 1em;
+}
+
+td.section {
+ background-color: #023264;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 1.2em;
+ padding-left: 0.5em;
+}
+
+td.subsection {
+ background-color: #557697;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 1em;
+ padding-left: 0.5em;
+}
+
+th.directive {
+ background-color: #e5ecf3;
+ color: #405871;
+ font-weight: bold;
+ font-size: 1em;
+}
+
+th.attribute {
+ background-color: #e5ecf3;
+ color: #405871;
+ font-weight: bold;
+ font-size: 1em;
+}
+
+table.screen {
+ background-color: #000000;
+ border: 1px solid;
+}
+
+td.screen {
+ padding-left: 0.5em;
+ background-color: #000000;
+ text-align: left;
+}
+
+td.figure {
+ background-color: #ffffff;
+ color: #000000;
+ font-family: Andale Mono, Courier New, Courier, monospace;
+ font-weight: normal;
+ font-style: italic;
+ font-size: 0.8em;
+ text-align: justify;
+}
Property changes on: sandbox/aloha/docs/html/style.css
___________________________________________________________________
Name: svn:eol-style
+ native
Added: sandbox/aloha/docs/mcmp-class.dia
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/mcmp-class.dia
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/aloha/docs/mcmp-class.png
===================================================================
(Binary files differ)
Property changes on: sandbox/aloha/docs/mcmp-class.png
___________________________________________________________________
Name: svn:mime-type
+ image/png
Added: sandbox/aloha/docs/rfc5501.txt
===================================================================
--- sandbox/aloha/docs/rfc5501.txt (rev 0)
+++ sandbox/aloha/docs/rfc5501.txt 2008-05-28 15:37:46 UTC (rev 1626)
@@ -0,0 +1,1854 @@
+
+
+
+
+
+Network Working Group M. Turk
+Request for Comments: 5501 J. Clere
+Category: Standards Track B. Stansberry
+ B. Ban
+ Red Hat Middleware, LLC
+ March 2008
+
+
+ HTTP Extensions for Mod Cluster Management Protocol -- MCMP/1.0
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardisation state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) Red Hat Middleware, LLC. or its licensors, as applicable.
+ All Rights Reserved.
+
+Abstract
+
+ This document specifies a set of methods, headers, and content-types
+ ancillary to HTTP/1.1 for the management of clustering properties,
+ creation and management of cluster nodes, application namespace
+ manipulation, and load balancing.
+
+Table of Contents
+
+ 1 Introduction ............................................2
+ 1.1 Purpose ..............................................2
+ 1.2 Requirements .........................................2
+ 1.3 Terminology ..........................................3
+ 1.4 Overall Operation ....................................5
+ 2 Notational Conventions and Generic Grammar ..............6
+ 3 Protocol Parameters .....................................6
+ 3.1 HTTP Version .........................................6
+ 3.2 MCMP Version .........................................6
+ 3.3 HTTP Methods .........................................6
+ 3.4 MCMP URL .............................................7
+ 3.5 Command ..............................................7
+ 3.5.1 INFO ..............................................8
+ 3.5.2 ENABLE ...........................................10
+ 3.5.3 DISABLE ..........................................11
+ 3.5.4 STOP .............................................12
+ 3.5.5 DELETE ...........................................13
+ 3.5.6 CONFIG ...........................................14
+ 3.5.7 EXEC ...........................................14
+ 3.5.8 RESET ...........................................14
+ 4 Resource Types .........................................15
+ 4.1 Server ..............................................15
+ 4.1.1 General Information ..............................15
+ 4.1.2 Client Connection Information ....................17
+ 4.2 Host ................................................18
+ 4.2.1 General Information ..............................18
+ 4.2.2 Application ......................................19
+ 4.3 Balancer ............................................21
+ 4.3.1 StickySession ....................................21
+ 4.3.2 StickySessionCookie ..............................21
+ 4.3.3 StickySessionPath ................................22
+ 4.3.4 StickySessionRemove ..............................23
+ 4.3.5 StickySessionForce ...............................23
+ 4.3.6 TimeOut ..........................................23
+ 4.4 Member ..............................................24
+ 4.4.1 Type .............................................24
+ 4.4.2 Address ..........................................24
+ 4.4.3 Port .............................................24
+ 4.4.4 Route ............................................25
+ 4.4.5 Domain ...........................................25
+ 4.4.6 Ping .............................................25
+ 4.4.7 MaxConnections ...................................26
+ 4.4.8 MinConnections ...................................26
+ 4.4.9 TTL ..............................................26
+ 4.4.10 LF ..............................................26
+ 4.4.11 Distance ........................................26
+ 4.4.12 Activation ......................................27
+ 4.4.13 Statistical data ................................27
+ 4.4.14 ENABLE ..........................................28
+ 4.4.15 DISABLE .........................................28
+ 4.4.16 STOP ............................................28
+ 4.4.17 INFO ............................................28
+ 4.4.18 DELETE ..........................................29
+ 4.5 Application .........................................29
+ 4.5.1 State ............................................29
+ 4.5.2 Statistical data .................................29
+ 4.5.3 DELETE ...........................................30
+ 4.6 ApplicationPool .....................................31
+ 4.6.1 Status ...........................................31
+ 4.6.2 Concurrency ......................................31
+ 4.6.3 TimeOut ..........................................31
+ 4.6.4 Statistical data .................................31
+ 5.Manager ................................................32
+ 5.1 Strict ...............................................33
+ 5.2 ProtocolVersion ......................................33
+ 5.3 ServerId .............................................34
+
+
+Turk, et. al. Standards Track [Page 1]
+
+RFC 5501 MCMP March 2008
+
+
+1 Introduction
+
+1.1 Purpose
+
+ This document describes an extension to the HTTP/1.1 protocol that
+ allows clients to perform remote clustering management operations.
+ This extension provides a coherent set of methods, headers, request
+ entity body formats, and response entity body formats that provide
+ operations for:
+
+ Members: The ability to create, remove, update and query information
+ about cluster members, such as their node address, session route, etc.
+ Also, the ability to link Applications of any media type to related
+ members.
+
+ Applications: The ability to create sets of mapped Applications and to
+ establish relationship between applications and members.
+
+1.2 Requirements
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [34].
+
+ An implementation is not compliant if it fails to satisfy one or more
+ of the MUST or REQUIRED level requirements for the protocols it
+ implements. An implementation that satisfies all the MUST or REQUIRED
+ level and all the SHOULD level requirements for its protocols is said
+ to be "unconditionally compliant"; one that satisfies all the MUST
+ level requirements but not all the SHOULD level requirements for its
+ protocols is said to be "conditionally compliant."
+
+
+
+Turk, et. al. Standards Track [Page 2]
+
+RFC 5501 MCMP March 2008
+
+
+1.3 Terminology
+
+ This specification uses a number of terms to refer to the roles
+ played by participants in, and objects of, the MCMP communication.
+
+ connection
+ A transport layer virtual circuit established between two programs
+ for the purpose of communication.
+
+ client
+ A program that establishes connections for the purpose of sending
+ requests.
+
+ message
+ The basic unit of HTTP communication, consisting of a structured
+ sequence of octets matching the syntax defined in HTTP/1.1
+ specification [RFC2068].
+
+ request
+ An HTTP request message, as defined in HTTP/1.1 specification
+ [RFC2068].
+
+ response
+ An HTTP response message, as defined in HTTP/1.1 specification
+ [RFC2068].
+
+ server
+ An application program that accepts connections in order to
+ service requests by sending back responses. Any given program may
+ be capable of being server; our use presumes it is Web server.
+
+ member
+ A dynamic resource in the web server that connects to the
+ remote backend application server node and proxies the requests
+ back and forth.
+
+ node
+ An backend application program that accepts connections in order
+ to service requests from member by sending back responses.
+
+ node connection
+ A transport layer virtual circuit established between member
+ and node for the purpose of communication.
+
+ node connection pool
+ A pool of connections between member and node for the purpose
+ of limiting and caching the node connections.
+
+
+Turk, et. al. Standards Track [Page 3]
+
+RFC 5501 MCMP March 2008
+
+
+ node protocol
+ The protocol used for communication between member and node.
+ Supported protocols are Apache Jserv Protocol (AJP) version
+ 1.3 as described in AJP protocol specification
+ [http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html],
+ HTTP 1.1 [RFC2068] and HTTPS [RFC2818].
+
+ application
+ A network data object or service that can be identified by a URI,
+ as defined n HTTP/1.1 specification [RFC2068] and provided by
+ the node.
+
+ cluster
+ A set of nodes that creates an management entity; our
+ use presumes they provide the same set of applications.
+
+ cluster group
+ A set of nodes in the cluster that shares the session replication
+ between them; our use presumes they have "buddy replication"
+ in place.
+
+ balancer
+ An static resource in the web server that consists of the list
+ of members. Balancer chooses the best member for servicing the
+ client request from the cluster or cluster group.
+
+ manager
+ An static resource in the web server that receives protocol
+ requests and manages the resources in the web server.
+
+ administrator
+ An application or applications in the cluster that communicates
+ with the manager using MCMP protocol. Its main usage is to
+ provide the manager with list of nodes, clusters, cluster groups
+ and applications together with the balancer information needed
+ for selecting the best node within the cluster for servicing the
+ client request.
+
+
+
+Turk, et. al. Standards Track [Page 4]
+
+RFC 5501 MCMP March 2008
+
+
+1.4 Overall Operation
+
+ The MCMP protocol is a request/response protocol. An administrator
+ sends a request to the web server in the form of a HTTP request method,
+ URI, and protocol version, followed by a set of headers containing request
+ modifiers, node information, etc. The manager responds with a status line,
+ including the message's protocol version and a success or error code,
+ followed by a text/plain MIME-like message containing server information,
+ entity metainformation, and possible entity-body content.
+
+ Client--->Balancer--->1*Member---->1*Node
+ | | |
+ +---------Manager<---->1*Administrator
+
+ The figure above shows the typical relation between participants
+ in the system.
+
+Turk, et. al. Standards Track [Page 5]
+
+RFC 5501 MCMP March 2008
+
+
+2 Notational Conventions and Generic Grammar
+
+ The Notational Conventions and Generic Grammar used is the one specified
+ in the HTTP 1.1 protocol specification RFC2068 [2].
+
+3 Protocol Parameters
+
+3.1 HTTP Version
+
+ MCMP uses HTTP 1.1 protocol version as defined in HTTP/1.1 specification
+ [RFC2068]. For the increased security the protocol used can be HTTP over
+ TLS or usually known as HTTPS [RFC2818].
+
+3.2 MCMP Version
+
+ The current MCMP version according to this rfc is "1.0".
+ MCMP uses a "<major>.<minor>" numbering scheme to indicate versions
+ of the protocol.
+
+ The version of an MCMP message is indicated by an MCMP-Version field
+ in the first line of the message.
+
+ MCMP-Version = "MCMP" "/" 1*DIGIT "." 1*DIGIT
+
+ Note that the major and minor numbers MUST be treated as separate
+ integers and that each may be incremented higher than a single digit.
+ Thus, MCMP/2.4 is a lower version than MCMP/2.13, which in turn is
+ lower than MCMP/12.3. Leading zeros MUST be ignored by recipients and
+ MUST NOT be sent.
+
+3.3 HTTP Methods
+
+ MCMP uses GET HTTP method for management and OPTIONS method for
+ determining the validity of the connection between member and node.
+
+
+
+Turk, et. al. Standards Track [Page 6]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.4 MCMP URL
+
+ Each mcmp requests MUST be an valid http request with URI
+ compliant to the RFC2068 [3.2]. The query MAY be present to
+ specify the command. In case the query is not present then the
+ administrator MUST provide the Server-Command header with corresponding
+ command value or use the appropriate HTTP method.
+ This section defines the scheme-specific
+ syntax and semantics for mcmp URLs.
+
+ mcmp_URL = "http:" "//" host [ ":" port ] abs_path [ cmd_path | "?" query ]
+
+ If the port is empty or not given, port 80 is assumed. Each mcmp_URL MUST
+ have either cmd_path, query or Server-Command header that corresponds to the
+ specific command the manager will fulfil. An example mcmp URL would be:
+
+ http://localhost:8000/manager/info
+ or:
+ http://localhost:8000/manager?info
+ or:
+ GET /manager HTTP/1.0
+ Host: localhost
+ Server-Command: info
+
+ The first example from above allows the web server to enforce command
+ based grained security as shown in the following Apache Httpd example:
+
+ <Location /manager/info>
+ SetHandler cluster-manager
+ Order Deny,Allow
+ Allow from 127.
+ </Location>
+
+ In case the query is not present the manager SHOULD treat the last part
+ of the mcmp_URL as a command in the same fashion as query. Both cmd_path
+ and query are case insensitive.
+
+3.5 Command
+
+ The Command token indicates the command to be performed on the manager
+ identified by the MCMP URL. The command is case-insensitive.
+
+ Command = "INFO" ; Section 3.5.1
+ | "ENABLE" ; Section 3.5.2
+ | "DISABLE" ; Section 3.5.3
+ | "STOP" ; Section 3.5.4
+ | "DELETE" ; Section 3.5.5
+ | "CONFIG" ; Section 3.5.6
+
+ Each command usually carries additional command line parameters. The
+ command line parameters are described for each particular command.
+
+ If the command is not recognised by the manager the manager SHOULD
+ respond with 200 (OK) response and the following entity-body using
+ text/plain MIME-type:
+
+ "?" MCMP-Version CRLF
+
+ Any other non 200 response is treated by the administrator as
+ communication problem between administrator and the manager.
+
+
+Turk, et. al. Standards Track [Page 7]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.5.1 INFO
+
+ The INFO command causes the manager to gather the information about
+ the specific resource on the server and present that information to
+ the administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ Server-Resource = "Server-Resource" ":"
+ #( resource-type )
+
+ resource-type = ( "*/*"
+ | ( type )
+ | ( type "/" "*" )
+ | ( type "/" subtype )
+ ) *( ";" parameter )
+
+ parameter = token [ "=" ( token | quoted-string ) ]
+
+ type = "server"
+ | "host"
+ | "balancer"
+ | "member"
+ | "application"
+
+ The asterisk "*" character is used to group resource types,
+ with "*/*" indicating all resource types and "type/*" indicating all
+ subtypes of that type. The resource type MAY include resource type
+ parameters that are applicable to that type.
+
+ The example
+
+ Server-Resource: member/*; load-factor; busy
+
+ will return the all members in the server with their load-factor and
+ busy parameter fields. If the parameters are not present then the
+ full information for the resource type SHOULD be returned.
+ The application subtype MAY contain the full application URL
+ in which case the leading slash MUST NOT be provided.
+
+ Server-Resource: application/foo/bar; status; host/*
+
+ will return the list of hosts on which the application with /foo/bar
+ URL is configured, and the status of the application within each host.
+
+
+Turk, et. al. Standards Track [Page 8]
+
+RFC 5501 MCMP March 2008
+
+
+
+ If the manager does contain information about requested type then it
+ MUST respond with 200 (OK) response and the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does contain information about requested subtype then it
+ MUST respond with 200 (OK) response and the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type information then
+ those information is returned as entity-body in random order with each
+ line representing a single resource-type.
+
+ Resource-Response = *( resource-type CRLF )
+
+ The example
+
+ member/node1; load-factor=10; busy=100
+ member/node2; load-factor=10; busy=105
+
+ Administrator MUST take the order of Resource-Response information
+ into account. If the Resource-Response contains the hierarchical
+ information the manager will provide the correct hierarchical order
+ of the resources.
+
+ The example
+
+ host/www.foo.org
+ application/foo; status=200
+ application/bar; status=404
+ host/www.foo.com
+ application/foo; status=503
+ application/baz; status=200
+
+ The resource-type hierarchy is implied by the system and
+ it looks like shown:
+
+ server ---> 1*host ----> 1*application
+ | ^
+ | |
+ +--> balancer --> 1*member -+
+
+ The output of INFO command MUST include the resource type
+ name in case the command evaluation results in multiple resource types
+ returned.
+ The output of INFO command MUST include the parameter name in case
+ the command evaluation results in multiple parameters returned.
+
+
+Turk, et. al. Standards Track [Page 9]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.5.2 ENABLE
+
+ The ENABLE command causes the manager to enable the specific resource
+ on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type object configured
+ and enable succeeds then it MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case the enable for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ The error-code is manager specified error code and error-description
+ is human readable description of the error code.
+ Error codes MAY be standard POSIX errno values with corresponding
+ description according to the POSIX specification.
+
+ The example
+
+ ?Error: 22; Invalid argument
+
+ Where 22 corresponds to the EINVAL error code from the POSIX
+ specification.
+ For the resources objects for which the ENABLE command is invalid
+ manager MUST respond with:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+
+ In case the resource object is already enabled the manager MUST
+ reply with the success, and MAY skip any processing that might
+ be needed.
+
+
+
+Turk, et. al. Standards Track [Page 10]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.5.3 DISABLE
+
+ The DISABLE command causes the manager to disable the specific resource
+ on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ mode then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ mode then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type object configured
+ and disable succeeds then it MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case the disable for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ Depending on the resource object type the DISABLE command has different
+ consequences. For node object it MUST disable further acceptance of
+ the request that does not carry the session affinity mark information.
+ This will cause that those nodes MUST get excluded from the balancer
+ scheduler list for all new requests while preserving the ones that carry
+ the session affinity mark.
+ For the resources objects for which the DISABLE command is invalid
+ manager MUST respond with:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+ In case the resource object is already disabled the manager MUST
+ reply with the success, and MAY skip any processing that might
+ be needed.
+
+
+
+Turk, et. al. Standards Track [Page 11]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.5.4 STOP
+
+ The STOP command causes the manager to stop the specific resource
+ on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type object configured
+ and stop succeeds then it MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case the stop for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ Depending on the resource object type the STOP command has different
+ consequences. For node object it MUST stop further acceptance of
+ the request after finishing the currently executing requests.
+ In case there is no more application left attached to this node all
+ the connections from the member to the node MUST be closed.
+ This will cause that those nodes MUST get excluded from the balancer
+ scheduler list for all requests until enabled again.
+ For the resources objects for which the STOP command is invalid
+ manager MUST respond with:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+ In case the resource object is already stopped the manager MUST
+ reply with the success, and MAY skip any processing that might
+ be needed.
+
+
+
+Turk, et. al. Standards Track [Page 12]
+
+RFC 5501 MCMP March 2008
+
+
+3.5.5 DELETE
+
+ The DELETE command causes the manager to remove the specific resource
+ on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ and is in strict mode then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ and is in strict mode then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type object configured
+ and delete succeeds then it MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case the delete for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ Depending on the resource object type the DELETE command has different
+ consequences. In general, object resource MUST NOT be deleted in case
+ it is referenced by some other object resource.
+ Application resource object MUST NOT be deleted unless it is in the
+ STOP mode. Node object MUST NOT be deleted if it contains any application
+ that is not in the STOP mode. In both cases the manager MUST respond
+ with the following entity-body using text/plain MIME-type:
+
+ ?Error: 16; Device or resource busy
+
+ Where 16 corresponds to the EBUSY error code from the POSIX
+ specification.
+
+ Deleting static objects or web server objects is not permitted and
+ manager MUST respond with the following entity-body using text/plain
+ MIME-type:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+ Deleting objects from the web server does not mean the server will
+ reuse the memory occupied by the deleted resource, thus the deletion
+ must be taken with care and avoid large number of deletions.
+
+
+
+Turk, et. al. Standards Track [Page 13]
+
+RFC 5501 MCMP March 2008
+
+
+
+3.5.6 CONFIG
+
+ The CONFIG command causes the manager to create or update the specific
+ resource on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ and is in strict mode then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ then it MUST create the specified object. If the object creation succeeds
+ then it MUST response with the following entity-body using text/plain
+ MIME-type:
+
+ "OK" CRLF
+
+ In case the manager has the requested resource type object configured
+ then CONFIG command MUST update the resource object and MUST overwrite
+ provided parameters. If update of the resource object succeeds then it
+ MUST response with the following entity-body using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case CONFIG for the specified resource type object is not
+ permitted or the resource or resource parameter is read only,
+ then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+
+
+ In case CONFIG for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ By default, newly created objects MUST be in STOP mode. To be functional
+ the objects MUST be put in the desired operational mode (ENABLE or DISABLE).
+ Creating new objects MAY cause the additional processing on
+ the web server and dependency on the other objects. In case the dependency
+ is not satisfied the manager MUST roll back the creation of the object
+ and it MUST response with the following entity-body using text/plain
+ MIME-type:
+
+ ?Error: 19; No such device
+
+ Where 19 corresponds to the ENODEV error code from the POSIX
+ specification.
+
+3.5.7 EXEC
+
+ The EXEC command is reserved for future use.
+ It will be used for Member to execute the ping/pong or to clear all
+ the active connections or to try to reconnect.
+
+
+3.5.8 RESET
+
+ The RESET command causes the manager to reset the specific resource
+ on the server and presents the result of that operation to the
+ administrator in a form of text/plain MIME-type reply.
+ The Server-Resource header field MUST be present in the request to
+ determine the type of server resource.
+
+ If the manager does not contain the requested type object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type CRLF
+
+ If the manager does not contain the requested subtype object configured
+ then it MUST respond with 200 (OK) response and the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Unknown-Type" ":" type "/" subtype CRLF
+
+ In case the manager has the requested resource type object configured
+ and reset succeeds then it MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "OK" CRLF
+
+ In case the reset for the specified resource type object does not
+ succeeds then the manager MUST response with the following entity-body
+ using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ Depending on the resource object type the RESET command has different
+ consequences.
+ For the resources objects for which the RESET command is invalid
+ manager MUST respond with:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+ In case the resource object is already stopped the manager MUST
+ reply with the success, and MAY skip any processing that might
+ be needed.
+
+
+Turk, et. al. Standards Track [Page 14]
+
+RFC 5501 MCMP March 2008
+
+
+
+4 Resource Types
+
+ Resource types are fixed objects or object collections inside web server
+ accessible by manager. There are five basic resource types; server, host,
+ balancer, member and application (see section 3.5.1).
+ Each resource type MAY contain the collection of name based resources
+ either as resource instance or reference to the resource instance.
+ In case the object is a reference to the resource instance the
+ resource collection item MAY contain local resource parameters. The object
+ reference MUST inherit parameters from the object instance, but then if
+ the object have local parameters they MUST preserve local data integrity.
+ Updating instance parameters MAY propagate the values to all references
+ local data having the same parameter.
+
+4.1 Server
+
+ Server resource type is the root object in the system and contains the
+ web server parameters. It MUST support the INFO command and MAY support
+ the CONFIG command. In case the CONFIG is not supported the manager MUST
+ respond with EPERM error code (see section 3.5.6).
+
+4.1.1 General Information
+
+ Server MUST provide the following parameters:
+
+ ServerName
+ Hostname and port that the server uses to identify itself.
+
+ ServerRoot
+ Base directory for the server installation.
+
+ ServerVersion
+ Version if the server.
+
+ ServerBuilt
+ Date and time when the server was built.
+
+ ServerArchitecture.
+ CPU architecture of the server (32 or 64 bit).
+
+ ThreadsPerChild
+ Number of threads created by each child process.
+ If the server does not use threading model then it MUST
+ report this value as 1.
+
+ MaxRequestsPerChild
+ Limit on the number of requests that an individual child server
+ will handle during its life. After MaxRequestsPerChild requests,
+ the child process will die.
+
+
+Turk, et. al. Standards Track [Page 15]
+
+RFC 5501 MCMP March 2008
+
+
+
+ ListenBackLog
+ Maximum length of the queue of pending connections
+
+ MaxClients
+ Limit on the number of simultaneous requests that will be served.
+ Any connection attempts over the MaxClients limit will normally
+ be queued, up to a number based on the ListenBacklog parameter.
+
+ CurrentTime
+ Current time on the server.
+
+ RestartTime
+ Time when the server was restarted.
+
+ ServerUpTime
+ Number of seconds since server start.
+
+ AccessCount
+ Number of requests since ServerUpTime.
+
+ BytesServed
+ Number of bytes served since ServerUpTime.
+
+ LimitRequestFields
+ Number is an integer from 0 (meaning unlimited) to 32767.
+ The default value is defined by the compile-time constant
+ DEFAULT_LIMIT_REQUEST_FIELDS (100 as distributed).
+
+ LimitRequestFieldSize
+ Specifies the number of bytes that are allowed in an HTTP
+ request header.
+
+ The server SHOULD provide the following parameters:
+
+ ConfigurationFile
+ Name of the configuration file the server is using.
+
+
+
+Turk, et. al. Standards Track [Page 16]
+
+RFC 5501 MCMP March 2008
+
+
+
+ CurrentConfiguration
+ Dump the current server configuration using the following notation:
+
+ current-configuration = *( "File" ":" configuration-file CRLF
+ *( [line-number] ":" directive CRLF )
+ )
+
+ The CurrentConfiguration parameter MUST be the only parameter
+ when executing server INFO command. All other parameters MUST
+ be disregarded from the requested parameter list.
+
+ The example output from the Apache Httpd server:
+
+ File: /opt/apache/conf/httpd.conf
+ 99: <Directory />
+ 100: Options FollowSymLinks
+ 101: AllowOverride None
+ : </Directory>
+ File: /opt/apache/conf/extra/httpd.info
+ 14: <Location /server-status>
+ 15: SetHandler server-status
+ : </Location>
+ File: /opt/apache/conf/httpd.conf
+ 5: Listen 80
+
+ Note that CurrentConfiguration does not represent the real
+ configuration file structure because it MAY remove all comments
+ and empty lines, neither the ordering reflects the original
+ ordering.
+
+
+4.1.2 Client Connection Information
+
+ Server SHOULD provide the connection information about each client
+ connection up to the MaxClients server parameter.
+
+ Connection = "Connection" "=" #( connection-id )
+
+ connection-id = ( "*" | connection-id )
+
+ will result in response containing the connection-status for one
+ or single connection.
+
+ connection-status = *( "." ; Server is dead
+ | "-" ; Ready
+ | "S" ; Starting
+ | "R" ; Reading
+ | "W" ; Writing
+ | "K" ; Keep-Alive
+ | "L" ; Writing to log
+ | "D" ; Resolving DNS
+ | "C" ; Closing
+ | "G" ; In graceful restart
+ | "I" ; Idle
+
+
+
+Turk, et. al. Standards Track [Page 17]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.2 Host
+
+
+ Host resource type represents the servers Host or Virtual Host.
+ Host MAY contain any number of application resource objects.
+ By default the Host object is created from server native configuration.
+
+ The Host that was created from server native configuration
+ MUST not be deleted. If the manager tries to DELETE such Host
+ the manager must respond with the following entity-body using
+ text/plain MIME-type:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+
+
+4.2.1 General Information
+
+ Host MUST provide the following parameters:
+
+ ServerName
+ Specifies what hostname must appear in the request's Host: header
+ to match this virtual host.
+
+ ServerAlias
+ Alternate names for a host used when matching requests
+ to name-virtual hosts.
+ [ "ServerAlias" "=" ] *( hostname SP )
+
+ IsVirtual
+ Is this a virtual host.
+ [ "IsVirtual" "=" ] ( "On" | "Off" )
+
+ DocumentRoot
+ Directory that forms the main document tree visible from the web.
+
+ ServerPath
+ Legacy URL pathname for a name-based virtual host that is accessed
+ by an incompatible browser.
+
+ KeepAlive
+ This server supports the persistent connections.
+ [ "KeepAlive" "=" ] ( "On" | "Off")
+
+ KeepAliveTimeout
+ Amount of time the server will wait for subsequent requests on a
+ persistent connection.
+
+ MaxKeepAliveRequests
+ Number of requests allowed on a persistent connection.
+
+ TimeOut
+ Amount of time the server will wait for certain events before
+ failing a request
+
+
+Turk, et. al. Standards Track [Page 18]
+
+RFC 5501 MCMP March 2008
+
+
+
+ LimitRequestBody
+ Specifies the number of bytes from 0 (meaning unlimited) to
+ 2147483647 (2GB) that are allowed in a request body.
+
+ Address
+ The bound IPV4 or IPV6 address for this host.
+
+ Port
+ The bound port for this host.
+
+ The host MAY provide the following parameters:
+
+ VirtualName
+ The name given in <VirtualHost > configuration.
+
+4.2.2 Application
+
+ Application resource type is configurable object inside host,
+ and it maps the incoming URLs to global balancer object.
+ Host MUST support unlimited number of application resource objects
+ and MUST support all commands.
+ If the application was already configured and created inside balancer
+ resource object then the manager MUST create application object
+ instance inside host object, otherwise it MUST reference already
+ created application instance inside balancer object.
+ This allows to have multiple instances of the application that have
+ the same name. Likewise it allows to share the common applications
+ between host resource objects.
+
+ Each application configured inside host MUST have it's own status
+ parameter that defines how the manager will map the application.
+
+ application-status = "Status" "="
+ ( 200 ; Application mapping allowed
+ | HTTP-Status ; Return HTTP-Status to the client
+ )
+
+ HTTP-Status as defined in RFC2068 [10].
+
+ When configuring the application object application-status MUST be
+ set to 200 unless explicitly specified inside CONFIG command.
+ On evaluation if the application is reference the manager MUST
+ first use the application-status from the instance of the application
+ object and only if the application-status is 200 the manager MAY
+ apply his local application-status.
+
+ DELETE command MUST remove the application object from the host.
+ In case the application object was a reference then the manager MUST
+ preserve the original application object and delete only the local
+ parameter data. Deleting the application from the host is the same
+
+
+
+Turk, et. al. Standards Track [Page 19]
+
+RFC 5501 MCMP March 2008
+
+
+
+ as setting the application-status to 404, so the administrator
+ MAY use this instead object deletion. Processing application with
+ application-status equal to 404 MUST produce the same result as if
+ the application was not defined at all.
+
+ STOP command MUST set the application-status to 404.
+ DISABLE command MUST set the application-status to 503.
+ ENABLE command MUST set the application-status to 200.
+ Those commands are convenience methods for using the CONFIG
+ command with corresponding application-status value.
+
+ The example
+
+ DISABLE Server-Resource: host/www.foo.org; application/*
+
+ MUST set the application-status to 503 for all the applications
+ inside www.foo.org host resource object. Next client request to the
+ www.foo.org host MUST then always return 503 HTTP-Status message
+ to the client for all configured applications.
+
+ The following example does exactly the same thing as above, but
+ using the CONFIG command and status parameter to set the
+ application-status.
+
+ CONFIG Server-Resource: host/www.foo.org; application/*; status=503
+
+
+
+
+
+
+Turk, et. al. Standards Track [Page 20]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.3 Balancer
+
+ Balancer resource type is static object inside server. Default
+ balancer object instance MUST be created at server startup and
+ present for the server lifetime. The name of this resource MUST
+ be set to "_default_", and server MUST use this balancer if the
+ balancer resource name or type was not provided with the command.
+
+ Balancer object instance contains the list of member instance
+ objects and it MUST support all commands.
+
+ Additional balancer object instances MAY be created inside server
+ and the server SHOULD NOT limit their number. However different
+ balancer object instances cannot share the same member object
+ instances and server MUST assure that two members with the same
+ member-host and member-port do not appear in two different balancer
+ instances. In case such attempt is made the manager must respond
+ with the following entity-body using text/plain MIME-type:
+
+ ?Error: 18; Cross-device link
+
+ Where 18 corresponds to the EXDEV error code from the POSIX
+ specification.
+
+
+4.3.1 StickySession
+
+ StickySession is balancer parameter with default value set to "On".
+ The balancer MAY extract the data from the sticky-session-cookie
+ or from the sticky-session-path to maintain the session affinity
+ for the particular member matching the session-route
+ (see 4.3.1 and 4.3.2).
+
+
+4.3.2 StickySessionCookie
+
+ StickySessionCookie is balancer parameter with default value
+ equal to "JSESSIONID" and is used to find the session affinity
+ mark that matches the member name. The member name comparison
+ MUST be case insensitive. However the comparison for the
+ StickySessionCookie MUST be case sensitive.
+
+ If the Cookie or Cookie2 header value provided by the client have
+ multiple occurrences of the StickySessionCookie only the last one
+ MUST be used for further processing.
+
+ sticky-session-cookie = "StickySessionCookie" "=" string
+
+
+
+
+Turk, et. al. Standards Track [Page 21]
+
+RFC 5501 MCMP March 2008
+
+
+
+ The extracted route information from the Cookie is
+
+ sticky-route = StickySessionCookie" "="
+ #( session-route )
+
+ session-route = ( session-id [ "." [ token ] ] )
+
+ session-domain = ( session-route
+ | session-route [ "." token ] ]
+ )
+
+ If the session-id contains the "." character everything after
+ that character MUST be treated as session-route. If the session
+ route contains "." character everything after that character
+ MUST be treated as session-domain.
+
+
+4.3.3 StickySessionPath
+
+ StickySessionPath is balancer parameter with default value
+ equal to ";jsessionid" and is used to find the session affinity
+ mark that matches the member name. The member name comparison
+ MUST be case insensitive. However the comparison for the
+ StickySessionPath MUST be case sensitive.
+
+ If the URL header value provided by the client have
+ multiple occurrences of the StickySessionPath only the last one
+ MUST be used for further processing.
+
+ sticky-session-path = "StickySessionPath" "=" string
+
+ The extracted route information from the Cookie is
+
+ sticky-route = "StickySessionPath" "="
+ #( session-route )
+
+ session-route = ( session-id [ "." [ token ] ] )
+
+ session-domain = ( session-route
+ | session-route [ "." token ] ]
+ )
+
+ If the session-id contains the "." character everything after
+ that character MUST be treated as session-route. If the session
+ route contains "." character everything after that character
+ MUST be treated as session-domain.
+
+
+
+
+Turk, et. al. Standards Track [Page 22]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.3.4 StickySessionRemove
+
+ StickySessionRemove is balancer parameter with default value
+ equal to "On" and is used to remove the sticky-session-cookie or
+ the sticky-session-path for failed mappings and routes.
+ (see section 4.3.5).
+
+ [ "StickySessionRemove" "=" ] ( "On" | "Off" )
+
+ When set to "On" the server MUST remove the sticky-session-cookie
+ from the Cookie header or sticky-session-path from the URL.
+
+
+4.3.5 StickySessionForce
+
+ Specifies whether requests with session-route for members that are
+ in error state should be rejected. If StickySessionForce is set to
+ "On" and the member that matches that session-route is in error state,
+ client will receive 500 (Server Error).
+ If set to "Off" (default value) failover on another member will be
+ issued with possibility of loosing client session.
+
+ [ "StickySessionForce" "=" ] ( "On" | "Off" )
+
+ If StickySessionRemove was set to "On" and member that matches the
+ session-route was in error state, the server MUST remove the
+ sticky-session-cookie from the Cookie header or sticky-session-path
+ from the URL. However this directive MUST be evaluated only if
+ the StickySession was set to "On"
+
+ For domain session routes all members of the domain MUST be
+ in error state to evaluate this rule.
+
+
+4.3.6 TimeOut
+
+ Connection wait timeout in seconds. If not set the balancer will
+ wait until the free connection is available. This directive is
+ used for limiting the number of connections to the node together
+ with MaxConnections member parameter.
+ Default value is server TimeOut.
+
+
+Turk, et. al. Standards Track [Page 23]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.4 Member
+
+ Member is resource object contained inside balancer object. Member
+ object provides the connection capability from the server to the node
+ and proxies the requests from the client to the node.
+
+
+4.4.1 Type
+
+ Type parameter defines the protocol the member is using when
+ communication to the node.
+
+ type = "Type" "="
+ #( protocol-type )
+
+ protocol-type = "ajp"
+ | "http"
+ | "https"
+
+ Once created the member MUST NOT change its protocol-type. Any such
+ attempt MUST respond with the following entity-body using
+ text/plain MIME-type:
+
+ ?Error: 1; Operation not permitted
+
+ Where 1 corresponds to the EPERM error code from the POSIX
+ specification.
+
+
+4.4.2 Address
+
+ Host name or IP address of the node to which the member connects.
+ The Host name can have a port number embedded separated by the
+ colon (":") character. Default value for the Address is "localhost"
+
+ Once created the member MUST NOT change its address unless the
+ member is in the STOP mode. Any such attempt must respond with
+ error message (see section 4.4.1).
+
+
+4.4.3 Port
+
+ Port number of the node to which the member connects.
+ The default value depends on the protocol-type and is
+
+ ajp = "8009"
+ http = "8080"
+ https = "8443"
+
+ Once created the member MUST NOT change its address unless the
+ member is in the STOP mode. Any such attempt must respond with
+ error message (see section 4.4.1).
+
+
+
+Turk, et. al. Standards Track [Page 24]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.4.4 Route
+
+ Route of the member is a value that SHOULD match to the session-route.
+ Balancer to whom the member belongs will select this member if the
+ session-route matches the Route. Route value MUST be case insensitive.
+
+ The length of the Route MUST be within 0 and 63 characters. In case
+ the length of Route is outside the limited range the manager MUST
+ respond with the following entity-body using text/plain MIME-type:
+
+ ?Error: 22; Invalid argument
+
+ Where 22 corresponds to the EINVAL error code from the POSIX
+ specification.
+
+
+4.4.5 Domain
+
+ Domain of the member is a value that SHOULD match to the session-domain.
+ Balancer to whom the member belongs will select this member if the
+ session-domain matches the Domain. Domain value MUST be case insensitive.
+ Balancer MUST match the Domain only if the matched session-route member
+ is not inside operational state.
+
+ The length of the Route MUST be within 0 and 63 characters. In case
+ the length of Domain is outside the limited range the manager MUST
+ respond with EINVAL error code (see section 4.4.4).
+
+
+4.4.6 Ping
+
+ Ping property MAY cause member to send a CPING request on ajp connection
+ before forwarding a request. The parameter is the delay in seconds
+ to wait for the CPONG reply. Currently this has an effect only if the
+ member Type is ajp. If the value of the property is zero (default)
+ then the member MUST NOT send the CPING requests.
+
+ If the attempt is made to set the non zero value to the member which
+ Type is different then ajp the manager MUST respond with EINVAL
+ error code (see section 4.4.4).
+
+
+
+Turk, et. al. Standards Track [Page 25]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.4.7 MaxConnections
+
+ Maximum number of connections that are allowed at any moment to
+ the node on each child process inside server. For threaded servers
+ this value MUST be within the range of 1 and the number of
+ ThreadsPerChild (see section 4.1.1). For non threaded servers this
+ value MUST always be one.
+
+ In case MaxConnections is outside the limited range the manager MUST
+ respond with EINVAL error code (see section 4.4.4).
+
+
+4.4.8 MinConnections
+
+ Minimum number of connections that the member will keep opened.
+ This value MUST be within the range of 1 and MaxConnections.
+
+ In case MinConnections is outside the limited range the manager MUST
+ respond with EINVAL error code (see section 4.4.4).
+
+
+4.4.9 TTL
+
+ Time To Live for the inactive connections above the MinConnections
+ in seconds. Apache will close all connections that has not been
+ used inside that time period.
+
+
+4.4.10 LF
+
+ Load Factor is the property of the member used by the balancer
+ to schedule the load. The value of LF property MUST be
+ within the 1 and 100 and defines the normalized weighted load
+ applied to the member. Default value is 1.
+
+
+4.4.11 Distance
+
+ An integer number to express preferences between the balanced
+ members of an balancer. A balancer MUST never choose some
+ member in case there is another usable member with lower distance.
+
+ Only in case all members below a given distance are in error,
+ disabled or stopped, member of a larger distance MAY be eligible
+ for balancing. This property is used for creating hot standby
+ members. Multiple hot standby chains might be created each
+ having the same Distance property larger by one.
+ Default value for Distance property is zero.
+
+
+
+Turk, et. al. Standards Track [Page 26]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.4.12 Activation
+
+ Defines the activation state of the member.
+
+ activation = ( "D" ; Disabled
+ | "S" ; Stopped
+ | "A" ; Active
+ )
+
+ Member with activation disabled ("D") only gets requests, which belong
+ to sessions for that member.
+ Member with activation stopped ("S") does not get requests requests.
+ Active ("A") means that the member works normally.
+
+
+4.4.13 Statistical data
+
+ Member MUST provide the following parameters:
+
+ State
+ Current state of the member resource object can be one
+ of the following values:
+
+ member-state = ( operational-state
+ | activation-state
+ | error-state
+ )
+
+ operational-state = ( "I" ; Idle
+ | "A" ; Active
+ | "B" ; Busy
+ )
+
+ activation-state = ( "D" ; Disabled
+ | "S" ; Stopped
+ )
+
+ error-state = "E" ; Error
+
+ Error
+ Error code and textual description of the error code
+
+ error = error-code [ ":" error-description ]
+
+ Busy
+ Number of connections that are currently servicing the
+ client requests.
+
+ Connected
+ Number of connections that are currently opened between
+ member and node.
+
+ Elected
+ Number of times the member was elected from the load balancer.
+
+ StickySessions
+ Number of times the member was elected according to the
+ sticky session rule.
+
+ ClientErrors
+ Number of client errors caused by communication error
+ between member and client.
+
+
+
+Turk, et. al. Standards Track [Page 27]
+
+RFC 5501 MCMP March 2008
+
+
+
+ NodeErrors
+ Number of errors caused by communication error between
+ member and node.
+
+ Readed
+ Number of bytes read from node.
+
+ Transferred
+ Number of bytes transferred to node.
+
+ Trace
+ Number of times the member was doing health check call
+ to the node.
+
+ TraceErrors
+ Number of times the member was doing health check call
+ to the node and the trace failed.
+
+
+4.4.14 ENABLE
+
+ ENABLE command when applied to the member if the member was in the
+ error-state state MUST make internal redirect that MUST result in
+ balancer electing this member. ENABLE MUST change the member status
+ only if the Trace call succeeds. In case the call does not succeeds
+ manager MUST NOT change the state of the member and MUST respond to
+ the administrator with the error-code provided by the member with the
+ following entity-body using text/plain MIME-type:
+
+ "?" "Error" ":" error-code; error-description CRLF
+
+ After successful trace the the member MUST change its state to
+ the one defined by activation. ENABLE command MAY have the
+ Activation parameter embedded in the command in which case the
+ member will update its activation status.
+
+
+4.4.15 DISABLE
+
+ DISABLE command is convenient method of setting the Activation
+ to "D" (see section 4.4.12).
+
+
+4.4.16 STOP
+
+ STOP command is convenient method of setting the Activation to
+ "S" (see section 4.4.12). However the manager MUST close all
+ connections to the node once the currently executing requests
+ are finished.
+
+
+4.4.17 INFO
+
+ If no parameters for the INFO command are present member MUST
+ respond as if the requested parameter was State.
+
+
+
+Turk, et. al. Standards Track [Page 28]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.4.18 DELETE
+
+ DELETE command MUST be executed only on stopped members.
+ In case the member is not in stop mode manager MUST return
+ EBUSY error code (see section 3.3.5).
+ If some of the members connections are still servicing the
+ request, those connections MUST be closed.
+ Administrator SHOULD usually wait until all pending
+ client requests are done, but it MAY use this feature to
+ forcibly close the stalled connections
+
+
+4.5 Application
+
+ Application resource object is instantiated inside balancer
+ but it MUST have reference link inside each balancer member.
+ Each member MUST track the status and statistical data for
+ each application defined inside balancer. Aplication instance
+ parameters MUST have higher priority then local member application
+ parameters. By default adding and deleting application objects
+ MUST be reflected to all balancer members.
+
+
+4.5.1 State
+
+ Application State parameter tells the balancer the state of
+ the application:
+
+ application-state = ( "D" ; Disabled
+ | "S" ; Stopped
+ | "A" ; Active
+ )
+
+ Application-state MUST have its local copy inside each balancer member.
+ Balancer MUST treat the final application-state as Active only
+ if both balancer and member application-state parameters are Active.
+ In any other case the balancer application-state MUST take
+ precedence. Disabled and Stopped state MUST be handled like
+ for the member itself (see section 4.4.12).
+
+
+4.5.2 Statistical data
+
+ For each member application MUST provide the following parameters:
+
+ Busy
+ Number of connections that are currently servicing the
+ client requests for this application.
+
+ Readed
+ Number of bytes read from node for this application
+
+ Transferred
+ Number of bytes transferred to node for this application.
+
+
+
+Turk, et. al. Standards Track [Page 29]
+
+RFC 5501 MCMP March 2008
+
+
+
+ Transactions
+ Number of requests for this application.
+
+ ClientErrors
+ Number of client errors caused by communication error
+ between member and client for this application.
+
+ To get the total statistical data across all members for this
+ application administrator MAY execute the following example:
+
+ INFO application/foo/bar
+
+ Manager MUST calculate the total sum of all statistical data
+ from each members of the balancer and present them to the
+ administrator. The output of this operation MAY look like
+ shown below:
+
+ Busy=101; Readed=230364; Transferred=271132; Transactions=50; \
+ ClientErrors=1
+
+
+4.5.3 DELETE
+
+ DELETE command MUST be executed only on stopped applications.
+ In case the application is not in stop mode manager MUST return
+ EBUSY error code (see section 3.3.5).
+
+
+Turk, et. al. Standards Track [Page 30]
+
+RFC 5501 MCMP March 2008
+
+
+
+4.6 ApplicationPool
+
+ ApplicationPool resource object inside server that holds references
+ to the Application objects. There is always on (_default_) ApplicationPool
+ created in the server holding reference for all Applications that have
+ not ApplicationPool explicitly defined.
+
+
+4.6.1 Status
+
+ ApplicationPool Status parameter tells the server the state of
+ the application pool:
+
+ application-pool-status = ( "D" ; Disabled
+ | "S" ; Stopped
+ | "A" ; Active
+ )
+
+ If the ApplicationPool status is Disabled all applications will
+ be rejected causing server to stop any url processing for the
+ Applications that are contained in this Application pool.
+
+4.6.2 Concurrency
+
+ ApplicationPool Concurrency tells the server the maximum number of
+ of requests that are currently in processing. If the total number of
+ active connections exceddes this value new requests MUST be delayed
+ for the maximum of TimeOut parameter.
+
+
+4.6.3 TimeOut
+
+ TimeOut is maximum time the connection that was blocked by excedding
+ the Concurrency value be held in the internal queue.
+
+4.6.4 Statistical data
+
+ For each member application MUST provide the following parameters:
+
+ Busy
+ Number of connections that are currently servicing the
+ client requests for this application pool.
+
+ Applications
+ Number of applications that are currently members of this
+ application pool.
+
+
+
+
+Turk, et. al. Standards Track [Page 31]
+
+RFC 5501 MCMP March 2008
+
+
+
+
+
+5. Manager
+
+ Manager is the application inside server that manages the resource
+ inside web server. In case manager does not understand the
+ given command it MUST return the error message back to the
+ administrator (see section 3.5).
+
+ If the manager does not understand any of the provided command
+ parameters it MUST silently disregard those parameter and use
+ only the one that he understand how to process.
+
+ If the strict flag is set and manager does not understand one of
+ the requested parameters then it MUST respond with 200 (OK)
+ response and the following entity-body using text/plain MIME-type:
+
+ "?" MCMP-Version CRLF
+ 1*("?" "Unknown-Parameter" ":" param CRLF)
+
+ for each parameter that he don't understand and MUST not execute
+ any other action.
+
+
+
+Turk, et. al. Standards Track [Page 32]
+
+RFC 5501 MCMP March 2008
+
+
+
+5.1 Strict
+
+ Strict parameter enforces the manager to treat the object types or
+ parameters as errors if they are not understandable by the current
+ manager version.
+
+ manager-strict = ( "On" | "Off" )
+
+ Default strict value is "Off" meaning that manager will disregard
+ all unknown parameters.
+
+
+5.2 ProtocolVersion
+
+ Current version of the MCMP protocol and manager
+
+ MCMP-Version ";" manager-version
+
+ Manager-version is read only property defined at compile time.
+
+
+5.3 ServerId
+
+ Unique id of the server where the Manager is running
+ ServerId is read only property defined at server statup.
+
+
+
+Turk, et. al. Standards Track [Page 33]
+
+RFC 5501 MCMP March 2008
Property changes on: sandbox/aloha/docs/rfc5501.txt
___________________________________________________________________
Name: svn:eol-style
+ native
16 years, 7 months