001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.console.configmanager;
017:
018: import java.io.IOException;
019: import java.io.Serializable;
020: import java.util.ArrayList;
021: import java.util.Collections;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Set;
027:
028: import javax.portlet.ActionRequest;
029: import javax.portlet.ActionResponse;
030: import javax.portlet.PortletConfig;
031: import javax.portlet.PortletException;
032: import javax.portlet.PortletRequestDispatcher;
033: import javax.portlet.RenderRequest;
034: import javax.portlet.RenderResponse;
035: import javax.portlet.WindowState;
036:
037: import org.apache.geronimo.console.BasePortlet;
038: import org.apache.geronimo.console.util.PortletManager;
039: import org.apache.geronimo.gbean.AbstractName;
040: import org.apache.geronimo.gbean.AbstractNameQuery;
041: import org.apache.geronimo.kernel.DependencyManager;
042: import org.apache.geronimo.kernel.Kernel;
043: import org.apache.geronimo.kernel.KernelRegistry;
044: import org.apache.geronimo.kernel.config.Configuration;
045: import org.apache.geronimo.kernel.config.ConfigurationInfo;
046: import org.apache.geronimo.kernel.config.ConfigurationManager;
047: import org.apache.geronimo.kernel.config.ConfigurationModuleType;
048: import org.apache.geronimo.kernel.config.ConfigurationUtil;
049: import org.apache.geronimo.kernel.config.InvalidConfigException;
050: import org.apache.geronimo.kernel.config.LifecycleException;
051: import org.apache.geronimo.kernel.config.LifecycleResults;
052: import org.apache.geronimo.kernel.config.NoSuchConfigException;
053: import org.apache.geronimo.kernel.management.State;
054: import org.apache.geronimo.kernel.repository.Artifact;
055: import org.apache.geronimo.kernel.repository.MissingDependencyException;
056: import org.apache.geronimo.management.geronimo.WebModule;
057:
058: public class ConfigManagerPortlet extends BasePortlet {
059:
060: private static final String START_ACTION = "start";
061:
062: private static final String STOP_ACTION = "stop";
063:
064: private static final String RESTART_ACTION = "restart";
065:
066: private static final String UNINSTALL_ACTION = "uninstall";
067:
068: private static final String CONFIG_INIT_PARAM = "config-type";
069:
070: private Kernel kernel;
071:
072: private PortletRequestDispatcher normalView;
073:
074: private PortletRequestDispatcher maximizedView;
075:
076: private PortletRequestDispatcher helpView;
077:
078: private static List loadChildren(Kernel kernel, String configName) {
079: List<String> kids = new ArrayList<String>();
080:
081: Map<String, String> filter = new HashMap<String, String>();
082: filter.put("J2EEApplication", configName);
083: filter.put("j2eeType", "WebModule");
084:
085: Set<AbstractName> test = kernel
086: .listGBeans(new AbstractNameQuery(null, filter));
087: for (AbstractName child : test) {
088: String childName = child.getNameProperty("name");
089: kids.add(childName);
090: }
091:
092: filter.put("j2eeType", "EJBModule");
093: test = kernel.listGBeans(new AbstractNameQuery(null, filter));
094: for (AbstractName child : test) {
095: String childName = child.getNameProperty("name");
096: kids.add(childName);
097: }
098:
099: filter.put("j2eeType", "AppClientModule");
100: test = kernel.listGBeans(new AbstractNameQuery(null, filter));
101: for (AbstractName child : test) {
102: String childName = child.getNameProperty("name");
103: kids.add(childName);
104: }
105:
106: filter.put("j2eeType", "ResourceAdapterModule");
107: test = kernel.listGBeans(new AbstractNameQuery(null, filter));
108: for (AbstractName child : test) {
109: String childName = child.getNameProperty("name");
110: kids.add(childName);
111: }
112: return kids;
113: }
114:
115: public void printResults(Set<Artifact> lcresult, StringBuffer buf) {
116: for (Artifact config : lcresult) {
117:
118: //TODO might be a hack
119: List<String> kidsChild = loadChildren(kernel, config
120: .toString());
121:
122: //TODO figure out the web url and show it when appropriate.
123: buf.append(" ").append(config).append("<br />");
124: for (String kid : kidsChild) {
125: buf.append(" `-> ").append(kid).append("<br />");
126: }
127: buf.append("<br />");
128: }
129: }
130:
131: public void processAction(ActionRequest actionRequest,
132: ActionResponse actionResponse) throws PortletException,
133: IOException {
134: String action = actionRequest.getParameter("action");
135: actionResponse.setRenderParameter("message", ""); // set to blank first
136: try {
137: ConfigurationManager configurationManager = ConfigurationUtil
138: .getConfigurationManager(kernel);
139: String config = getConfigID(actionRequest);
140: Artifact configId = Artifact.create(config);
141:
142: if (START_ACTION.equals(action)) {
143: if (!configurationManager.isLoaded(configId)) {
144: configurationManager.loadConfiguration(configId);
145: }
146: if (!configurationManager.isRunning(configId)) {
147: org.apache.geronimo.kernel.config.LifecycleResults lcresult = configurationManager
148: .startConfiguration(configId);
149: message(actionResponse, lcresult,
150: "Started application<br /><br />");
151: }
152: } else if (STOP_ACTION.equals(action)) {
153: if (configurationManager.isRunning(configId)) {
154: configurationManager.stopConfiguration(configId);
155: }
156: if (configurationManager.isLoaded(configId)) {
157: LifecycleResults lcresult = configurationManager
158: .unloadConfiguration(configId);
159: message(actionResponse, lcresult,
160: "Stopped application<br /><br />");
161: }
162: } else if (UNINSTALL_ACTION.equals(action)) {
163: configurationManager.uninstallConfiguration(configId);
164: message(actionResponse, null,
165: "Uninstalled application<br /><br />"
166: + configId + "<br /><br />");
167: } else if (RESTART_ACTION.equals(action)) {
168: LifecycleResults lcresult = configurationManager
169: .restartConfiguration(configId);
170: message(actionResponse, lcresult,
171: "Restarted application<br /><br />");
172: } else {
173: message(actionResponse, null,
174: "Invalid value for changeState: " + action
175: + "<br /><br />");
176: throw new PortletException(
177: "Invalid value for changeState: " + action);
178: }
179: } catch (NoSuchConfigException e) {
180: // ignore this for now
181: message(actionResponse, null,
182: "Configuration not found<br /><br />");
183: throw new PortletException("Configuration not found", e);
184: } catch (LifecycleException e) {
185: // todo we have a much more detailed report now
186: message(actionResponse, null,
187: "Lifecycle operation failed<br /><br />");
188: throw new PortletException("Exception", e);
189: } catch (Exception e) {
190: message(actionResponse, null,
191: "Encountered an unhandled exception<br /><br />");
192: throw new PortletException("Exception", e);
193: }
194: }
195:
196: private void message(ActionResponse actionResponse,
197: LifecycleResults lcresult, String str) {
198: StringBuffer buf = new StringBuffer(str);
199: if (lcresult != null) {
200: this .printResults(lcresult.getStarted(), buf);
201: }
202: actionResponse.setRenderParameter("messageStatus", buf
203: .toString());
204: }
205:
206: /**
207: * Check if a configuration should be listed here. This method depends on the "config-type" portlet parameter
208: * which is set in portle.xml.
209: */
210: private boolean shouldListConfig(ConfigurationModuleType info) {
211: String configType = getInitParameter(CONFIG_INIT_PARAM);
212: return configType == null
213: || info.getName().equalsIgnoreCase(configType);
214: }
215:
216: private String getConfigID(ActionRequest actionRequest) {
217: return actionRequest.getParameter("configId");
218: }
219:
220: protected void doView(RenderRequest renderRequest,
221: RenderResponse renderResponse) throws IOException,
222: PortletException {
223: if (WindowState.MINIMIZED
224: .equals(renderRequest.getWindowState())) {
225: return;
226: }
227:
228: List<ModuleDetails> moduleDetails = new ArrayList<ModuleDetails>();
229: ConfigurationManager configManager = ConfigurationUtil
230: .getConfigurationManager(kernel);
231: List<ConfigurationInfo> infos = configManager
232: .listConfigurations();
233: for (ConfigurationInfo info : infos) {
234:
235: String moduleType = getInitParameter(CONFIG_INIT_PARAM);
236: if (ConfigurationModuleType.WAR.getName().equalsIgnoreCase(
237: moduleType)) {
238:
239: if (info.getType().getValue() == ConfigurationModuleType.WAR
240: .getValue()) {
241: ModuleDetails details = new ModuleDetails(info
242: .getConfigID(), info.getType(), info
243: .getState());
244: try {
245: AbstractName configObjName = Configuration
246: .getConfigurationAbstractName(info
247: .getConfigID());
248: boolean loaded = loadModule(configManager,
249: configObjName);
250:
251: WebModule webModule = (WebModule) PortletManager
252: .getModule(renderRequest, info
253: .getConfigID());
254: if (webModule != null) {
255: details.getContextPaths().add(
256: webModule.getContextPath());
257: }
258:
259: addDependencies(details, configObjName);
260: if (loaded) {
261: unloadModule(configManager, configObjName);
262: }
263: } catch (InvalidConfigException ice) {
264: // Should not occur
265: ice.printStackTrace();
266: }
267: moduleDetails.add(details);
268: } else if (info.getType().getValue() == ConfigurationModuleType.EAR
269: .getValue()) {
270: try {
271: AbstractName configObjName = Configuration
272: .getConfigurationAbstractName(info
273: .getConfigID());
274: boolean loaded = loadModule(configManager,
275: configObjName);
276:
277: Configuration config = configManager
278: .getConfiguration(info.getConfigID());
279: for (Configuration child : config.getChildren()) {
280: if (child.getModuleType().getValue() == ConfigurationModuleType.WAR
281: .getValue()) {
282: ModuleDetails childDetails = new ModuleDetails(
283: info.getConfigID(), child
284: .getModuleType(), info
285: .getState());
286: childDetails.setComponentName(child
287: .getId().toString());
288: WebModule webModule = getWebModule(
289: config, child);
290: if (webModule != null) {
291: childDetails.getContextPaths().add(
292: webModule.getContextPath());
293: }
294: addDependencies(childDetails,
295: configObjName);
296: moduleDetails.add(childDetails);
297: }
298: }
299:
300: if (loaded) {
301: unloadModule(configManager, configObjName);
302: }
303: } catch (InvalidConfigException ice) {
304: // Should not occur
305: ice.printStackTrace();
306: }
307: }
308:
309: } else if (shouldListConfig(info.getType())) {
310: ModuleDetails details = new ModuleDetails(info
311: .getConfigID(), info.getType(), info.getState());
312: try {
313: AbstractName configObjName = Configuration
314: .getConfigurationAbstractName(info
315: .getConfigID());
316: boolean loaded = loadModule(configManager,
317: configObjName);
318:
319: if (info.getType().getValue() == ConfigurationModuleType.EAR
320: .getValue()) {
321: Configuration config = configManager
322: .getConfiguration(info.getConfigID());
323: Iterator childs = config.getChildren()
324: .iterator();
325: while (childs.hasNext()) {
326: Configuration child = (Configuration) childs
327: .next();
328: if (child.getModuleType().getValue() == ConfigurationModuleType.WAR
329: .getValue()) {
330: WebModule webModule = getWebModule(
331: config, child);
332: if (webModule != null) {
333: details.getContextPaths().add(
334: webModule.getContextPath());
335: }
336: }
337: }
338: }
339:
340: addDependencies(details, configObjName);
341: if (loaded) {
342: unloadModule(configManager, configObjName);
343: }
344: } catch (InvalidConfigException ice) {
345: // Should not occur
346: ice.printStackTrace();
347: }
348: moduleDetails.add(details);
349: }
350: }
351: Collections.sort(moduleDetails);
352: renderRequest.setAttribute("configurations", moduleDetails);
353: renderRequest.setAttribute("showWebInfo", Boolean
354: .valueOf(showWebInfo()));
355: if (moduleDetails.size() == 0) {
356: renderRequest.setAttribute("messageInstalled",
357: "No modules found of this type<br /><br />");
358: } else {
359: renderRequest.setAttribute("messageInstalled", "");
360: }
361: renderRequest.setAttribute("messageStatus", renderRequest
362: .getParameter("messageStatus"));
363: if (WindowState.NORMAL.equals(renderRequest.getWindowState())) {
364: normalView.include(renderRequest, renderResponse);
365: } else {
366: maximizedView.include(renderRequest, renderResponse);
367: }
368: }
369:
370: private WebModule getWebModule(Configuration config,
371: Configuration child) {
372: try {
373: Map<String, String> query1 = new HashMap<String, String>();
374: String name = config.getId().getArtifactId();
375: query1.put("J2EEApplication", config.getId().toString());
376: query1.put("j2eeType", "WebModule");
377: query1.put("name", child.getId().getArtifactId().substring(
378: name.length() + 1));
379: AbstractName childName = new AbstractName(config
380: .getAbstractName().getArtifact(), query1);
381: return (WebModule) kernel.getGBean(childName);
382: } catch (Exception h) {
383: // No gbean found, will not happen
384: // Except if module not started, ignored
385: }
386: return null;
387: }
388:
389: private boolean loadModule(ConfigurationManager configManager,
390: AbstractName configObjName) {
391: if (!kernel.isLoaded(configObjName)) {
392: try {
393: configManager.loadConfiguration(configObjName
394: .getArtifact());
395: return true;
396: } catch (NoSuchConfigException e) {
397: // Should not occur
398: e.printStackTrace();
399: } catch (LifecycleException e) {
400: // config could not load because one or more of its dependencies
401: // has been removed. cannot load the configuration in this case,
402: // so don't rely on that technique to discover its parents or children
403: if (e.getCause() instanceof MissingDependencyException) {
404: // do nothing
405: } else {
406: e.printStackTrace();
407: }
408: }
409: }
410: return false;
411: }
412:
413: private void addDependencies(ModuleDetails details,
414: AbstractName configObjName) {
415: DependencyManager depMgr = kernel.getDependencyManager();
416: Set<AbstractName> parents = depMgr.getParents(configObjName);
417: for (AbstractName parent : parents) {
418: details.getParents().add(parent.getArtifact());
419: }
420: Set<AbstractName> children = depMgr.getChildren(configObjName);
421: for (AbstractName child : children) {
422: //if(configManager.isConfiguration(child.getArtifact()))
423: if (child.getNameProperty("configurationName") != null) {
424: details.getChildren().add(child.getArtifact());
425: }
426: }
427: Collections.sort(details.getParents());
428: Collections.sort(details.getChildren());
429: }
430:
431: private void unloadModule(ConfigurationManager configManager,
432: AbstractName configObjName) {
433: try {
434: configManager.unloadConfiguration(configObjName
435: .getArtifact());
436: } catch (NoSuchConfigException e) {
437: // Should not occur
438: e.printStackTrace();
439: }
440: }
441:
442: private boolean showWebInfo() {
443: String moduleType = getInitParameter(CONFIG_INIT_PARAM);
444: return ConfigurationModuleType.WAR.getName().equalsIgnoreCase(
445: moduleType)
446: || ConfigurationModuleType.EAR.getName()
447: .equalsIgnoreCase(moduleType);
448: }
449:
450: protected void doHelp(RenderRequest renderRequest,
451: RenderResponse renderResponse) throws PortletException,
452: IOException {
453: helpView.include(renderRequest, renderResponse);
454: }
455:
456: public void init(PortletConfig portletConfig)
457: throws PortletException {
458: super .init(portletConfig);
459: kernel = KernelRegistry.getSingleKernel();
460: normalView = portletConfig.getPortletContext()
461: .getRequestDispatcher(
462: "/WEB-INF/view/configmanager/normal.jsp");
463: maximizedView = portletConfig.getPortletContext()
464: .getRequestDispatcher(
465: "/WEB-INF/view/configmanager/maximized.jsp");
466: helpView = portletConfig.getPortletContext()
467: .getRequestDispatcher(
468: "/WEB-INF/view/configmanager/help.jsp");
469: }
470:
471: public void destroy() {
472: normalView = null;
473: maximizedView = null;
474: kernel = null;
475: super .destroy();
476: }
477:
478: /**
479: * Convenience data holder for portlet that displays deployed modules.
480: * Includes context path information for web modules.
481: */
482: public static class ModuleDetails implements Comparable,
483: Serializable {
484: private static final long serialVersionUID = -7022687152297202079L;
485: private final Artifact configId;
486: private final ConfigurationModuleType type;
487: private final State state;
488: private List<Artifact> parents = new ArrayList<Artifact>();
489: private List<Artifact> children = new ArrayList<Artifact>();
490: private boolean expertConfig = false; // used to mark this config as one that should only be managed (stop/uninstall) by expert users.
491: private List<String> contextPaths = new ArrayList<String>();
492: private String componentName;
493:
494: public ModuleDetails(Artifact configId,
495: ConfigurationModuleType type, State state) {
496: this .configId = configId;
497: this .type = type;
498: this .state = state;
499: if (configId.toString().indexOf(
500: "org.apache.geronimo.configs/") == 0) {
501: this .expertConfig = true;
502: }
503: }
504:
505: public int compareTo(Object o) {
506: if (o != null && o instanceof ModuleDetails) {
507: return configId.compareTo(((ModuleDetails) o).configId);
508: } else {
509: return -1;
510: }
511: }
512:
513: public Artifact getConfigId() {
514: return configId;
515: }
516:
517: public State getState() {
518: return state;
519: }
520:
521: public ConfigurationModuleType getType() {
522: return type;
523: }
524:
525: public boolean getExpertConfig() {
526: return expertConfig;
527: }
528:
529: public List<Artifact> getParents() {
530: return parents;
531: }
532:
533: public List<Artifact> getChildren() {
534: return children;
535: }
536:
537: public List<String> getContextPaths() {
538: return contextPaths;
539: }
540:
541: public String getComponentName() {
542: return componentName;
543: }
544:
545: public void setComponentName(String name) {
546: componentName = name;
547: }
548: }
549: }
|