/* * JBoss, Home of Professional Open Source * Copyright 2008, 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.protocol; import java.net.URI; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.savara.common.logging.JournalLogger; import org.savara.common.resources.ResourceLocator; import org.savara.protocol.util.ProtocolServices; import org.savara.scenario.model.Event; import org.savara.scenario.model.MessageEvent; 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.protocol.internal.Message; import org.savara.scenario.simulator.protocol.internal.MonitorContextImpl; import org.scribble.common.logging.CachedJournal; import org.scribble.common.logging.ConsoleJournal; import org.scribble.common.resource.ByteArrayContent; import org.scribble.common.resource.Content; import org.scribble.protocol.DefaultProtocolContext; import org.scribble.protocol.export.monitor.MonitorProtocolExporter; import org.scribble.protocol.model.ProtocolModel; import org.scribble.protocol.monitor.DefaultSession; import org.scribble.protocol.monitor.MonitorContext; import org.scribble.protocol.monitor.ProtocolMonitor; import org.scribble.protocol.monitor.ProtocolMonitorFactory; import org.scribble.protocol.monitor.Result; import org.scribble.protocol.monitor.Session; import org.scribble.protocol.monitor.model.Description; import org.scribble.protocol.monitor.util.MonitorModelUtil; /** * This class provides the scribble implementation of the Role Simulator interface. * */ public class ProtocolRoleSimulator implements RoleSimulator { private static Logger LOG=Logger.getLogger(ProtocolRoleSimulator.class.getName()); public static final String PROTOCOL_SIMULATOR = "Protocol simulator"; private ProtocolMonitor _monitor=ProtocolMonitorFactory.createProtocolMonitor(); private MonitorProtocolExporter _exporter=new MonitorProtocolExporter(); private MonitorContext _context=new MonitorContextImpl(); /** * {@inheritDoc} */ public String getName() { return PROTOCOL_SIMULATOR; } /** * {@inheritDoc} */ public void initialize(SimulationContext context) throws Exception { if (context.getModel() == null) { LOG.severe("Cannot initialize role simulator without a model"); } else if (!(context.getModel() instanceof Description)) { LOG.severe("Unable to initialize role simulator due to incorrect model type"); } else { context.getProperties().put(Session.class.getName(), _monitor.createSession(_context, (Description)context.getModel(), DefaultSession.class)); } // Add the fork/join extension to the protocol monitor exporter _exporter.setMonitorExportVisitor( new org.savara.protocol.export.monitor.ForkJoinMonitorExportVisitor()); } /** * {@inheritDoc} */ public boolean isSupported(SimulationModel model) { Content content=new ByteArrayContent(model.getName(), null); return (ProtocolServices.getParserManager().isParserAvailable(content)); } /** * {@inheritDoc} */ public Object getModel(SimulationModel model, final ResourceLocator locator) { Object ret=null; if (LOG.isLoggable(Level.FINE)) { LOG.fine("Get model for '"+model.getName()+"'"); } try { java.io.InputStream is=model.getContents(); byte[] b=new byte[is.available()]; is.read(b); is.close(); Content content=new ByteArrayContent(model.getName(), b); CachedJournal journal=new CachedJournal(); org.scribble.common.resource.ResourceLocator res= new org.scribble.common.resource.ResourceLocator() { public URI getResourceURI(String arg0) throws Exception { return locator.getResourceURI(arg0); } }; DefaultProtocolContext context= new DefaultProtocolContext(ProtocolServices.getParserManager(), res); ret = ProtocolServices.getParserManager().parse(context, content, journal); if (journal.hasErrors()) { LOG.severe("Failed to parse model '"+model.getName()+""); journal.apply(new ConsoleJournal()); ret = null; } } catch(Exception e) { LOG.log(Level.SEVERE, "Failed to get model", e); } if (LOG.isLoggable(Level.FINE)) { LOG.fine("Returning model for '"+model.getName()+"' = "+ret); } return (ret); } /** * {@inheritDoc} */ public List<Role> getModelRoles(Object model) { if (model instanceof ProtocolModel) { java.util.List<Role> ret=new java.util.Vector<Role>(); if (((ProtocolModel)model).isLocated()) { Role role=new Role(); role.setName(((ProtocolModel)model).getProtocol().getLocatedRole().getName()); ret.add(role); } else { for (org.scribble.protocol.model.Role r : ((ProtocolModel)model).getRoles()) { Role role=new Role(); role.setName(r.getName()); ret.add(role); } } return (ret); } return (Collections.emptyList()); } /** * {@inheritDoc} */ public Object getModelForRole(Object model, Role role, final ResourceLocator locator) { Object ret=null; org.scribble.common.resource.ResourceLocator res= new org.scribble.common.resource.ResourceLocator() { public URI getResourceURI(String arg0) throws Exception { return locator.getResourceURI(arg0); } }; DefaultProtocolContext context= new DefaultProtocolContext(ProtocolServices.getParserManager(), res); CachedJournal journal=new CachedJournal(); ProtocolModel local=null; if (((ProtocolModel)model).isLocated()) { if (((ProtocolModel)model).getProtocol().getLocatedRole().getName().equals(role.getName())) { local = (ProtocolModel)model; } } else { local = ProtocolServices.getProtocolProjector().project(context, (ProtocolModel)model, new org.scribble.protocol.model.Role(role.getName()), journal); } if (journal.hasErrors()) { //LOG.log(Level.SEVERE, "Errors detected projecting located protocol model for export to monitor description"); journal.apply(new JournalLogger()); local = null; } else if (local != null) { try { // Convert protocol model to monitoring description java.io.ByteArrayOutputStream os=new java.io.ByteArrayOutputStream(); _exporter.export(local, journal, os); os.close(); if (journal.hasErrors()) { //LOG.severe("Errors detected when exporting protocol '"+ // local+"' to monitorable description"); journal.apply(new ConsoleJournal()); ret = null; } else { java.io.InputStream is=new java.io.ByteArrayInputStream(os.toByteArray()); ret = MonitorModelUtil.deserialize(is); is.close(); } } catch(Exception e) { LOG.log(Level.SEVERE, "Failed to export monitor description for located protocol model", e); ret = null; } } else { LOG.log(Level.SEVERE, "Failed to obtain located protocol model for export to monitor description"); } return (ret); } /** * {@inheritDoc} */ public void onEvent(SimulationContext context, Event event, SimulationHandler handler) { if (event instanceof MessageEvent) { MessageEvent me=(MessageEvent)event; if (me.getParameter().size() == 1) { String type=me.getParameter().get(0).getType(); String path=me.getParameter().get(0).getValue(); java.io.Serializable value=null; if (path != null) { try { java.io.InputStream is=context.getResource(path); byte[] b=new byte[is.available()]; is.read(b); is.close(); // Assume value is text value = new String(b); } catch(Exception e) { handler.error("Failed to obtain message value", event, e); } } try { Message mesg=new Message(); mesg.setOperator(((MessageEvent) event).getOperationName()); mesg.setFault(((MessageEvent) event).getFaultName()); mesg.getTypes().add(type); mesg.getValues().add((String)value); Result result=null; if (event instanceof SendEvent) { result = _monitor.messageSent(_context, (Description)context.getModel(), (Session)context.getProperties().get(Session.class.getName()), mesg); } else if (event instanceof ReceiveEvent) { result = _monitor.messageReceived(_context, (Description)context.getModel(), (Session)context.getProperties().get(Session.class.getName()), mesg); } if (result.isValid()) { handler.processed(event); } else { handler.unexpected(event); } } catch(Exception e) { handler.error("Failed to simulate message", event, e); } } else { handler.error("Cannot simulate event as does not have single parameter", event, null); } } } /** * {@inheritDoc} */ public void close(SimulationContext context) throws Exception { } }