/*
* JBoss, Home of Professional Open Source
* Copyright 2008-11, Red Hat Middleware LLC, and others contributors as indicated
* by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* 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,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.savara.scenario.simulator.switchyard;
import java.util.Hashtable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.xml.namespace.QName;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.jboss.weld.environment.se.events.ContainerInitialized;
import org.savara.common.resources.ResourceLocator;
import org.savara.scenario.model.Event;
import org.savara.scenario.model.ReceiveEvent;
import org.savara.scenario.model.Role;
import org.savara.scenario.model.SendEvent;
import org.savara.scenario.simulation.RoleSimulator;
import org.savara.scenario.simulation.SimulationContext;
import org.savara.scenario.simulation.SimulationHandler;
import org.savara.scenario.simulation.SimulationModel;
import org.savara.scenario.simulator.switchyard.binding.soap.OutboundHandler;
import org.savara.scenario.simulator.switchyard.binding.soap.deploy.SOAPActivator;
import org.savara.scenario.simulator.switchyard.internal.MessageStore;
import org.switchyard.deploy.Activator;
import org.switchyard.standalone.SwitchYard;
/**
* The Switchyard based implementation of the RoleSimulator.
*
*/
public class SwitchyardRoleSimulator implements RoleSimulator {
private static final String BINDING_CONTEXT = "java:comp";
private static final String BEAN_MANAGER_NAME = "BeanManager";
private static final String SWITCHYARD_SIMULATOR = "Switchyard simulator";
private static final String SWITCHYARD_DESCRIPTOR = "switchyard.xml";
private SimulationContext _context=null;
private SwitchYard _switchyard=null;
private SOAPActivator _activator=null;
private MessageStore _messageStore=new MessageStore();
private int _eventCounter=0;
private static final Logger LOG=Logger.getLogger(SwitchyardRoleSimulator.class.getName());
/**
* {@inheritDoc}
*/
public String getName() {
return SWITCHYARD_SIMULATOR;
}
/**
* {@inheritDoc}
*/
public void initialize(SimulationContext context) throws Exception {
_context = context;
if (_messageStore != null) {
_messageStore.setSimulationContext(context);
}
if (context.getModel() instanceof java.io.File) {
java.io.InputStream is=new java.io.FileInputStream(
(java.io.File)context.getModel());
_switchyard = new SwitchYard(is);
is.close();
// Configure the JNDI factory
System.getProperties().put(InitialContext.INITIAL_CONTEXT_FACTORY, JNDIFactory.class.getName());
_switchyard.start();
for (Activator activator : _switchyard.getActivatorList()) {
if (activator instanceof SOAPActivator) {
_activator = (SOAPActivator)activator;
for (OutboundHandler oh : _activator.getOutboundHandlers().values()) {
oh.setMessageStore(_messageStore);
}
break;
}
}
}
}
/**
* This method returns the activator.
*
* @return The activator
*/
protected SOAPActivator getActivator() {
return (_activator);
}
/**
* This method indicates whether the supplied model is supported.
*
* @param model The simulation model information
* @return Whether the model is supported by this role simulator
*/
public boolean isSupported(SimulationModel model) {
return(model.getName().endsWith(SWITCHYARD_DESCRIPTOR));
}
/**
* {@inheritDoc}
*/
public Object getModel(SimulationModel model, ResourceLocator locator) {
Object ret=null;
if (model.getName().endsWith(SWITCHYARD_DESCRIPTOR)) {
try {
ret = new java.io.File(model.getName());
if (!((java.io.File)ret).exists()) {
ret = null;
java.net.URL url=Thread.currentThread().getContextClassLoader().getResource(model.getName());
if (url != null) {
ret = new java.io.File(url.getFile());
if (!((java.io.File)ret).exists()) {
ret = null;
}
}
}
} catch(Throwable e) {
LOG.log(Level.SEVERE, "Failed to load Switchyard descriptor model", e);
}
}
return(ret);
}
/**
* {@inheritDoc}
*/
public List<Role> getModelRoles(Object model) {
return(java.util.Collections.emptyList());
}
/**
* {@inheritDoc}
*/
public Object getModelForRole(Object model, Role role, ResourceLocator locator) {
return null;
}
/**
* {@inheritDoc}
*/
public void onEvent(SimulationContext context, final Event event,
final SimulationHandler handler) {
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("onEvent "+event);
}
// Associate handler with message store
_messageStore.setHandler(handler);
if (event instanceof ReceiveEvent) {
final ReceiveEvent recv=(ReceiveEvent)event;
incrementEventCounter();
if (_activator.getInboundHandler().isOperation(recv.getOperationName())) {
LOG.fine("Invoke REQUEST: "+recv);
Thread t=new Thread(new Runnable() {
public void run() {
try {
java.io.InputStream is=
_context.getResource(recv.getParameter().get(0).getValue());
byte[] b=new byte[is.available()];
is.read(b);
is.close();
handler.processed(recv);
String resp=_activator.getInboundHandler().invoke(
recv.getOperationName(), new String(b),
QName.valueOf(recv.getParameter().get(0).getType()));
if (resp != null) {
_messageStore.waitForSendEvent(recv.getOperationName(),
resp);
}
} catch (Throwable t) {
LOG.log(Level.SEVERE, "Failed to invoke service", t);
}
decrementEventCounter();
}
});
t.start();
} else {
LOG.fine("Receive RESPONSE: "+recv);
try {
_messageStore.handleReceiveEvent(recv);
} catch(Throwable t) {
handler.error("Failed to handle receive event", event, t);
}
decrementEventCounter();
}
} else if (event instanceof SendEvent) {
SendEvent send=(SendEvent)event;
incrementEventCounter();
// Should block waiting for sent event
try {
_messageStore.handleSendEvent(send);
} catch(Throwable t) {
handler.error("Failed to handle send event", event, t);
}
decrementEventCounter();
}
}
protected void incrementEventCounter() {
synchronized(this) {
_eventCounter++;
if (LOG.isLoggable(Level.FINEST)) {
LOG.finest("Increment event counter: "+_eventCounter);
}
}
}
protected void decrementEventCounter() {
synchronized(this) {
_eventCounter--;
if (LOG.isLoggable(Level.FINEST)) {
LOG.finest("Decrement event counter: "+_eventCounter);
}
this.notifyAll();
}
}
/**
* {@inheritDoc}
*/
public void close(SimulationContext context) throws Exception {
// Delay until all events handled
synchronized(this) {
while (_eventCounter > 0) {
wait(5000);
}
}
// Close the message store
if (_messageStore != null) {
_messageStore.close();
}
// Close switchyard
if (_switchyard != null) {
_switchyard.stop();
}
}
public static class JNDIFactory implements javax.naming.spi.InitialContextFactory {
public Context getInitialContext(Hashtable<?, ?> environment)
throws NamingException {
return new JNDIContext();
}
}
public static class JNDIContext implements javax.naming.Context {
java.util.Map<String, Object> _contents=new java.util.HashMap<String, Object>();
private static Weld _weld;
private static WeldContainer _weldContainer;
static {
_weld = new Weld();
_weldContainer = _weld.initialize();
_weldContainer.event().select(ContainerInitialized.class).fire(new ContainerInitialized());
}
public Object lookup(Name name) throws NamingException {
return (lookup(name.toString()));
}
public Object lookup(String name) throws NamingException {
if (!_contents.containsKey(name)) {
if (name.equals(BINDING_CONTEXT)) {
return (this);
} else if (name.equals(BEAN_MANAGER_NAME)) {
return (_weldContainer.getBeanManager());
}
throw new NamingException("Item '"+name+"' not found");
}
return (_contents.get(name));
}
public void bind(Name name, Object obj) throws NamingException {
// TODO Auto-generated method stub
}
public void bind(String name, Object obj) throws NamingException {
// TODO Auto-generated method stub
}
public void rebind(Name name, Object obj) throws NamingException {
// TODO Auto-generated method stub
}
public void rebind(String name, Object obj) throws NamingException {
// TODO Auto-generated method stub
}
public void unbind(Name name) throws NamingException {
// TODO Auto-generated method stub
}
public void unbind(String name) throws NamingException {
// TODO Auto-generated method stub
}
public void rename(Name oldName, Name newName) throws NamingException {
// TODO Auto-generated method stub
}
public void rename(String oldName, String newName)
throws NamingException {
// TODO Auto-generated method stub
}
public NamingEnumeration<NameClassPair> list(Name name)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public NamingEnumeration<NameClassPair> list(String name)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public NamingEnumeration<Binding> listBindings(Name name)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public NamingEnumeration<Binding> listBindings(String name)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public void destroySubcontext(Name name) throws NamingException {
// TODO Auto-generated method stub
}
public void destroySubcontext(String name) throws NamingException {
// TODO Auto-generated method stub
}
public Context createSubcontext(Name name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Context createSubcontext(String name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Object lookupLink(Name name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Object lookupLink(String name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public NameParser getNameParser(Name name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public NameParser getNameParser(String name) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Name composeName(Name name, Name prefix) throws NamingException {
// TODO Auto-generated method stub
return null;
}
public String composeName(String name, String prefix)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Object removeFromEnvironment(String propName)
throws NamingException {
// TODO Auto-generated method stub
return null;
}
public Hashtable<?, ?> getEnvironment() throws NamingException {
// TODO Auto-generated method stub
return null;
}
public void close() throws NamingException {
// TODO Auto-generated method stub
}
public String getNameInNamespace() throws NamingException {
// TODO Auto-generated method stub
return null;
}
}
}