/* * Copyright 2011 the original author or authors. * * 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. */ package org.rioproject.monitor.service; import net.jini.config.Configuration; import net.jini.id.Uuid; import org.rioproject.deploy.DeployAdmin; import org.rioproject.deploy.ServiceBeanInstance; import org.rioproject.deploy.ServiceProvisionListener; import org.rioproject.monitor.ProvisionMonitor; import org.rioproject.monitor.ProvisionMonitorEvent; import org.rioproject.monitor.service.peer.ProvisionMonitorPeer; import org.rioproject.monitor.service.persistence.StateManager; import org.rioproject.opstring.OperationalString; import org.rioproject.opstring.OperationalStringException; import org.rioproject.opstring.OperationalStringManager; import org.rioproject.opstring.ServiceElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.rmi.RemoteException; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; /** * This class manages interactions with {@link OpStringManager} classes. */ public class OpStringManagerController { /** * Collection for all OperationalString OpStringManager instances */ private ProvisionMonitorPeer provisionMonitorPeer; private Configuration config; private ProvisionMonitor serviceProxy; private ProvisionMonitorEventProcessor eventProcessor; private StateManager stateManager; private ServiceProvisioner serviceProvisioner; private Uuid uuid; private static Logger logger = LoggerFactory.getLogger(OpStringManagerController.class.getName()); private DeploymentVerifier deploymentVerifier; private final ConcurrentHashMap<String, OpStringManager> opStringManagerTable = new ConcurrentHashMap<String, OpStringManager>(); void setServiceProvisioner(final ServiceProvisioner serviceProvisioner) { this.serviceProvisioner = serviceProvisioner; } void setUuid(Uuid uuid) { this.uuid = uuid; } void setEventProcessor(final ProvisionMonitorEventProcessor eventProcessor) { this.eventProcessor = eventProcessor; } void setServiceProxy(final ProvisionMonitor serviceProxy) { this.serviceProxy = serviceProxy; } void setProvisionMonitorPeer(final ProvisionMonitorPeer provisionMonitorPeer) { this.provisionMonitorPeer = provisionMonitorPeer; } void setConfig(final Configuration config) { this.config = config; } void setStateManager(final StateManager stateManager) { this.stateManager = stateManager; } public DeploymentVerifier getDeploymentVerifier() { return deploymentVerifier; } public void setDeploymentVerifier(DeploymentVerifier deploymentVerifier) { this.deploymentVerifier = deploymentVerifier; } public void undeploy(final OpStringManager opStringManager, final boolean terminate) { opStringManager.setDeploymentStatus(OperationalString.UNDEPLOYED); OperationalString opString = opStringManager.doGetOperationalString(); logger.trace("Terminating Operational String [{}]", opString.getName()); OperationalString[] terminated = opStringManager.terminate(terminate); logger.info("Undeployed Operational String [{}]", opString.getName()); for (OperationalString os : terminated) { eventProcessor.processEvent(new ProvisionMonitorEvent(serviceProxy, ProvisionMonitorEvent.Action.OPSTRING_UNDEPLOYED, os)); } if (stateManager != null) stateManager.stateChanged(opStringManager, true); } /** * Get all OperationalString objects from the Collection of OpStringManagers * * @return Array of OperationalString objects */ public OperationalString[] getOperationalStrings() { List<OperationalString> list = new ArrayList<OperationalString>(); for(Map.Entry<String, OpStringManager> entry : opStringManagerTable.entrySet()) { if (entry.getValue().isTopLevel()) list.add(entry.getValue().doGetOperationalString()); } return list.toArray(new OperationalString[list.size()]); } /** * Get the OpStringManager for an OperationalString * * @param name The name of an OperationalString * @return The corresponding OpStringManager, or null if * not found */ public OpStringManager getOpStringManager(final String name) { if (name == null) return null; return opStringManagerTable.get(name); } /** * Get the primary OperationalStringManager for an opstring * * @param name The name of an OperationalString * @return The primary OperationalStringManager if found, or null if not */ public OperationalStringManager getPrimary(final String name) { OperationalStringManager mgr = null; ProvisionMonitor[] monitors = provisionMonitorPeer.getProvisionMonitorPeers(); for (ProvisionMonitor monitor : monitors) { try { DeployAdmin dAdmin = (DeployAdmin) monitor.getAdmin(); OperationalStringManager[] mgrs = dAdmin.getOperationalStringManagers(); for (OperationalStringManager mgr1 : mgrs) { if (mgr1.getOperationalString().getName().equals(name) && mgr1.isManaging()) { mgr = mgr1; break; } } } catch (Exception e) { logger.warn("Getting the primary OperationalStringManager for [" + name + "]", e); } } return mgr; } /** * Get the primary DeployAdmin for the opstring * * @param opStringName The opstring name * @return The primary DeployAdmin for the opstring, or null * if not found */ public DeployAdmin getPrimaryDeployAdmin(final String opStringName) { DeployAdmin primary = null; ProvisionMonitor.PeerInfo[] peers = provisionMonitorPeer.getBackupInfo(); for (ProvisionMonitor.PeerInfo peer : peers) { ProvisionMonitor peerMon = peer.getService(); try { DeployAdmin dAdmin = (DeployAdmin) peerMon.getAdmin(); if (dAdmin.hasDeployed(opStringName)) { OperationalStringManager mgr = dAdmin.getOperationalStringManager(opStringName); if (mgr.isManaging()) { primary = dAdmin; break; } } } catch (RemoteException e) { if (logger.isDebugEnabled()) logger.debug("Communicating to peer while searching for " + "primary testManager of [" + opStringName + "]", e); } catch (OperationalStringException e) { /* ignore */ } } return primary; } /** * Remove an OpStringManager from the collection of managed OpStringManagers * * @param opStringManager The OpStringManager to remove */ public boolean remove(final OpStringManager opStringManager) { return opStringManagerTable.remove(opStringManager.getName())!=null; } /** * Add an OpStringManager to this ProvisionMonitor. * * @param opString The OperationalString to add * @param map A Map to store any exceptions produced while loading the * opString * @param parent The parent of the opString. The addOperationalString * method recursively processes OperationalString instances and uses this * parameter to indicate a nested OperationalString * @param dAdmin The managing DeployAdmin, if the OperationalString is * being added in an inactive mode, as a backup. If this value is null, * this ProvisionMonitor is set to be active * @param listener A ServiceProvisionListener that will be set to the * OperationalStringManager for notification of services as they are * deployed initially. * @return An OpStringManager * @throws IOException if an OpStringManger cannot be created */ public OpStringManager addOperationalString(final OperationalString opString, final Map<String, Throwable> map, final OpStringManager parent, final DeployAdmin dAdmin, final ServiceProvisionListener listener) throws IOException { /* If there is no DeployAdmin active is true */ boolean active = dAdmin == null; OpStringManager opMgr = new DefaultOpStringManager(opString, parent, config, this); if (opStringManagerTable.putIfAbsent(opString.getName(), opMgr) == null) { if (logger.isInfoEnabled()) logger.info("Adding OpString [" + opString.getName() + "] active [" + active + "]"); ((DefaultOpStringManager) opMgr).setServiceProxy(serviceProxy); ((DefaultOpStringManager) opMgr).setEventProcessor(eventProcessor); ((DefaultOpStringManager) opMgr).setStateManager(stateManager); opMgr.initialize(active); Map<String, Throwable> errorMap = ((DefaultOpStringManager) opMgr).createServiceElementManagers(serviceProvisioner, uuid, listener); if (dAdmin != null) { OperationalStringManager activeMgr; Map<ServiceElement, ServiceBeanInstance[]> elemInstanceMap = new HashMap<ServiceElement, ServiceBeanInstance[]>(); try { activeMgr = dAdmin.getOperationalStringManager(opString.getName()); ServiceElement[] elems = opString.getServices(); for (ServiceElement elem : elems) { try { ServiceBeanInstance[] instances = activeMgr.getServiceBeanInstances(elem); elemInstanceMap.put(elem, instances); } catch (Exception e) { logger.warn("Getting ServiceBeanInstances from active testManager", e); } } ((DefaultOpStringManager) opMgr).startManager(listener, elemInstanceMap); } catch (Exception e) { logger.warn("Getting active OperationalStringManager", e); } } else { ((DefaultOpStringManager) opMgr).startManager(listener); } if (map != null) map.putAll(errorMap); if (stateManager != null) stateManager.stateChanged(opMgr, false); OperationalString[] nestedStrings = opString.getNestedOperationalStrings(); if (logger.isTraceEnabled()) { logger.trace("[{}] nested OperationalString count: [{}]", opString.getName(), nestedStrings.length); } for (OperationalString nestedString : nestedStrings) { if (logger.isTraceEnabled()) { logger.trace("Processing nested OperationalString [{}]", nestedString.getName()); } addOperationalString(nestedString, map, opMgr, dAdmin, listener); if (logger.isTraceEnabled()) { logger.trace("Completed processing nested OperationalString [{}]", nestedString.getName()); } } } if (active) { ProvisionMonitorEvent event = new ProvisionMonitorEvent(serviceProxy, ProvisionMonitorEvent.Action.OPSTRING_DEPLOYED, opMgr.doGetOperationalString()); if (opMgr.getOAR() != null) event.setRemoteRepositories(opMgr.getRemoteRepositories()); eventProcessor.processEvent(event); } if (logger.isTraceEnabled()) logger.trace("Return from add OperationalString [{}], mgr: {}", opString.getName(), opMgr); return opMgr; } public void shutdownAllManagers() { for (OpStringManager opMgr : getOpStringManagers()) { opMgr.terminate(false); } } public OpStringManager[] getOpStringManagers() { Collection<OpStringManager> mgrs = opStringManagerTable.values(); return mgrs.toArray(new OpStringManager[mgrs.size()]); } /** * Determine if the OperationalString with the provided name is deployed * * @param opStringName The name of the OperationalString * @return true if the OperationalString with the provided name is loaded */ public synchronized boolean opStringExists(final String opStringName) { return opStringManagerTable.get(opStringName)!=null; } /** * Dump an error map associated with the loading and/or addition of an * OperationalString * * @param errorMap The map containing exceptions */ public void dumpOpStringError(Map errorMap) { if (!errorMap.isEmpty()) { Set keys = errorMap.keySet(); StringBuilder sb = new StringBuilder(); sb.append("+========================+\n"); //int i = 0; for (Object comp : keys) { sb.append("Component: "); sb.append(comp); Object o = errorMap.get(comp); if (o instanceof Throwable) { StackTraceElement[] els = ((Throwable) o).getStackTrace(); for (StackTraceElement el : els) { sb.append("\tat "); sb.append(el); sb.append("\n"); } } else { sb.append(" "); sb.append(o.toString()); } } sb.append("\n+========================+"); if (logger.isDebugEnabled()) logger.debug(sb.toString()); } } class Deployer implements Callable<OpStringManager> { @Override public OpStringManager call() throws Exception { return null; } } }