![JAR search and dependency download from the Maven repository](/logo.png)
org.ow2.petals.microkernel.container.lifecycle.ServiceAssemblyLifeCycleImpl Maven / Gradle / Ivy
/**
* Copyright (c) 2005-2012 EBM WebSourcing, 2012-2016 Linagora
*
* This program/library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or (at your
* option) any later version.
*
* This program/library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program/library; If not, see http://www.gnu.org/licenses/
* for the GNU Lesser General Public License version 2.1.
*/
package org.ow2.petals.microkernel.container.lifecycle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.jbi.JBIException;
import javax.jbi.management.DeploymentServiceMBean;
import org.objectweb.fractal.fraclet.annotations.Component;
import org.objectweb.fractal.fraclet.annotations.Interface;
import org.objectweb.fractal.fraclet.annotations.Lifecycle;
import org.objectweb.fractal.fraclet.annotations.Requires;
import org.objectweb.fractal.fraclet.types.Step;
import org.ow2.petals.jbi.descriptor.original.generated.ServiceAssembly;
import org.ow2.petals.microkernel.api.container.IsolatingThread;
import org.ow2.petals.microkernel.api.container.ServiceAssemblyLifeCycle;
import org.ow2.petals.microkernel.api.container.ServiceUnitLifeCycle;
import org.ow2.petals.microkernel.api.system.SystemStateService;
import org.ow2.petals.microkernel.jbi.management.util.ManagementMessageUtil;
import com.ebmwebsourcing.easycommons.lang.ExceptionHelper;
import com.ebmwebsourcing.easycommons.log.LoggingUtil;
/**
* This class manages the life cycle of deployed service assemblies.
*
* The synchonisation and ordering of lifecycle actions is managed using synchronization on this and all the actual
* actions are done on the service units which relies on the component {@link IsolatingThread}.
*
* @author Olivier Fabre - EBM WebSourcing
* @author ddesjardins - EBM WebSourcing
* @author vnoel
*/
@Component(provides = @Interface(name = ServiceAssemblyLifeCycle.FRACTAL_SRV_ITF_NAME, signature = ServiceAssemblyLifeCycle.class))
public class ServiceAssemblyLifeCycleImpl implements ServiceAssemblyLifeCycle {
private final LoggingUtil log = new LoggingUtil(Logger.getLogger(ServiceAssemblyLifeCycle.COMPONENT_LOGGER_NAME));
private String name;
private String state;
/**
* Platform component :: SystemState Service
*/
@Requires(name = "systemstate")
private SystemStateService systemState;
/**
* The SA JBI descriptor
*/
private ServiceAssembly serviceAssembly;
/**
* List of SU life-cycles
*
* We use a LinkedHashMap to preserve insert ordering and make it synchronized to avoid concurrency problems
*/
private final Map serviceUnitsLifeCycles = Collections
.synchronizedMap(new LinkedHashMap());
private boolean firstStart = true;
@Override
public void init(ServiceAssembly serviceAssembly) throws JBIException {
this.serviceAssembly = serviceAssembly;
this.name = serviceAssembly.getIdentification().getName();
// set the state to SHUTDOWN, as the JBI specifications specifies
this.setState(DeploymentServiceMBean.SHUTDOWN);
}
@Override
public synchronized List init() throws JBIException {
final List results = new ArrayList<>();
if (isShutdownState()) {
doInit(results);
setState(DeploymentServiceMBean.STOPPED);
}
return results;
}
private void doInit(final List results) throws JBIException {
boolean allFailed = true;
final List exceptions = new ArrayList<>();
for (final ServiceUnitLifeCycle suLifeCycle : serviceUnitsLifeCycles.values()) {
try {
// it is only executed if the SU is shutdown
suLifeCycle.init();
results.add(ManagementMessageUtil.getComponentTaskResult(
suLifeCycle.getTargetComponentName(), "init", ManagementMessageUtil.TASK_RESULT_SUCCESS));
allFailed = false;
} catch (final Exception e) {
exceptions.add(e);
results.add(ManagementMessageUtil.getComponentTaskResult(
suLifeCycle.getTargetComponentName(), "init", ManagementMessageUtil.TASK_RESULT_FAILED,
ManagementMessageUtil.MESSAGE_TYPE_ERROR, "2", "Failed to initialise SU: {1}",
new String[] { suLifeCycle.getSuName() }, ExceptionHelper.getStackTrace(e)));
this.log.error(
String.format("The initialization of service unit '%s' fails.", suLifeCycle.getSuName()), e);
}
}
// if exceptions is empty, it means there was nothing executed!
if (allFailed && !exceptions.isEmpty()) {
final JBIException ex = new JBIException("SA start failed");
for (final Exception e : exceptions) {
ex.addSuppressed(e);
}
throw ex;
}
}
@Override
public synchronized void shutDown() throws JBIException {
if (isStartedState()) {
doStop();
setState(DeploymentServiceMBean.STOPPED);
}
if (isStoppedState()) {
doShutdown();
setState(DeploymentServiceMBean.SHUTDOWN);
}
}
public void doShutdown() {
final List reversedSuLifeCycles = new ArrayList(
serviceUnitsLifeCycles.values());
Collections.reverse(reversedSuLifeCycles);
for (final ServiceUnitLifeCycle suLifeCycle : reversedSuLifeCycles) {
try {
suLifeCycle.shutDown();
} catch (final Exception e) {
this.log.error(String.format("The shutdown of service unit '%s' fails.", suLifeCycle.getSuName()), e);
}
}
}
@Override
public synchronized List start() throws JBIException {
final List results = new ArrayList<>();
// note: do start calls init by itself
if (isShutdownState() || isStoppedState()) {
doStart(results);
setState(DeploymentServiceMBean.STARTED);
}
return results;
}
private void doStart(final List results) throws JBIException {
// The JBI specifications force to initialize ALL the SUs of the SA before all starting them
doInit(results);
boolean allFailed = true;
final List exceptions = new ArrayList<>();
for (final ServiceUnitLifeCycle suLifeCycle : serviceUnitsLifeCycles.values()) {
try {
// it is only executed if the SU is stopped!
suLifeCycle.start();
results.add(ManagementMessageUtil.getComponentTaskResult(
suLifeCycle.getTargetComponentName(), "start", ManagementMessageUtil.TASK_RESULT_SUCCESS));
allFailed = false;
} catch (final Exception e) {
exceptions.add(e);
results.add(
ManagementMessageUtil.getComponentTaskResult(suLifeCycle.getTargetComponentName(), "start",
ManagementMessageUtil.TASK_RESULT_FAILED, ManagementMessageUtil.MESSAGE_TYPE_ERROR, "2",
"Failed to start SU: {1}", new String[] { suLifeCycle.getSuName() },
ExceptionHelper.getStackTrace(e)));
this.log.error(String.format("The start-up of service unit '%s' fails.", suLifeCycle.getSuName()), e);
}
}
// if exceptions is empty, it means there was nothing executed!
if (allFailed && !exceptions.isEmpty()) {
final JBIException ex = new JBIException("SA start failed");
for (final Exception e : exceptions) {
ex.addSuppressed(e);
}
throw ex;
}
}
@Override
public synchronized void stop() throws JBIException {
if (isStartedState()) {
doStop();
setState(DeploymentServiceMBean.STOPPED);
}
}
private void doStop() {
final List reversedSuLifeCycles = new ArrayList(
serviceUnitsLifeCycles.values());
Collections.reverse(reversedSuLifeCycles);
for (final ServiceUnitLifeCycle suLifeCycle : reversedSuLifeCycles) {
try {
suLifeCycle.stop();
} catch (final Exception e) {
this.log.error(String.format("The stop of service unit '%s' fails.", suLifeCycle.getSuName()), e);
}
}
}
@Override
public ServiceAssembly getServiceAssembly() {
return this.serviceAssembly;
}
@Override
public Collection getServiceUnitLifeCycles() {
return Collections.unmodifiableCollection(this.serviceUnitsLifeCycles.values());
}
@Override
public void registerSU(final ServiceUnitLifeCycle serviceUnitLifeCycle) throws JBIException {
final String suName = serviceUnitLifeCycle.getSuName();
if (this.serviceUnitsLifeCycles.containsKey(suName)) {
throw new JBIException("Duplicate service unit: same name (" + suName + ")");
}
this.serviceUnitsLifeCycles.put(suName, serviceUnitLifeCycle);
}
@Override
public void unregisterSU(final ServiceUnitLifeCycle serviceUnitLifeCycle) {
this.serviceUnitsLifeCycles.remove(serviceUnitLifeCycle.getSuName());
}
@Override
public String getCurrentState() {
return this.state;
}
public boolean isShutdownState() {
return DeploymentServiceMBean.SHUTDOWN.equals(this.getCurrentState());
}
public boolean isStartedState() {
return DeploymentServiceMBean.STARTED.equals(this.getCurrentState());
}
public boolean isStoppedState() {
return DeploymentServiceMBean.STOPPED.equals(this.getCurrentState());
}
private void setState(final String state) throws JBIException {
if (!(DeploymentServiceMBean.SHUTDOWN.equals(state) || DeploymentServiceMBean.STARTED.equals(state)
|| DeploymentServiceMBean.STOPPED.equals(state))) {
throw new JBIException(
"State '" + state + "' isn't defined by the JBI specification. No state changement done.");
}
this.state = state;
try {
this.systemState.updateServiceAssemblyState(this.name, state);
} catch (final Exception e) {
throw new JBIException("Failed to persist the state of the Service Assembly '" + this.name + "'", e);
}
}
@Lifecycle(step = Step.START)
public void startFractalComponent() throws JBIException {
this.log.call();
if (!firstStart) {
// the first start is handled by init
// Note: this method is never really called after stopFractalComponent has been called,
// but the following is present for coherence: this is NOT related to restoration (for restoration, init and
// start are called as needed by the restoration subsystem)
final List results = new ArrayList<>();
if (isStartedState()) {
this.doStart(results);
} else if (isStoppedState()) {
this.doInit(results);
}
if (this.log.isInfoEnabled()) {
this.log.info("started service assembly lifecycle for " + this.name + ": " + results);
}
} else {
firstStart = false;
}
}
/**
* Stop of the petals component
*
*/
@Lifecycle(step = Step.STOP)
public void stopFractalComponent() {
this.log.start();
if (isStartedState()) {
this.doStop();
this.doShutdown();
}
if (isStoppedState()) {
this.doShutdown();
}
this.log.end();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy