/*
* JBoss, Home of Professional Open Source Copyright 2008, Red Hat Middleware
* LLC, and individual contributors by the @authors tag. See the copyright.txt
* in the distribution for a full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.jboss.soa.esb.listeners.deployers.mc;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.management.ObjectName;
import org.apache.log4j.Logger;
import org.jboss.beans.metadata.spi.BeanMetaData;
import org.jboss.beans.metadata.spi.builder.BeanMetaDataBuilder;
import org.jboss.dependency.spi.ControllerState;
import org.jboss.deployers.client.spi.DeployerClient;
import org.jboss.deployers.spi.deployer.DeploymentStages;
import org.jboss.deployers.vfs.spi.deployer.AbstractSimpleVFSRealDeployer;
import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
import org.jboss.deployment.DeploymentException;
import org.jboss.internal.soa.esb.util.JBossDeployerUtil;
import org.jboss.virtual.VirtualFile;
/**
* EsbDeployer takes care of the deployment of an {@link EsbDeployment}.
* <p/>
*
* This deployer actually only creates a BeanMetaData object describing a
* {@link EsbDeployment}. The MicroContainer will take care of the actual
* creation and starting of the deployment using it's lifecycle callbacks. <p/>
*
* Example configuration:
*
* <pre>{@code
* <bean name="EsbDeployer" class="org.jboss.soa.esb.listeners.deployers.mc.EsbDeployer">
* <property name="esbBeanPrefix">jboss.esb</property>
* <property name="defaultDependencies">
* <list elementClass="java.lang.String">
* <value>jboss.esb:service=ESBRegistry</value>
* <value>jboss.esb:service=JuddiRMI</value>
* </list>
* </property>
* </bean>
* }</pre>
*
* @author <a href="mailto:dbevenius@jboss.com">Daniel Bevenius</a>
* @author <a href="mailto:mageshbk@jboss.com">Magesh Kumar B</a>
*/
public class EsbDeployer extends AbstractSimpleVFSRealDeployer<EsbMetaData>
{
/**
* Logger.
*/
private Logger log = Logger.getLogger(EsbDeployer.class);
/**
* Prefix used for the BeanMetaData and for the managenment bean name.
*/
private String esbBeanPrefix = "jboss.esb";
/**
* Default dependencies that will be added to all {@link EsbDeployment}s.
*/
private List<String> defaultDeps = new ArrayList<String>();
private DeployerClient mainDeployer;
/**
* The path the the directory that will be used to generate the war file
* for all web gateway deployments (EBWS and HTTP Gateways).
*/
private String warFilesDir;
/**
* No args constructor.
*/
public EsbDeployer()
{
super(EsbMetaData.class);
// Tell the MicroContainer that we are producing BeanMetaData.
setOutput(BeanMetaData.class);
// Need access to classloaders
setStage(DeploymentStages.POST_CLASSLOADER);
}
public void setMainDeployer(DeployerClient mainDeployer)
{
this.mainDeployer = mainDeployer;
}
/**
* Sets the directory that will be used for generating ESWS wars.
* @param dir The directory to be used.
*/
public void setWarFilesDir(final String dir)
{
this.warFilesDir = dir;
}
/**
* Creates an {@link BeanMetaData} instance that describes the JBossESB
* deployment. The BeanMetaData is created using the information from the
* EsbMetaData object, such as the contents of jboss-esb.xml, archive name etc.
*
* The BeanMeatData is then attached to the Microcontainers deployment unit
* and will be picked up by the BeanMetaDataDeployer.
*
* @param deploymentUnit The deployment unit to deploy.
* @param esbMetaData The ESB MetaData that is associated with the deployment unit.
*/
@Override
public final void deploy(final VFSDeploymentUnit deploymentUnit, final EsbMetaData esbMetaData) throws org.jboss.deployers.spi.DeploymentException
{
try
{
final BeanMetaData beanMetaData = createBeanMetaData(deploymentUnit, esbMetaData);
deploymentUnit.addAttachment(BeanMetaData.class.getName() + "_ESB", beanMetaData);
log.debug("Created beanMetaData : " + beanMetaData);
}
catch (final DeploymentException e)
{
throw new org.jboss.deployers.spi.DeploymentException(e.getMessage(), e);
}
catch (final IOException e)
{
throw new org.jboss.deployers.spi.DeploymentException(e.getMessage(), e);
}
}
/**
* Creates a {@link BeanMetaData} that describes the
*
* @param deploymentUnit The deployment unit to deploy.
* @param esbMetaData The ESB MetaData that is associated with the deployment unit.
* @return BeanMetaData The {@link BeanMetaData} describing the EsbDeployment.
*
* @throws IOException
* @throws DeploymentException
*/
private BeanMetaData createBeanMetaData(final VFSDeploymentUnit deploymentUnit, final EsbMetaData esbMetaData) throws DeploymentException, IOException
{
log.debug(esbMetaData);
BeanMetaDataBuilder bmdBuilder = BeanMetaDataBuilder.createBuilder(esbBeanPrefix + "." + deploymentUnit.getName(), EsbDeployment.class.getName());
// Setup the first constructor argument (esb meta data).
bmdBuilder.addConstructorParameter(EsbMetaData.class.getName(), esbMetaData);
// Setup the second constructor argument (the name of the mbean).
final String mbeanName = esbBeanPrefix + ":deployment=" + deploymentUnit.getSimpleName();
bmdBuilder.addConstructorParameter(String.class.getName(), mbeanName);
// Setup the third constructor argument (vfs deployment unit).
bmdBuilder.addConstructorParameter(VFSDeploymentUnit.class.getName(), deploymentUnit);
if (warFilesDir == null)
{
final String errorMsg = String.format("No property named '%s' was configured in jbossesb.sar/META-INF/jboss-service.xml for %s", "warFilesDir", getClass().getName());
throw new DeploymentException(errorMsg);
}
final File tmpDir = new File(warFilesDir);
if (!tmpDir.exists())
{
final String errorMsg = String.format("The directory configured for %s='%s' does not exist.", "warFilesDir", tmpDir);
throw new DeploymentException(errorMsg);
}
// Setup the fourth constructor argument (temp war directory).
File esbWarFiles = JBossDeployerUtil.createDir(tmpDir, "esbwarfiles");
bmdBuilder.addConstructorParameter(File.class.getName(), esbWarFiles);
// Add management annotation.
bmdBuilder.addAnnotation("@org.jboss.aop.microcontainer.aspects.jmx.JMX(registerDirectly=true, exposedInterface=void.class, name=\"" + mbeanName + "\")");
// Add default dependencies.
for (String dependency : defaultDeps)
{
bmdBuilder.addDependency(dependency);
}
// Add the dependencies for this deployment.
Set<ObjectName> dependencies = esbMetaData.getDependencies();
for (ObjectName objectName : dependencies)
{
// The dependencies are added as demands. If we add them as dependencies
// they will get undeployed when this unit is undeployed.
log.debug("Adding depend " + objectName.toString() + " for " + esbMetaData.getDeploymentName());
bmdBuilder.addDemand(objectName.toString(), ControllerState.PRE_INSTALL, ControllerState.INSTALLED, null);
}
if (esbMetaData.getPublishers().size() > 0)
{
// set publishers on the deployment instance, or rather tell MC to do this for us.
log.debug("Adding publishers : " + esbMetaData.getPublishers());
bmdBuilder.addPropertyMetaData("publishers", esbMetaData.getPublishers());
}
if (esbMetaData.getServlets().size() > 0)
{
// set servlets on the deployment instance, or rather tell MC to do this for us.
log.debug("Adding servlets : " + esbMetaData.getServlets());
bmdBuilder.addPropertyMetaData("servlets", esbMetaData.getServlets());
}
bmdBuilder.addPropertyMetaData("mainDeployer", mainDeployer);
return bmdBuilder.getBeanMetaData();
}
public void setEsbBeanPrefix(final String prefix)
{
this.esbBeanPrefix = prefix;
}
public String getEsbBeanPrefix()
{
return esbBeanPrefix;
}
public void setDefaultDependencies(final List<String> deps)
{
if (deps != null)
{
defaultDeps.addAll(deps);
}
}
public List<String> getDefaultDependencies()
{
return Collections.unmodifiableList(defaultDeps);
}
}