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 */
017
018 package org.apache.geronimo.console.configmanager;
019
020 import java.io.IOException;
021 import java.io.Serializable;
022 import java.net.URL;
023 import java.util.ArrayList;
024 import java.util.Collections;
025 import java.util.HashMap;
026 import java.util.Iterator;
027 import java.util.List;
028 import java.util.Map;
029 import java.util.Set;
030
031 import javax.enterprise.deploy.shared.ModuleType;
032 import javax.enterprise.deploy.spi.DeploymentManager;
033 import javax.enterprise.deploy.spi.Target;
034 import javax.enterprise.deploy.spi.TargetModuleID;
035 import javax.enterprise.deploy.spi.exceptions.TargetException;
036 import javax.portlet.ActionRequest;
037 import javax.portlet.ActionResponse;
038 import javax.portlet.PortletConfig;
039 import javax.portlet.PortletException;
040 import javax.portlet.PortletRequestDispatcher;
041 import javax.portlet.RenderRequest;
042 import javax.portlet.RenderResponse;
043 import javax.portlet.WindowState;
044
045 import org.apache.geronimo.common.DeploymentException;
046 import org.apache.geronimo.console.BasePortlet;
047 import org.apache.geronimo.console.util.PortletManager;
048 import org.apache.geronimo.deployment.plugin.TargetModuleIDImpl;
049 import org.apache.geronimo.gbean.AbstractName;
050 import org.apache.geronimo.gbean.AbstractNameQuery;
051 import org.apache.geronimo.kernel.DependencyManager;
052 import org.apache.geronimo.kernel.Kernel;
053 import org.apache.geronimo.kernel.KernelRegistry;
054 import org.apache.geronimo.kernel.config.Configuration;
055 import org.apache.geronimo.kernel.config.ConfigurationInfo;
056 import org.apache.geronimo.kernel.config.ConfigurationManager;
057 import org.apache.geronimo.kernel.config.ConfigurationModuleType;
058 import org.apache.geronimo.kernel.config.ConfigurationUtil;
059 import org.apache.geronimo.kernel.config.InvalidConfigException;
060 import org.apache.geronimo.kernel.config.LifecycleException;
061 import org.apache.geronimo.kernel.config.NoSuchConfigException;
062 import org.apache.geronimo.kernel.management.State;
063 import org.apache.geronimo.kernel.repository.Artifact;
064 import org.apache.geronimo.kernel.repository.MissingDependencyException;
065 import org.apache.geronimo.management.geronimo.WebModule;
066 import org.apache.geronimo.kernel.config.LifecycleResults;
067
068 public class ConfigManagerPortlet extends BasePortlet {
069
070 private static final String START_ACTION = "start";
071
072 private static final String STOP_ACTION = "stop";
073
074 private static final String RESTART_ACTION = "restart";
075
076 private static final String UNINSTALL_ACTION = "uninstall";
077
078 private static final String CONFIG_INIT_PARAM = "config-type";
079
080 private String messageStatus = "";
081
082 private Kernel kernel;
083
084 private PortletRequestDispatcher normalView;
085
086 private PortletRequestDispatcher maximizedView;
087
088 private PortletRequestDispatcher helpView;
089
090 private void printChilds(AbstractName config, int tab) {
091 messageStatus += "<br/>";
092 for (int i=0;i<tab;i++)
093 messageStatus += " ";
094 messageStatus +=config.toString();
095
096 DependencyManager depMgr = kernel.getDependencyManager();
097
098 java.util.Set children = depMgr.getChildren(config);
099 for (Iterator itr = children.iterator(); itr.hasNext(); ) {
100 AbstractName child = (AbstractName)itr.next();
101 //if(configManager.isConfiguration(child.getArtifact()))
102 if (child.getNameProperty("configurationName") != null) {
103 printChilds(child,tab+1);
104 }
105 }
106 }
107
108 public static List loadChildren(Kernel kernel, String configName) {
109 List kids = new ArrayList();
110
111 Map filter = new HashMap();
112 filter.put("J2EEApplication", configName);
113
114 filter.put("j2eeType", "WebModule");
115 Set test = kernel.listGBeans(new AbstractNameQuery(null, filter));
116 for (Iterator it = test.iterator(); it.hasNext();) {
117 AbstractName child = (AbstractName) it.next();
118 String childName = child.getNameProperty("name");
119 kids.add(childName);
120 }
121
122 filter.put("j2eeType", "EJBModule");
123 test = kernel.listGBeans(new AbstractNameQuery(null, filter));
124 for (Iterator it = test.iterator(); it.hasNext();) {
125 AbstractName child = (AbstractName) it.next();
126 String childName = child.getNameProperty("name");
127 kids.add(childName);
128 }
129
130 filter.put("j2eeType", "AppClientModule");
131 test = kernel.listGBeans(new AbstractNameQuery(null, filter));
132 for (Iterator it = test.iterator(); it.hasNext();) {
133 AbstractName child = (AbstractName) it.next();
134 String childName = child.getNameProperty("name");
135 kids.add(childName);
136 }
137
138 filter.put("j2eeType", "ResourceAdapterModule");
139 test = kernel.listGBeans(new AbstractNameQuery(null, filter));
140 for (Iterator it = test.iterator(); it.hasNext();) {
141 AbstractName child = (AbstractName) it.next();
142 String childName = child.getNameProperty("name");
143 kids.add(childName);
144 }
145 return kids;
146 }
147
148 public static boolean isWebApp(Kernel kernel, String configName) {
149 Map filter = new HashMap();
150 filter.put("j2eeType", "WebModule");
151 filter.put("name", configName);
152 Set set = kernel.listGBeans(new AbstractNameQuery(null, filter));
153 return set.size() > 0;
154 }
155
156 public void printResults(Set lcresult, String action) {
157
158 java.util.Iterator iterator= lcresult.iterator();
159 while (iterator.hasNext()) {
160 Artifact config = (Artifact)iterator.next();
161
162 //TODO might be a hack
163 List kidsChild = loadChildren(kernel, config.toString());
164
165 // Build a response obect containg the started configuration and a list of it's contained modules
166 TargetModuleIDImpl idChild = new TargetModuleIDImpl(null, config.toString(),
167 (String[]) kidsChild.toArray(new String[kidsChild.size()]));
168 if (isWebApp(kernel, config.toString())) {
169 idChild.setType(ModuleType.WAR);
170 }
171 if (idChild.getChildTargetModuleID() != null) {
172 for (int k = 0; k < idChild.getChildTargetModuleID().length; k++) {
173 TargetModuleIDImpl child = (TargetModuleIDImpl) idChild.getChildTargetModuleID()[k];
174 if (isWebApp(kernel, child.getModuleID())) {
175 child.setType(ModuleType.WAR);
176 }
177 }
178 }
179 messageStatus += " ";
180 messageStatus += idChild.getModuleID()+(idChild.getWebURL() == null || !action.equals(START_ACTION) ? "" : " @ "+idChild.getWebURL());
181 messageStatus += "<br />";
182 if (idChild.getChildTargetModuleID() != null) {
183 for (int j = 0; j < idChild.getChildTargetModuleID().length; j++) {
184 TargetModuleID child = idChild.getChildTargetModuleID()[j];
185 messageStatus += " `-> "+child.getModuleID()+(child.getWebURL() == null || !action.equals(START_ACTION) ? "" : " @ "+child.getWebURL());
186 messageStatus += "<br />";
187 }
188 }
189 messageStatus += "<br />";
190
191
192 }
193 }
194
195 public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException {
196 String action = actionRequest.getParameter("action");
197 actionResponse.setRenderParameter("message", ""); // set to blank first
198 try {
199 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel);
200 String config = getConfigID(actionRequest);
201 Artifact configId = Artifact.create(config);
202
203 if (START_ACTION.equals(action)) {
204 if(!configurationManager.isLoaded(configId)) {
205 configurationManager.loadConfiguration(configId);
206 }
207 if(!configurationManager.isRunning(configId)) {
208 org.apache.geronimo.kernel.config.LifecycleResults lcresult = configurationManager.startConfiguration(configId);
209 messageStatus = "Started application<br /><br />";
210 this.printResults(lcresult.getStarted(), action);
211 }
212 } else if (STOP_ACTION.equals(action)) {
213 if(configurationManager.isRunning(configId)) {
214 configurationManager.stopConfiguration(configId);
215 }
216 if(configurationManager.isLoaded(configId)) {
217 LifecycleResults lcresult = configurationManager.unloadConfiguration(configId);
218 messageStatus = "Stopped application<br /><br />";
219 this.printResults(lcresult.getUnloaded(), action);
220 }
221 } else if (UNINSTALL_ACTION.equals(action)) {
222 configurationManager.uninstallConfiguration(configId);
223 messageStatus = "Uninstalled application<br /><br />"+configId+"<br /><br />";
224 } else if (RESTART_ACTION.equals(action)) {
225 LifecycleResults lcresult = configurationManager.restartConfiguration(configId);
226 messageStatus = "Restarted application<br /><br />";
227 this.printResults(lcresult.getStarted(), START_ACTION);
228 } else {
229 messageStatus = "Invalid value for changeState: " + action + "<br /><br />";
230 throw new PortletException("Invalid value for changeState: " + action);
231 }
232 } catch (NoSuchConfigException e) {
233 // ignore this for now
234 messageStatus = "Configuration not found<br /><br />";
235 throw new PortletException("Configuration not found", e);
236 } catch (LifecycleException e) {
237 // todo we have a much more detailed report now
238 messageStatus = "Lifecycle operation failed<br /><br />";
239 throw new PortletException("Exception", e);
240 } catch (Exception e) {
241 messageStatus = "Encountered an unhandled exception<br /><br />";
242 throw new PortletException("Exception", e);
243 }
244 }
245
246 /**
247 * Check if a configuration should be listed here. This method depends on the "config-type" portlet parameter
248 * which is set in portle.xml.
249 */
250 private boolean shouldListConfig(ConfigurationInfo info) {
251 String configType = getInitParameter(CONFIG_INIT_PARAM);
252 return configType == null || info.getType().getName().equalsIgnoreCase(configType);
253 }
254
255 /*
256 * private URI getConfigID(ActionRequest actionRequest) throws
257 * PortletException { URI configID; try { configID = new
258 * URI(actionRequest.getParameter("configId")); } catch (URISyntaxException
259 * e) { throw new PortletException("Invalid configId parameter: " +
260 * actionRequest.getParameter("configId")); } return configID; }
261 */
262
263 private String getConfigID(ActionRequest actionRequest) {
264 return actionRequest.getParameter("configId");
265 }
266
267 protected void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException {
268 if (WindowState.MINIMIZED.equals(renderRequest.getWindowState())) {
269 return;
270 }
271
272 List moduleDetails = new ArrayList();
273 ConfigurationManager configManager = ConfigurationUtil.getConfigurationManager(kernel);
274 DependencyManager depMgr = kernel.getDependencyManager();
275 List infos = configManager.listConfigurations();
276 for (Iterator j = infos.iterator(); j.hasNext();) {
277 ConfigurationInfo info = (ConfigurationInfo) j.next();
278 if (shouldListConfig(info)) {
279 ModuleDetails details = new ModuleDetails(info.getConfigID(), info.getType(), info.getState());
280
281 if (info.getType().getValue()== ConfigurationModuleType.WAR.getValue()){
282 WebModule webModule = (WebModule) PortletManager.getModule(renderRequest, info.getConfigID());
283 if (webModule != null) {
284 details.setContextPath(webModule.getContextPath());
285 }
286 }
287 try {
288 AbstractName configObjName = Configuration.getConfigurationAbstractName(info.getConfigID());
289 boolean flag = false;
290 // Check if the configuration is loaded. If not, load it to get information.
291 if(!kernel.isLoaded(configObjName)) {
292 try {
293 configManager.loadConfiguration(configObjName.getArtifact());
294 flag = true;
295 } catch (NoSuchConfigException e) {
296 // Should not occur
297 e.printStackTrace();
298 } catch (LifecycleException e) {
299 // config could not load because one or more of its dependencies
300 // has been removed. cannot load the configuration in this case,
301 // so don't rely on that technique to discover its parents or children
302 if (e.getCause() instanceof MissingDependencyException) {
303 // do nothing
304 } else {
305 e.printStackTrace();
306 }
307 }
308 }
309
310 java.util.Set parents = depMgr.getParents(configObjName);
311 for(Iterator itr = parents.iterator(); itr.hasNext(); ) {
312 AbstractName parent = (AbstractName)itr.next();
313 details.getParents().add(parent.getArtifact());
314 }
315 java.util.Set children = depMgr.getChildren(configObjName);
316 for(Iterator itr = children.iterator(); itr.hasNext(); ) {
317 AbstractName child = (AbstractName)itr.next();
318 //if(configManager.isConfiguration(child.getArtifact()))
319 if(child.getNameProperty("configurationName") != null) {
320 details.getChildren().add(child.getArtifact());
321 }
322 }
323 Collections.sort(details.getParents());
324 Collections.sort(details.getChildren());
325
326 // Unload the configuration if it has been loaded earlier for the sake of getting information
327 if(flag) {
328 try {
329 configManager.unloadConfiguration(configObjName.getArtifact());
330 } catch (NoSuchConfigException e) {
331 // Should not occur
332 e.printStackTrace();
333 }
334 }
335 } catch(InvalidConfigException ice) {
336 // Should not occur
337 ice.printStackTrace();
338 }
339 moduleDetails.add(details);
340 }
341 }
342 Collections.sort(moduleDetails);
343 renderRequest.setAttribute("configurations", moduleDetails);
344 renderRequest.setAttribute("showWebInfo", Boolean.valueOf(getInitParameter(CONFIG_INIT_PARAM).equalsIgnoreCase(ConfigurationModuleType.WAR.getName())));
345 if (moduleDetails.size() == 0) {
346 renderRequest.setAttribute("messageInstalled", "No modules found of this type<br /><br />");
347 } else {
348 renderRequest.setAttribute("messageInstalled", "");
349 }
350 renderRequest.setAttribute("messageStatus", messageStatus);
351 messageStatus = "";
352 if (WindowState.NORMAL.equals(renderRequest.getWindowState())) {
353 normalView.include(renderRequest, renderResponse);
354 } else {
355 maximizedView.include(renderRequest, renderResponse);
356 }
357 }
358
359 protected void doHelp(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException, IOException {
360 helpView.include(renderRequest, renderResponse);
361 }
362
363 public void init(PortletConfig portletConfig) throws PortletException {
364 super.init(portletConfig);
365 kernel = KernelRegistry.getSingleKernel();
366 normalView = portletConfig.getPortletContext().getRequestDispatcher("/WEB-INF/view/configmanager/normal.jsp");
367 maximizedView = portletConfig.getPortletContext().getRequestDispatcher("/WEB-INF/view/configmanager/maximized.jsp");
368 helpView = portletConfig.getPortletContext().getRequestDispatcher("/WEB-INF/view/configmanager/help.jsp");
369 }
370
371 public void destroy() {
372 normalView = null;
373 maximizedView = null;
374 kernel = null;
375 super.destroy();
376 }
377
378 /**
379 * Convenience data holder for portlet that displays deployed modules.
380 * Includes context path information for web modules.
381 */
382 public static class ModuleDetails implements Comparable, Serializable {
383 private final Artifact configId;
384 private final ConfigurationModuleType type;
385 private final State state;
386 private String contextPath; // only relevant for webapps
387 private List parents = new ArrayList();
388 private List children = new ArrayList();
389
390 public ModuleDetails(Artifact configId, ConfigurationModuleType type, State state) {
391 this.configId = configId;
392 this.type = type;
393 this.state = state;
394 }
395
396 public ModuleDetails(Artifact configId, ConfigurationModuleType type, State state, List parents, List children) {
397 this.configId = configId;
398 this.type = type;
399 this.state = state;
400 this.parents = parents;
401 this.children = children;
402 }
403
404 public int compareTo(Object o) {
405 if (o != null && o instanceof ModuleDetails){
406 return configId.compareTo(((ModuleDetails)o).configId);
407 } else {
408 return -1;
409 }
410 }
411
412 public Artifact getConfigId() {
413 return configId;
414 }
415
416 public State getState() {
417 return state;
418 }
419
420 public String getContextPath() {
421 return contextPath;
422 }
423
424 public void setContextPath(String contextPath) {
425 this.contextPath = contextPath;
426 }
427
428 public ConfigurationModuleType getType() {
429 return type;
430 }
431
432 public List getParents() {
433 return parents;
434 }
435
436 public List getChildren() {
437 return children;
438 }
439 }
440 }