001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.jmx.adaptor.html;
023:
024: import java.io.IOException;
025: import java.io.StringReader;
026: import java.io.BufferedReader;
027: import java.util.Properties;
028: import java.util.Vector;
029: import java.util.Enumeration;
030: import javax.servlet.http.HttpServlet;
031: import javax.servlet.http.HttpServletRequest;
032: import javax.servlet.http.HttpServletResponse;
033: import javax.servlet.ServletConfig;
034: import javax.servlet.ServletException;
035: import javax.servlet.RequestDispatcher;
036: import javax.naming.InitialContext;
037: import javax.naming.Context;
038: import javax.naming.NamingException;
039: import javax.naming.NamingEnumeration;
040: import javax.naming.NameClassPair;
041: import javax.management.ObjectName;
042:
043: import org.jboss.ha.framework.interfaces.HAPartition;
044: import org.jboss.jmx.adaptor.control.AddressPort;
045: import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
046: import org.jboss.logging.Logger;
047: import org.jnp.interfaces.NamingContext;
048:
049: /** A servlet that provides the cluster view bootstrap index for the
050: * jmx-console cluster frame.
051: *
052: * @author Scott.Stark@jboss.org
053: * @version $Revision: 57210 $
054: */
055: public class ClusteredConsoleServlet extends HttpServlet {
056: private static Logger log = Logger
057: .getLogger(ClusteredConsoleServlet.class);
058:
059: private static final String ACTION_PARAM = "action";
060: private static final String CLUSTER_BOOTSTRAP_ACTION = "bootstrap";
061: private static final String CLUSTER_INDEX_ACTION = "index";
062:
063: private static final String BOOTSTRAP_PARAM = "bootstrap";
064: private static final String PARTITION_PARAM = "partition";
065: private static final String HOSTNAME_PARAM = "hostname";
066: private static final String PORT_PARAM = "port";
067: private static final String DISCOVERY_GROUP_PARAM = "discoveryGroup";
068: private static final String DISCOVERY_TIMEOUT_PARAM = "discoveryTimeout";
069:
070: private String jgProps;
071:
072: /** Creates a new instance of HtmlAdaptor */
073: public ClusteredConsoleServlet() {
074: }
075:
076: public void init(ServletConfig config) throws ServletException {
077: super .init(config);
078:
079: jgProps = config.getInitParameter("jgProps");
080: if (jgProps == null)
081: throw new ServletException(
082: "No jgProps init-param specified");
083: StringBuffer trimedProps = new StringBuffer();
084: StringReader sr = new StringReader(jgProps);
085: BufferedReader br = new BufferedReader(sr);
086: String protocol = null;
087: try {
088: while ((protocol = br.readLine()) != null)
089: trimedProps.append(protocol.trim());
090: } catch (IOException e) {
091: throw new ServletException("Failed to process jgProps", e);
092: }
093: jgProps = trimedProps.toString();
094: log.debug("Using jbPropgs: " + jgProps);
095: }
096:
097: public void destroy() {
098: }
099:
100: protected void doGet(HttpServletRequest request,
101: HttpServletResponse response) throws ServletException,
102: IOException {
103: processRequest(request, response);
104: }
105:
106: protected void doPost(HttpServletRequest request,
107: HttpServletResponse response) throws ServletException,
108: IOException {
109: processRequest(request, response);
110: }
111:
112: protected void processRequest(HttpServletRequest request,
113: HttpServletResponse response) throws ServletException,
114: IOException {
115: String action = request.getParameter(ACTION_PARAM);
116:
117: if (action == null)
118: action = CLUSTER_INDEX_ACTION;
119:
120: if (action.equals(CLUSTER_INDEX_ACTION))
121: clusterIndex(request, response);
122: else if (action.equals(CLUSTER_BOOTSTRAP_ACTION))
123: clusterBootstrap(request, response);
124: }
125:
126: /** cluster index view
127: */
128: private void clusterIndex(HttpServletRequest request,
129: HttpServletResponse response) throws ServletException,
130: IOException {
131: try {
132: // Query for the membership of the partition cluster
133: String[] hosts = {};
134: request.setAttribute("partition", "none");
135: request.setAttribute("partitionHosts", hosts);
136: RequestDispatcher rd = this .getServletContext()
137: .getRequestDispatcher("/cluster/clusterView.jsp");
138: rd.forward(request, response);
139: } catch (Exception e) {
140: log.debug("Failed to get partition view", e);
141: response.sendError(HttpServletResponse.SC_NO_CONTENT,
142: "No partition view found");
143: }
144: }
145:
146: /** bootstrap cluster node view
147: */
148: private void clusterBootstrap(HttpServletRequest request,
149: HttpServletResponse response) throws ServletException,
150: IOException {
151: String bootstrap = request.getParameter(BOOTSTRAP_PARAM);
152: log.debug("processRequest, parameters:");
153: Enumeration params = request.getParameterNames();
154: while (params.hasMoreElements()) {
155: String name = (String) params.nextElement();
156: log.debug(name + "=" + request.getParameter(name));
157: }
158:
159: if (bootstrap == null)
160: bootstrap = "discovery";
161: String hostname = request.getParameter(HOSTNAME_PARAM);
162: if (hostname == null || hostname.equalsIgnoreCase("localhost"))
163: hostname = request.getServerName();
164: String partition = request.getParameter(PARTITION_PARAM);
165: String port = request.getParameter(PORT_PARAM);
166: String discoveryGroup = request
167: .getParameter(DISCOVERY_GROUP_PARAM);
168: String discoveryTimeout = request
169: .getParameter(DISCOVERY_TIMEOUT_PARAM);
170:
171: log.debug("bootstrap: " + bootstrap);
172: String[] hosts = {};
173: Properties env = new Properties();
174: try {
175: if (bootstrap.equals("discovery")) {
176: if (partition != null && partition.length() > 0)
177: env.setProperty(NamingContext.JNP_PARTITION_NAME,
178: partition);
179: if (port != null && port.length() > 0)
180: env.setProperty(NamingContext.JNP_DISCOVERY_PORT,
181: port);
182: if (discoveryGroup != null
183: && discoveryGroup.length() > 0)
184: env.setProperty(NamingContext.JNP_DISCOVERY_GROUP,
185: discoveryGroup);
186: if (discoveryTimeout != null
187: && discoveryTimeout.length() > 0)
188: env.setProperty(
189: NamingContext.JNP_DISCOVERY_TIMEOUT,
190: discoveryTimeout);
191: hosts = discoverHosts(env);
192: } else if (bootstrap.equals("byhost")) {
193: queryHost(hostname, port, env);
194: } else {
195: throw new ServletException(
196: "Unkown bootstrap mode specified: " + bootstrap);
197: }
198: } catch (Exception e) {
199: throw new ServletException("Failed to bootstrap hosts", e);
200: }
201:
202: try {
203: // Query for the membership of the partition cluster
204: partition = env
205: .getProperty(NamingContext.JNP_PARTITION_NAME);
206: request.setAttribute("partition", partition);
207: request.setAttribute("partitionHosts", hosts);
208: RequestDispatcher rd = this .getServletContext()
209: .getRequestDispatcher("/cluster/clusterView.jsp");
210: rd.forward(request, response);
211: } catch (Exception e) {
212: log.debug("Failed to get partition view", e);
213: response.sendError(HttpServletResponse.SC_NO_CONTENT,
214: "No partition view found");
215: }
216: }
217:
218: private String[] discoverHosts(Properties env)
219: throws NamingException, IOException {
220: env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
221: "org.jnp.interfaces.NamingContextFactory");
222:
223: String[] hosts = {};
224: log.debug("Querying HAJNDI: " + env);
225: InitialContext ctx = new InitialContext(env);
226: String partitionName = env
227: .getProperty(NamingContext.JNP_PARTITION_NAME);
228: if (partitionName != null) {
229: String partitionJndiName = "/HAPartition/" + partitionName;
230: HAPartition partition = (HAPartition) ctx
231: .lookup(partitionJndiName);
232: Vector view = partition.getCurrentView();
233: log.debug("Found HAPartition: " + partitionName);
234: hosts = new String[view.size()];
235: for (int v = 0; v < view.size(); v++) {
236: Object addr = view.get(v);
237: log.debug(addr);
238: hosts[v] = addr.toString();
239: }
240: } else {
241: NamingEnumeration iter = ctx.list("/HAPartition");
242: while (iter.hasMore()) {
243: NameClassPair pair = (NameClassPair) iter.next();
244: partitionName = pair.getName();
245: String partitionJndiName = "/HAPartition/"
246: + partitionName;
247: HAPartition partition = (HAPartition) ctx
248: .lookup(partitionJndiName);
249: env.setProperty(NamingContext.JNP_PARTITION_NAME,
250: partitionName);
251: Vector view = partition.getCurrentView();
252: log.debug("Found HAPartition: " + partitionName);
253: hosts = new String[view.size()];
254: for (int v = 0; v < view.size(); v++) {
255: Object addr = view.get(v);
256: AddressPort ap = AddressPort.getMemberAddress(addr);
257: log.debug(ap);
258: hosts[v] = ap.getHostAddress();
259: }
260: break;
261: }
262: }
263:
264: return hosts;
265: }
266:
267: private String[] queryHost(String hostname, String port,
268: Properties env) throws Exception {
269: String[] hosts = {};
270: env.setProperty(Context.INITIAL_CONTEXT_FACTORY,
271: "org.jnp.interfaces.NamingContextFactory");
272: env.setProperty(Context.PROVIDER_URL, hostname + ":" + port);
273: InitialContext ctx = new InitialContext(env);
274: NamingEnumeration iter = ctx.list("/HAPartition");
275: String partitionName = null;
276: while (iter.hasMore()) {
277: NameClassPair pair = (NameClassPair) iter.next();
278: partitionName = pair.getName();
279: break;
280: }
281: if (partitionName == null)
282: throw new NamingException("Failed to find any parition");
283: env
284: .setProperty(NamingContext.JNP_PARTITION_NAME,
285: partitionName);
286:
287: RMIAdaptor adaptor = (RMIAdaptor) ctx
288: .lookup("jmx/rmi/RMIAdaptor");
289: ObjectName clusterPartition = new ObjectName("jboss:service="
290: + partitionName);
291: Vector view = (Vector) adaptor.getAttribute(clusterPartition,
292: "CurrentView");
293: log.debug("Found ClusterPartition: " + clusterPartition);
294: hosts = new String[view.size()];
295: for (int v = 0; v < view.size(); v++) {
296: Object addr = view.get(v);
297: AddressPort ap = AddressPort.getMemberAddress(addr);
298: log.debug(ap);
299: hosts[v] = ap.getHostAddress();
300: }
301: return hosts;
302: }
303: }
|