/** * Load a deployment unit record stored in the db into memory. * * @param dudao */ protected List<ProcessConfImpl> load(DeploymentUnitDAO dudao) { __log.debug("Loading deployment unit record from db: " + dudao.getName()); File dudir = findDeployDir(dudao); if (dudir == null || !dudir.exists()) throw new ContextException( "Deployed directory " + (dudir == null ? "(unknown)" : dudir) + " no longer there!"); DeploymentUnitDir dud = new DeploymentUnitDir(dudir); // set the name with the one from database dud.setName(dudao.getName()); dud.scan(); ArrayList<ProcessConfImpl> loaded = new ArrayList<ProcessConfImpl>(); _rw.writeLock().lock(); try { _deploymentUnits.put(dud.getName(), dud); long version = 0; for (ProcessConfDAO p : dudao.getProcesses()) { TDeployment.Process pinfo = dud.getProcessDeployInfo(p.getType()); if (pinfo == null) { __log.warn("Cannot load " + p.getPID() + "; cannot find descriptor."); continue; } Map<QName, Node> props = calcInitialProperties(dud.getProperties(), pinfo); // TODO: update the props based on the values in the DB. ProcessConfImpl pconf = new ProcessConfImpl( p.getPID(), p.getType(), p.getVersion(), dud, pinfo, dudao.getDeployDate(), props, p.getState(), eprContext, _configDir, generateProcessEventsAll); version = p.getVersion(); _processes.put(pconf.getProcessId(), pconf); loaded.add(pconf); } // All processes and the DU have the same version dud.setVersion(version); } finally { _rw.writeLock().unlock(); } return loaded; }
/** Load all the deployment units out of the store. Called on start-up. */ public void loadAll() { final ArrayList<ProcessConfImpl> loaded = new ArrayList<ProcessConfImpl>(); exec( new Callable<Object>() { public Object call(ConfStoreConnection conn) { Collection<DeploymentUnitDAO> dus = conn.getDeploymentUnits(); for (DeploymentUnitDAO du : dus) try { loaded.addAll(load(du)); } catch (Exception ex) { __log.error("Error loading DU from store: " + du.getName(), ex); } return null; } }); // Dispatch DISABLED, RETIRED and ACTIVE events in that order Collections.sort( loaded, new Comparator<ProcessConf>() { public int compare(ProcessConf o1, ProcessConf o2) { return stateValue(o1.getState()) - stateValue(o2.getState()); } int stateValue(ProcessState state) { if (ProcessState.DISABLED.equals(state)) return 0; if (ProcessState.RETIRED.equals(state)) return 1; if (ProcessState.ACTIVE.equals(state)) return 2; throw new IllegalStateException("Unexpected process state: " + state); } }); for (ProcessConfImpl p : loaded) { try { fireStateChange(p.getProcessId(), p.getState(), p.getDeploymentUnit().getName()); } catch (Exception except) { __log.error( "Error while activating process: pid=" + p.getProcessId() + " package=" + p.getDeploymentUnit().getName(), except); } } }
/** Deploys a process. */ public Collection<QName> deploy( final File deploymentUnitDirectory, boolean activate, String duName, boolean autoincrementVersion) { __log.info(__msgs.msgDeployStarting(deploymentUnitDirectory)); final Date deployDate = new Date(); // Create the DU and compile/scan it before acquiring lock. final DeploymentUnitDir du = new DeploymentUnitDir(deploymentUnitDirectory); if (duName != null) { // Override the package name if given from the parameter du.setName(duName); } long version; if (autoincrementVersion || du.getStaticVersion() == -1) { // Process and DU use a monotonically increased single version number by default. try { version = getCurrentVersion(); } finally { // we need to reset the current version thread local value. _currentVersion.set(null); } } else { version = du.getStaticVersion(); } du.setVersion(version); try { du.compile(); } catch (CompilationException ce) { String errmsg = __msgs.msgDeployFailCompileErrors(ce); __log.error(errmsg, ce); throw new ContextException(errmsg, ce); } du.scan(); final DeployDocument dd = du.getDeploymentDescriptor(); final ArrayList<ProcessConfImpl> processes = new ArrayList<ProcessConfImpl>(); Collection<QName> deployed; _rw.writeLock().lock(); try { if (_deploymentUnits.containsKey(du.getName())) { String errmsg = __msgs.msgDeployFailDuplicateDU(du.getName()); __log.error(errmsg); throw new ContextException(errmsg); } retirePreviousPackageVersions(du); for (TDeployment.Process processDD : dd.getDeploy().getProcessArray()) { QName pid = toPid(processDD.getName(), version); if (_processes.containsKey(pid)) { String errmsg = __msgs.msgDeployFailDuplicatePID(processDD.getName(), du.getName()); __log.error(errmsg); throw new ContextException(errmsg); } QName type = processDD.getType() != null ? processDD.getType() : processDD.getName(); CBPInfo cbpInfo = du.getCBPInfo(type); if (cbpInfo == null) { String errmsg = __msgs.msgDeployFailedProcessNotFound(processDD.getName(), du.getName()); __log.error(errmsg); throw new ContextException(errmsg); } ProcessConfImpl pconf = new ProcessConfImpl( pid, processDD.getName(), version, du, processDD, deployDate, calcInitialProperties(du.getProperties(), processDD), calcInitialState(processDD), eprContext, _configDir, generateProcessEventsAll); processes.add(pconf); } _deploymentUnits.put(du.getName(), du); for (ProcessConfImpl process : processes) { __log.info(__msgs.msgProcessDeployed(du.getDeployDir(), process.getProcessId())); _processes.put(process.getProcessId(), process); } } finally { _rw.writeLock().unlock(); } // Do the deployment in the DB. We need this so that we remember deployments across system // shutdowns. // We don't fail if there is a DB error, simply print some errors. deployed = exec( new Callable<Collection<QName>>() { public Collection<QName> call(ConfStoreConnection conn) { // Check that this deployment unit is not deployed. DeploymentUnitDAO dudao = conn.getDeploymentUnit(du.getName()); if (dudao != null) { String errmsg = "Database out of synch for DU " + du.getName(); __log.warn(errmsg); dudao.delete(); } dudao = conn.createDeploymentUnit(du.getName()); try { dudao.setDeploymentUnitDir(deploymentUnitDirectory.getCanonicalPath()); } catch (IOException e1) { String errmsg = "Error getting canonical path for " + du.getName() + "; deployment unit will not be available after restart!"; __log.error(errmsg); } ArrayList<QName> deployed = new ArrayList<QName>(); // Going trough each process declared in the dd for (ProcessConfImpl pc : processes) { try { ProcessConfDAO newDao = dudao.createProcess(pc.getProcessId(), pc.getType(), pc.getVersion()); newDao.setState(pc.getState()); for (Map.Entry<QName, Node> prop : pc.getProcessProperties().entrySet()) { newDao.setProperty(prop.getKey(), DOMUtils.domToString(prop.getValue())); } deployed.add(pc.getProcessId()); } catch (Throwable e) { String errmsg = "Error persisting deployment record for " + pc.getProcessId() + "; process will not be available after restart!"; __log.error(errmsg, e); } } return deployed; } }); _rw.readLock().lock(); boolean readLockHeld = true; try { for (ProcessConfImpl process : processes) { fireEvent( new ProcessStoreEvent( ProcessStoreEvent.Type.DEPLOYED, process.getProcessId(), process.getDeploymentUnit().getName())); fireStateChange( process.getProcessId(), process.getState(), process.getDeploymentUnit().getName()); } } catch (Exception e) { // need to unlock as undeploy operation will need a writeLock _rw.readLock().unlock(); readLockHeld = false; // A problem at that point means that engine deployment failed, we don't want the store to // keep the du __log.warn("Deployment failed within the engine, store undeploying process.", e); undeploy(deploymentUnitDirectory); if (e instanceof ContextException) throw (ContextException) e; else throw new ContextException("Deployment failed within the engine. " + e.getMessage(), e); } finally { if (readLockHeld) _rw.readLock().unlock(); } return deployed; }