
org.objectweb.petals.component.framework.AbstractComponent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of petals-cdk Show documentation
Show all versions of petals-cdk Show documentation
The PEtALS component framework. This framework is used to easily
create JBI 1.0 compliant components.
The newest version!
/**
* PETALS - PETALS Services Platform.
* Copyright (c) 2007 EBM Websourcing, http://www.ebmwebsourcing.com/
*
* This 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 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* -------------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------------
*/
package org.objectweb.petals.component.framework;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jbi.JBIException;
import javax.jbi.component.Component;
import javax.jbi.component.ComponentContext;
import javax.jbi.component.ComponentLifeCycle;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.servicedesc.ServiceEndpoint;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import org.objectweb.petals.component.framework.interceptor.Interceptor;
import org.objectweb.petals.component.framework.interceptor.description.InterceptorBuilder;
import org.objectweb.petals.component.framework.interceptor.description.InterceptorConfiguration;
import org.objectweb.petals.component.framework.listener.JBIListenerManager;
import org.objectweb.petals.component.framework.mbean.PerformanceNotification;
import org.objectweb.petals.component.framework.mbean.PerformanceNotifierMBean;
import org.objectweb.petals.component.framework.su.ServiceUnitExtensionsValidator;
import org.objectweb.petals.component.framework.su.ServiceUnitListener;
import org.objectweb.petals.component.framework.su.ServiceUnitManager;
import org.objectweb.petals.component.framework.util.Exchange;
import org.objectweb.petals.component.framework.util.StringHelper;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
/**
* An abstract class that can be used to easily create a new JBI Component. It
* implements Component, ComponentLifeCycle and MessageExchangeProcessor JBI
* interfaces.
*
* @author ofabre
*
*/
public abstract class AbstractComponent implements Component,
ComponentLifeCycle {
/**
* InOnly Mep shortcut
*/
public static final String IN_ONLY = "in-only";
/**
* InOnly Mep shortcut
*/
public static final String ROBUST_IN_ONLY = "robust-in-only";
/**
* InOnly Mep shortcut
*/
public static final String IN_OUT = "in-out";
/**
* InOnly Mep shortcut
*/
public static final String IN_OPTIONAL_OUT = "in-optional-out";
/**
* The component's delivery channel
*/
private DeliveryChannel channel;
/**
* The Component's Context
*/
private ComponentContext context;
/**
* The component configuration
*/
private ComponentConfiguration componentConfiguration;
/**
* The message exchange listener
*/
private JBIListenerManager listenerManager;
/**
* The component's logger
*/
private Logger log; // NOPMD by ofabre
/**
* The ServiceUnit lifecycle listener
*/
private ServiceUnitListener serviceUnitListener;
/**
* The service unit extensions validator
*/
private ServiceUnitExtensionsValidator serviceUnitExtensionsValidator;
/**
* The component's service unit manager
*/
private ServiceUnitManager suManager;
/**
* All the component interceptors. Key is the name of the interceptor. All
* the
*/
protected Map interceptors;
/**
* JMX Performance notifier MBean
*/
private PerformanceNotifierMBean jmxPerformanceNotifierMBean = null;
/**
* Creates a new {@link JBIListenerManager}
*
* @param configuration
* Configuration of the component
* @return the created {@link JBIListenerManager}
*/
private JBIListenerManager createJBIListenerManager(
final ComponentConfiguration configuration) {
return new JBIListenerManager(this, configuration, this.log,
this.suManager);
}
/**
* Can be overidden to provide a specific service unit manager
*
* @return the service unit manager used by this component.
*/
protected ServiceUnitManager createServiceUnitManager() {
return new ServiceUnitManager(this);
}
/**
* Creates the component configuration from the component manager. The
* component configuration contains all PCF properties as attributes.
*
* @return the component configuration.
*/
protected ComponentConfiguration createComponentConfiguration()
throws PEtALSCDKException {
final ComponentConfiguration conf = new ComponentConfiguration();
// get the component properties manager to load extension values
final ComponentPropertiesManager extensionProperties =
new ComponentPropertiesManager();
extensionProperties.setRootPath(this.getContext().getInstallRoot());
if (!extensionProperties.load()) {
throw new PEtALSCDKException(
"Failed to load extensions section in the component descriptor file");
}
final Properties properties = extensionProperties.getProperties();
// create configuration from required values
int poolSize = 0;
try {
if ((extensionProperties.getProperty(
ComponentPropertiesManager.POOL_SIZE) == null)||
(extensionProperties.getProperty(
ComponentPropertiesManager.POOL_SIZE).trim().equals(""))) {
extensionProperties.getProperties().setProperty(
ComponentPropertiesManager.POOL_SIZE,
ComponentPropertiesManager.DEFAULT_POOL_SIZE);
}
poolSize = Integer.parseInt(extensionProperties.getProperty(
ComponentPropertiesManager.POOL_SIZE,
ComponentPropertiesManager.DEFAULT_POOL_SIZE));
} catch (final NumberFormatException e) {
throw new PEtALSCDKException("The PCF parameter '"
+ ComponentPropertiesManager.POOL_SIZE
+ "' is invalid in the component descriptor file");
}
if (poolSize <= 0) {
throw new PEtALSCDKException("The PCF parameter '"
+ ComponentPropertiesManager.POOL_SIZE
+ "' is invalid in the component descriptor file");
}
conf.setPoolSize(poolSize);
properties.setProperty(ComponentPropertiesManager.POOL_SIZE, Integer
.toString(conf.getPoolSize()));
IgnoredStatusConstants ignoreStatus;
try {
if ((extensionProperties.getProperty(
ComponentPropertiesManager.IGNORED_STATUS) == null)||(extensionProperties.getProperty(
ComponentPropertiesManager.IGNORED_STATUS).trim()
.equals(""))) {
extensionProperties.getProperties().setProperty(
ComponentPropertiesManager.IGNORED_STATUS,
ComponentPropertiesManager.DEFAULT_IGNORED_STATUS);
}
ignoreStatus = IgnoredStatusConstants.valueOf(extensionProperties
.getProperty(ComponentPropertiesManager.IGNORED_STATUS,
ComponentPropertiesManager.DEFAULT_IGNORED_STATUS));
} catch (final IllegalArgumentException e) {
throw new PEtALSCDKException("The PCF parameter '"
+ ComponentPropertiesManager.IGNORED_STATUS
+ "' is invalid in the component descriptor file");
}
conf.setIgnoredStatus(ignoreStatus);
properties.setProperty(ComponentPropertiesManager.IGNORED_STATUS, conf
.getIgnoredStatus().value());
final String jbiListenerClassName = extensionProperties
.getProperty(ComponentPropertiesManager.JBI_LISTENER_CLASSNAME);
if (StringHelper.isNullOrEmpty(jbiListenerClassName)) {
throw new PEtALSCDKException("The PCF parameter '"
+ ComponentPropertiesManager.JBI_LISTENER_CLASSNAME
+ "' is invalid or absent in the component descriptor file");
}
conf.setJbiListenerClassName(jbiListenerClassName);
conf.setExternalListenerClassName(extensionProperties
.getProperty(ComponentPropertiesManager.
EXTERNAL_LISTENER_CLASSNAME));
this.log.info("Component configuration -> Thread pool size : "
+ conf.getPoolSize() + ", Ignored message exchange status : "
+ conf.getIgnoredStatus().value());
// put the updated properties
conf.setProperties(properties);
return conf;
}
/**
* Returns the component delivery channel, used to send messages to petals
* container
*
* @return the delivery channel. Not null.
*/
public DeliveryChannel getChannel() {
return this.channel;
}
/**
* The component context
*
* @return the component context. Not null.
*/
public ComponentContext getContext() {
return this.context;
}
/**
* Returns null by default as this class does not provides JMX extension
* MBean
*
* @see javax.jbi.component.ComponentLifeCycle#getExtensionMBeanName()
*/
public ObjectName getExtensionMBeanName() {
return null;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#getLifeCycle()
*/
public ComponentLifeCycle getLifeCycle() {
return this;
}
/**
* Returns the component logger
*
* @return component logger. Not null.
*/
public Logger getLogger() {
return this.log;
}
/**
* Can be overidden to return a custom resource bundle name
*
* @return the resource bundle name or null if no resource bundle name has
* to be used (default value)
*/
protected String getResourceBundleName() {
return null;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#getServiceDescription(javax.jbi.servicedesc.ServiceEndpoint)
*/
public Document getServiceDescription(final ServiceEndpoint endpoint) {
return this.suManager.getServiceDescription(endpoint);
}
public ServiceUnitListener getServiceUnitListener() {
return this.serviceUnitListener;
}
public ServiceUnitExtensionsValidator getServiceUnitExtensionsValidator() {
return this.serviceUnitExtensionsValidator;
}
/**
* Get all the interceptors
*
* @return
*/
public Map getInterceptors() {
return this.interceptors;
}
/**
* Get the interceptor that have the given name.
*
* @param name
* @return null if the interceptor is not found of is there are no
* interceptor in the component
*/
public Interceptor getInterceptor(final String name) {
Interceptor interceptor = null;
if (this.interceptors != null) {
interceptor = this.interceptors.get(name);
}
return interceptor;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#getServiceUnitManager()
*/
public javax.jbi.component.ServiceUnitManager getServiceUnitManager() {
if (this.suManager == null) {
this.suManager = this.createServiceUnitManager();
}
return this.suManager;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.ComponentLifeCycle#init(javax.jbi.component.ComponentContext)
*/
public final void init(final ComponentContext compContext)
throws JBIException {
this.context = compContext;
this.log = this.context.getLogger("", this.getResourceBundleName());
this.log.fine("Component initialization in progress...");
this.channel = this.context.getDeliveryChannel();
this.componentConfiguration = this.createComponentConfiguration();
this.interceptors = this.loadInterceptors();
this.suManager = this.createServiceUnitManager();
this.log.fine("Calling specific initialization...");
this.doInit();
this.log.fine("Specific initialization done.");
this.log.log(Level.INFO, "Component initialized");
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#isExchangeWithConsumerOkay(javax.jbi.servicedesc.ServiceEndpoint,
* javax.jbi.messaging.MessageExchange)
*/
public boolean isExchangeWithConsumerOkay(final ServiceEndpoint endpoint,
final MessageExchange exchange) {
return true;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#isExchangeWithProviderOkay(javax.jbi.servicedesc.ServiceEndpoint,
* javax.jbi.messaging.MessageExchange)
*/
public boolean isExchangeWithProviderOkay(final ServiceEndpoint endpoint,
final MessageExchange exchange) {
return true;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.Component#resolveEndpointReference(org.w3c.dom.DocumentFragment)
*/
public ServiceEndpoint resolveEndpointReference(final DocumentFragment epr) {
return null;
}
public void setServiceUnitListener(
final ServiceUnitListener serviceUnitListener) {
this.serviceUnitListener = serviceUnitListener;
}
public void setServiceUnitExtensionsValidator(
final ServiceUnitExtensionsValidator serviceUnitExtensionsValidator) {
this.serviceUnitExtensionsValidator = serviceUnitExtensionsValidator;
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.ComponentLifeCycle#shutDown()
*/
public final void shutDown() throws JBIException {
this.log.log(Level.INFO, "shutdown");
this.doShutdown();
this.listenerManager = null; // NOPMD frees the memory while
// component is
// shutdown
this.context = null; // NOPMD idem
this.log = null; // NOPMD idem
this.channel = null; // NOPMD idem
this.suManager = null; // NOPMD idem
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.ComponentLifeCycle#start()
*/
public final void start() throws JBIException {
this.log.log(Level.INFO, "start");
this.registerPerformanceNotifierMBean();
this.listenerManager = this
.createJBIListenerManager(this.componentConfiguration);
this.listenerManager.startListening();
this.log.fine("Calling specific start...");
this.doStart();
this.log.fine("Specific start done.");
}
/*
* (non-Javadoc)
*
* @see javax.jbi.component.ComponentLifeCycle#stop()
*/
public final void stop() throws JBIException {
this.log.log(Level.INFO, "stop");
// FIXME : call terminate or close?
this.unregisterPerformanceNotifierMBean();
this.listenerManager.stopListening();
this.log.fine("Calling specific stop...");
this.doStop();
this.log.fine("Specific stop done.");
}
/**
* A convenience method which can be overridden so that there's no need to
* call super.doInit(). This method is called at the end of the component
* classical initialization. When this method is called, the component's
* delivery channel, context, logger and service unit manager are available.
*
*/
protected void doInit() throws JBIException {
}
/**
* A convenience method which can be overridden so that there's no need to
* call super.doStart(). This method is called at the end of the component
* classical start.
*
*/
protected void doStart() throws JBIException {
}
/**
* A convenience method which can be overridden so that there's no need to
* call super.doStop(). This method is called at the end of the component
* classical stop.
*
*/
protected void doStop() throws JBIException {
}
/**
* A convenience method which can be overridden so that there's no need to
* call super.doShutdown(). This method is called at the end of the
* component classical shutdown.
*
*/
protected void doShutdown() throws JBIException {
}
public ComponentConfiguration getComponentConfiguration() {
return this.componentConfiguration;
}
/**
* Load the interceptors
*
* @param configuration
*/
protected final Map loadInterceptors() {
Map interceptors = null;
final InterceptorBuilder builder = InterceptorBuilder.getInstance();
try {
final List list = builder
.loadComponentInterceptors(this.getContext()
.getInstallRoot());
interceptors = this.instanciateInterceptors(list);
} catch (final PEtALSCDKException e) {
e.printStackTrace();
}
return interceptors;
}
/**
* Load the accept interceptors
*
* @return
*/
protected final Map instanciateInterceptors(
final List interceptors) {
final Map loaded = new HashMap();
if (interceptors != null) {
final InterceptorBuilder builder = InterceptorBuilder.getInstance();
for (final InterceptorConfiguration interceptorConfig : interceptors) {
try {
this.getLogger().info(
"Loading interceptor : "
+ interceptorConfig.getName());
final Interceptor itc = builder
.loadInstance(interceptorConfig.getClazz());
itc.init(this, interceptorConfig.getName(),
interceptorConfig.isActive(), interceptorConfig
.getParameters(), this.getLogger());
loaded.put(itc.getName(), itc);
} catch (final PEtALSCDKException e) {
this.getLogger().log(
Level.WARNING,
"Could not load or initialize interceptor '"
+ interceptorConfig.getName()
+ "' from class '"
+ interceptorConfig.getClazz()
+ "', this interceptor is skipped");
}
}
}
return loaded;
}
/**
*
* @return
*/
public JBIListenerManager getListenerManager() {
return this.listenerManager;
}
/**
* Register the performance notifier in the JMX server
*
* @throws JBIException
*/
private void registerPerformanceNotifierMBean() throws JBIException {
try {
final ObjectName jmxPerformanceNotifierName = this.context
.getMBeanNames().createCustomComponentMBeanName(
"performance_notifier_"
+ this.context.getComponentName());
this.jmxPerformanceNotifierMBean = new PerformanceNotifierMBean(
this.componentConfiguration, jmxPerformanceNotifierName);
final MBeanServer server = this.context.getMBeanServer();
if (server == null) {
throw new JBIException("MBean server is null !");
}
if (server.isRegistered(jmxPerformanceNotifierName)) {
server.unregisterMBean(jmxPerformanceNotifierName);
}
server.registerMBean(this.jmxPerformanceNotifierMBean,
jmxPerformanceNotifierName);
} catch (final InstanceNotFoundException e) {
throw new JBIException(e);
} catch (final MBeanRegistrationException e) {
throw new JBIException(e);
} catch (final InstanceAlreadyExistsException e) {
throw new JBIException(e);
} catch (final NotCompliantMBeanException e) {
throw new JBIException(e);
}
}
/**
* Unregister the performance notifier
*
* @throws JBIException
*/
private void unregisterPerformanceNotifierMBean() throws JBIException {
try {
final MBeanServer server = this.context.getMBeanServer();
server.unregisterMBean(this.jmxPerformanceNotifierMBean
.getJmxPerformanceNotifierName());
} catch (final InstanceNotFoundException e) {
throw new JBIException(e);
} catch (final MBeanRegistrationException e) {
throw new JBIException(e);
}
}
/**
* Get the performance notifier
*
* @return
*/
public PerformanceNotifierMBean getJmxPerformanceNotifierMBean() {
return this.jmxPerformanceNotifierMBean;
}
/**
* Create a performance notification which the type RECEIVING_FROM_OUTSIDE
*
* @return The performance notification to send.
*/
public PerformanceNotification createPerformanceNotificationReceivingFromOutside(
final String userData, final Exchange msgExchange) {
return this.createPerformanceNotification(
PerformanceNotification.RECEIVING_FROM_OUTSIDE, userData,
msgExchange);
}
/**
* Create a performance notification which the type SENDING_TO_OUTSIDE
*
* @return The performance notification to send.
*/
public PerformanceNotification createPerformanceNotificationSendingToOutside(
final String userData, final Exchange msgExchange) {
return this.createPerformanceNotification(
PerformanceNotification.SENDING_TO_OUTSIDE, userData,
msgExchange);
}
/**
* Create a performance notification which the type RECEIVING_FROM_NMR
*
* @return The performance notification to send.
*/
public PerformanceNotification createPerformanceNotificationReceivingFromNMR(
final String userData, final Exchange msgExchange) {
return this.createPerformanceNotification(
PerformanceNotification.RECEIVING_FROM_NMR, userData,
msgExchange);
}
/**
* Create a performance notification which the type SENDING_TO_NMR
*
* @return The performance notification to send.
*/
public PerformanceNotification createPerformanceNotificationSendingToNMR(
final String userData, final Exchange msgExchange) {
return this.createPerformanceNotification(
PerformanceNotification.SENDING_TO_NMR, userData, msgExchange);
}
/**
* Create a new notification
*
* @param type
* @param userData
* @param msgExchange
* @return
*/
private PerformanceNotification createPerformanceNotification(
final String type, final String userData, final Exchange msgExchange) {
PerformanceNotification performanceNotification = null;
if (this.componentConfiguration.isPerformanceNotificationsEnabled()) {
performanceNotification = this.jmxPerformanceNotifierMBean
.createPerformanceNotifications(System.currentTimeMillis(),
this.context.getComponentName(), type, userData,
msgExchange);
}
return performanceNotification;
}
/**
* Send a performance notification using the performance notifier
*
* @param performanceNotification
*/
public void sendPerformanceNotification(
final PerformanceNotification performanceNotification) {
if (this.componentConfiguration.isPerformanceNotificationsEnabled()) {
this.jmxPerformanceNotifierMBean.send(performanceNotification);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy