diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/LMHWorkflow.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/LMHWorkflow.java index c97e6b97c474340874571f5c7fb265bed79293b2..6a589787607a3d0de3ae51d1c33d7c84f0f91235 100644 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/LMHWorkflow.java +++ b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/LMHWorkflow.java @@ -1,20 +1,14 @@ package info.kwarc.sally4.mathhubworker.impl; import info.kwarc.sally4.core.CamelContextProvider; -import info.kwarc.sally4.core.SallyInteractionResultAcceptor; -import info.kwarc.sally4.core.SallyService; -import info.kwarc.sally4.core.SallyServiceProvider; import info.kwarc.sally4.docmanager.AlexRoute; import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; import info.kwarc.sally4.mathhubworker.MathHubWorkerManager; -import info.kwarc.sally4.mathhubworker.internal.comm.GetLMHWorkers; -import info.kwarc.sally4.mathhubworker.routes.LMHRoute; - -import java.util.HashMap; -import java.util.Map; +import info.kwarc.sally4.mathhubworker.routes.LMHWorkflowInstance; import org.apache.camel.CamelContext; -import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultCamelContext; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Instantiate; import org.apache.felix.ipojo.annotations.Provides; @@ -22,37 +16,20 @@ import org.apache.felix.ipojo.annotations.Requires; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - @Component @Instantiate @Provides -public class LMHWorkflow extends WorkflowCommon implements IDocWorkflow, SallyServiceProvider { +public class LMHWorkflow implements IDocWorkflow { @Requires CamelContextProvider camelContextProvider; @Requires MathHubWorkerManager workerManager; - - Map<String, CamelContext> routeContexts; - Map<String, String> routeWorkerIDs; Logger log; public LMHWorkflow() { log = LoggerFactory.getLogger(getClass()); - routeContexts = new HashMap<String, CamelContext>(); - routeWorkerIDs = new HashMap<String, String>(); - } - - public void setWorkerKey(String AlexRouteID, String workerID) { - routeWorkerIDs.put(AlexRouteID, workerID); - } - - @SallyService - public void getLMHWorkers(GetLMHWorkers click, SallyInteractionResultAcceptor acceptor, Exchange context) { - for (String s : routeWorkerIDs.values()) { - acceptor.acceptResult(s); - } } @Override @@ -66,42 +43,16 @@ public class LMHWorkflow extends WorkflowCommon implements IDocWorkflow, SallySe } @Override - public boolean handleMessage(AlexRoute route, String namespace, String type, - Exchange exchange) { - - return false; - } - - @Override - public void startRoutes(CamelContext camelContext, final AlexRoute route) { - workerManager.addNewWorker(route); + public IDocWorkflowInstance createDocumentInstance(AlexRoute route) { + CamelContext context = new DefaultCamelContext(); + LMHWorkflowInstance lmhWorkflowInstance = new LMHWorkflowInstance(route); try { - camelContext.addRoutes(new LMHRoute(route, this)); - camelContext.addComponent("mhw", route.getAlexComponent()); - camelContext.start(); - camelContext.createProducerTemplate().sendBody("direct:start", ""); - - route.addOnStopHandler(new Runnable() { - - @Override - public void run() { - routeWorkerIDs.remove(route.getID()); - } - }); + context.addRoutes(lmhWorkflowInstance); + context.start(); } catch (Exception e) { e.printStackTrace(); } - - } - - @Override - public String[] getContextComponentsToCopy() { - return new String[]{"activemq"}; - } - - @Override - public CamelContextProvider getCamelContextProvider() { - return camelContextProvider; + return lmhWorkflowInstance; } } diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/MathHubEnvironment.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/MathHubEnvironment.java index a362f62564f0cb204aa87134b990853da7c515b0..08ecec31465e3bce71a0da6f4168fc5d0efd786b 100644 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/MathHubEnvironment.java +++ b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/MathHubEnvironment.java @@ -18,12 +18,12 @@ public class MathHubEnvironment { } public void addWorker(final AlexRoute worker) { - workers.put(worker.getID(), worker); + workers.put(worker.getDocQueue(), worker); worker.addOnStopHandler(new Runnable() { @Override public void run() { - workers.remove(worker.getID()); + workers.remove(worker.getDocQueue()); if (workers.size() == 0 && onEmpty != null) { onEmpty.run(); } diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/PlanetaryClientWorkflow.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/PlanetaryClientWorkflow.java index 82ebce787e221a117ae5f86272d5de4a6b802605..1cda804e2a376dceffc3f2c4cc167c35e40ab7d0 100644 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/PlanetaryClientWorkflow.java +++ b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/PlanetaryClientWorkflow.java @@ -1,27 +1,16 @@ package info.kwarc.sally4.mathhubworker.impl; -import info.kwarc.sally.comm.planetaryclient.NewService; import info.kwarc.sally4.core.CamelContextProvider; import info.kwarc.sally4.core.SallyInteraction; import info.kwarc.sally4.docmanager.AlexRoute; import info.kwarc.sally4.docmanager.IDocWorkflow; -import info.kwarc.sally4.marshalling.MarshallUtils; -import info.kwarc.sally4.mathhubworker.internal.comm.GetLMHWorkers; -import info.kwarc.sally4.mathhubworker.routes.PlanetaryClientRoute; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; +import info.kwarc.sally4.mathhubworker.routes.PlanetaryClientWorkflowInstance; import info.kwarc.sally4.planetary.PlanetaryConnection; import info.kwarc.sally4.servlet.SallyServlet; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; - -import javax.xml.ws.RequestWrapper; - import org.apache.camel.CamelContext; -import org.apache.camel.Exchange; -import org.apache.camel.Property; -import org.apache.camel.RecipientList; +import org.apache.camel.impl.DefaultCamelContext; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Instantiate; import org.apache.felix.ipojo.annotations.Invalidate; @@ -32,7 +21,7 @@ import org.apache.felix.ipojo.annotations.Validate; @Component @Instantiate @Provides -public class PlanetaryClientWorkflow extends WorkflowCommon implements IDocWorkflow { +public class PlanetaryClientWorkflow implements IDocWorkflow { String planetaryClientNamespace = "http://kwarc.info/sally/comm/planetaryclient"; @Requires @@ -53,27 +42,8 @@ public class PlanetaryClientWorkflow extends WorkflowCommon implements IDocWorkf @Invalidate public void stop() { - - } - - @Override - public String[] getContextComponentsToCopy() { - return new String[] {"activemq", "planetary"}; } - public void startRoutes(CamelContext camelContext, AlexRoute route) { - camelContext.addComponent("alex", route.getAlexComponent()); - - try { - camelContext.start(); - camelContext.addRoutes(new PlanetaryClientRoute(this)); - camelContext.createProducerTemplate().sendBody("direct:start", route); - } catch (Exception e) { - log.error(e.getMessage()); - e.printStackTrace(); - } - } - public String[] getInterfaceRequirements() { return new String[]{"planetaryclient"}; } @@ -81,60 +51,23 @@ public class PlanetaryClientWorkflow extends WorkflowCommon implements IDocWorkf public String[] getHandlingNamespaces() { return new String[] { planetaryClientNamespace }; } - - public List<String> getFreeAvailableKeys(Exchange e) { - @SuppressWarnings("unchecked") - List<HashMap<String, String>> takenKeys = (List<HashMap<String, String>>) e.getIn().getBody(List.class); - HashSet<String> taken = new HashSet<String>(); - for (HashMap<String, String> takenKey : takenKeys) { - taken.add(takenKey.get("key")); - } - List<String> result = new ArrayList<String>(); - List<String> availableKeys = interact.getPossibleInteractions(new GetLMHWorkers(), String.class, e); - for (String aKey : availableKeys) { - if (taken.contains(result)) - continue; - availableKeys.add(aKey); - } - return result; - } - // very simple - public String getNewMHW(List<String> availableKeys, @Property("uid") Long uid) { - if (availableKeys.size()==0) - return null; - return availableKeys.get(0); - } - - public void addService(AlexRoute route, NewService serviceDesk) { + @Override + public IDocWorkflowInstance createDocumentInstance(AlexRoute route) { + CamelContext context = new DefaultCamelContext(); - } - - public boolean handleMessage(AlexRoute route, String namespace, String type, Exchange exchange) { - CamelContext context = this.routeContexts.get(route.getID()); - if (context == null) // should not really happen - return false; - - log.info("responding to "+type); - if (type.equals("GetServices")) { - NewService serv = new NewService(); - String host = "http://localhost:8181/sally"; - serv.setIcon(host+"/planetary/libs/mhwsettings.png"); - serv.setId("mhwsettings"); - serv.setName("Math Hub Worker Settings"); - serv.setType("toolbar"); - serv.setUrl(host+"/planetary/mhwsettings?id="+route.getID()); - String xml = MarshallUtils.marshallToXML("planetaryclient", serv, getClass().getClassLoader()); - log.info("sending back"+xml); - exchange.getIn().setBody(xml); - return true; + PlanetaryClientWorkflowInstance planetaryWorkflowInstance = new PlanetaryClientWorkflowInstance( + camelContextProvider.getComponent("activemq"), + route.getAlexComponent(), + camelContextProvider.getComponent("planetary"), + interact); + + try { + context.addRoutes(planetaryWorkflowInstance); + context.start(); + } catch (Exception e) { + e.printStackTrace(); } - return false; + return planetaryWorkflowInstance; } - - @Override - public CamelContextProvider getCamelContextProvider() { - return camelContextProvider; - } - } diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/WorkflowCommon.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/WorkflowCommon.java deleted file mode 100644 index c72ef61407d6c24c37b35d43cf4c56698817d361..0000000000000000000000000000000000000000 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/impl/WorkflowCommon.java +++ /dev/null @@ -1,59 +0,0 @@ -package info.kwarc.sally4.mathhubworker.impl; - -import info.kwarc.sally4.core.CamelContextProvider; -import info.kwarc.sally4.docmanager.AlexRoute; -import info.kwarc.sally4.docmanager.IDocWorkflow; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.camel.CamelContext; -import org.apache.camel.impl.DefaultCamelContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class WorkflowCommon implements IDocWorkflow { - Map<String, CamelContext> routeContexts; - Logger log; - - - public WorkflowCommon() { - log = LoggerFactory.getLogger(getClass()); - routeContexts = new HashMap<String, CamelContext>(); - } - - public abstract void startRoutes(CamelContext camelContext, AlexRoute route); - public abstract String [] getContextComponentsToCopy(); - public abstract CamelContextProvider getCamelContextProvider(); - - public void onNewDocument(final AlexRoute route) { - CamelContext camelContext = new DefaultCamelContext(); - camelContext.getShutdownStrategy().setTimeout(1); - CamelContextProvider camelGlobalProvider = getCamelContextProvider(); - - for (String comp : getContextComponentsToCopy()) { - camelContext.addComponent(comp, camelGlobalProvider.getComponent(comp)); - } - - routeContexts.put(route.getID(), camelContext); - - route.addOnStopHandler(new Runnable() { - - public void run() { - try { - if (routeContexts.containsKey(route.getID())) { - routeContexts.get(route.getID()).stop(); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - routeContexts.remove(route); - } - } - }); - - startRoutes(camelContext, route); - - - } -} diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHRoute.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHWorkflowInstance.java similarity index 65% rename from MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHRoute.java rename to MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHWorkflowInstance.java index cde74a9dc2d17ba207711cb7b991b1b9f1fc2eb9..b2df397069eee8bbf42660ca2b81bfedfc3e09ac 100644 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHRoute.java +++ b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/LMHWorkflowInstance.java @@ -3,32 +3,32 @@ package info.kwarc.sally4.mathhubworker.routes; import info.kwarc.sally.comm.mathhubworker.GetAuthKeyRequest; import info.kwarc.sally.comm.mathhubworker.GetAuthKeyResponse; import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; import info.kwarc.sally4.marshalling.CommUtils; -import info.kwarc.sally4.mathhubworker.impl.LMHWorkflow; +import org.apache.camel.Exchange; import org.apache.camel.ExchangeTimedOutException; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.spi.DataFormat; -public class LMHRoute extends RouteBuilder { +public class LMHWorkflowInstance extends RouteBuilder implements IDocWorkflowInstance { - AlexRoute thisRoute; - LMHWorkflow thisWorklow; + AlexRoute route; - public LMHRoute(AlexRoute thisRoute, LMHWorkflow thisWorkflow) { - this.thisRoute = thisRoute; - this.thisWorklow = thisWorkflow; + public LMHWorkflowInstance(AlexRoute route) { + this.route = route; } public void setWorkerKey(GetAuthKeyResponse response) { - thisWorklow.setWorkerKey(thisRoute.getID(), response.getAuthkey()); +// thisWorklow.setWorkerKey(route.getID(), response.getAuthkey()); } @Override public void configure() throws Exception { DataFormat worker = CommUtils.getDataFormat("mathhubworker", getClass().getClassLoader()); + getContext().addComponent("alex", route.getAlexComponent()); from("direct:start") .to("direct:requestAuthKey"); @@ -47,4 +47,16 @@ public class LMHRoute extends RouteBuilder { .bean(method(this, "setWorkerKey")); } + @Override + public boolean handleMessage(AlexRoute route, String namespace, + String type, Exchange exchange) { + return false; + } + + @Override + public void stop() { + // TODO Auto-generated method stub + + } + } diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientRoute.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientRoute.java deleted file mode 100644 index 38f73f6306d78be5ba26b08d8dda7a8c4b0df5c5..0000000000000000000000000000000000000000 --- a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientRoute.java +++ /dev/null @@ -1,82 +0,0 @@ -package info.kwarc.sally4.mathhubworker.routes; - -import info.kwarc.sally.comm.planetaryclient.GetSessionIDRequest; -import info.kwarc.sally.comm.planetaryclient.GetSessionIDResponse; -import info.kwarc.sally4.marshalling.CommUtils; -import info.kwarc.sally4.mathhubworker.impl.PlanetaryClientWorkflow; -import info.kwarc.sally4.processors.FileServeProcessor; - -import org.apache.camel.ExchangeTimedOutException; -import org.apache.camel.LoggingLevel; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.spi.DataFormat; - -public class PlanetaryClientRoute extends RouteBuilder { - - PlanetaryClientWorkflow thisWorkflow; - - public PlanetaryClientRoute(PlanetaryClientWorkflow thisWorkflow) { - this.thisWorkflow = thisWorkflow; - } - - public String getSessionID(GetSessionIDResponse response) { - return response.getSessionid(); - } - - @Override - public void configure() throws Exception { - DataFormat planetaryClient = CommUtils.getDataFormat("planetaryclient", getClass().getClassLoader()); - - from("direct:start") - .to("direct:requestSessionID") - .to("direct:getPlanetaryUser") - .to("direct:assignMHW"); - - - from("direct:requestSessionID") - .setBody(constant(new GetSessionIDRequest())) - .marshal(planetaryClient) - .doTry() - .inOut("alex:requestSession") - .doCatch(ExchangeTimedOutException.class) - .log(LoggingLevel.ERROR,"MathHubRoute","Alex did not respond to GetSessionIDRequest. Ending this route.") - .stop() - .doFinally() - .unmarshal(planetaryClient) - .bean(method(this, "getSessionID")) - .setProperty("sessionid", body()); - - - from("direct:getPlanetaryUser") - .setBody(property("sessionid")) - .inOut("planetary:select uid from sessions where sid=#?outputType=SelectOne") - .setProperty("uid", body()) - .choice() - .when(simple("${body} == null")) - .log(LoggingLevel.ERROR,"MathHubRoute","SessionID could not be found in planetary database.") - .stop() - .endChoice(); - - from("direct:assignMHW") - .inOut("planetary:select 'key' from mhw_assignment where uid=#?outputType=SelectOne") - .choice() - .when(simple("${body} == null")) -// .to("direct:getNewMHW") - .endChoice(); - - /* - from("direct:getNewMHW") - // get already taken keys - .inOut("planetary:select 'key' from mhw_assignment") - // compute list of free and available keys - .bean(thisWorkflow, "getFreeAvailableKeys") - // choose one key based on user info - .bean(thisWorkflow, "getNewMHW") - .choice() - .when(simple("${body} == null")) - .end() - .endChoice() - */ - } - -} diff --git a/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientWorkflowInstance.java b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientWorkflowInstance.java new file mode 100644 index 0000000000000000000000000000000000000000..f17dbc93c94355ed5ec58b4e7245707237528f75 --- /dev/null +++ b/MathHubWorker/src/main/java/info/kwarc/sally4/mathhubworker/routes/PlanetaryClientWorkflowInstance.java @@ -0,0 +1,152 @@ +package info.kwarc.sally4.mathhubworker.routes; + +import info.kwarc.sally.comm.planetaryclient.GetSessionIDRequest; +import info.kwarc.sally.comm.planetaryclient.GetSessionIDResponse; +import info.kwarc.sally.comm.planetaryclient.NewService; +import info.kwarc.sally4.core.SallyInteraction; +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; +import info.kwarc.sally4.marshalling.CommUtils; +import info.kwarc.sally4.marshalling.MarshallUtils; +import info.kwarc.sally4.mathhubworker.internal.comm.GetLMHWorkers; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +import org.apache.camel.Component; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangeTimedOutException; +import org.apache.camel.LoggingLevel; +import org.apache.camel.Property; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.spi.DataFormat; + +public class PlanetaryClientWorkflowInstance extends RouteBuilder implements IDocWorkflowInstance { + + SallyInteraction interact; + Component activemqComponent; + Component alexComponent; + Component planetaryComponent; + + public PlanetaryClientWorkflowInstance(Component activemqComponent, Component alexComponent, Component planetaryComponent, SallyInteraction interact) { + this.interact = interact; + this.activemqComponent = activemqComponent; + this.alexComponent = alexComponent; + this.planetaryComponent = planetaryComponent; + } + + public String getSessionID(GetSessionIDResponse response) { + return response.getSessionid(); + } + + public List<String> getFreeAvailableKeys(Exchange e) { + @SuppressWarnings("unchecked") + List<HashMap<String, String>> takenKeys = (List<HashMap<String, String>>) e.getIn().getBody(List.class); + HashSet<String> taken = new HashSet<String>(); + for (HashMap<String, String> takenKey : takenKeys) { + taken.add(takenKey.get("key")); + } + List<String> result = new ArrayList<String>(); + List<String> availableKeys = interact.getPossibleInteractions(new GetLMHWorkers(), String.class, e); + for (String aKey : availableKeys) { + if (taken.contains(result)) + continue; + availableKeys.add(aKey); + } + return result; + } + + // very simple + public String getNewMHW(List<String> availableKeys, @Property("uid") Long uid) { + if (availableKeys.size()==0) + return null; + return availableKeys.get(0); + } + + @Override + public void configure() throws Exception { + DataFormat planetaryClient = CommUtils.getDataFormat("planetaryclient", getClass().getClassLoader()); + getContext().addComponent("activemq", activemqComponent); + getContext().addComponent("alex", alexComponent); + getContext().addComponent("planetary", planetaryComponent); + + from("direct:start") + .to("direct:requestSessionID") + .to("direct:getPlanetaryUser") + .to("direct:assignMHW"); + + + from("direct:requestSessionID") + .setBody(constant(new GetSessionIDRequest())) + .marshal(planetaryClient) + .doTry() + .inOut("alex:requestSession") + .doCatch(ExchangeTimedOutException.class) + .log(LoggingLevel.ERROR,"MathHubRoute","Alex did not respond to GetSessionIDRequest. Ending this route.") + .stop() + .doFinally() + .unmarshal(planetaryClient) + .bean(method(this, "getSessionID")) + .setProperty("sessionid", body()); + + + from("direct:getPlanetaryUser") + .setBody(property("sessionid")) + .inOut("planetary:select uid from sessions where sid=#?outputType=SelectOne") + .setProperty("uid", body()) + .choice() + .when(simple("${body} == null")) + .log(LoggingLevel.ERROR,"MathHubRoute","SessionID could not be found in planetary database.") + .stop() + .endChoice(); + + from("direct:assignMHW") + .inOut("planetary:select 'key' from mhw_assignment where uid=#?outputType=SelectOne") + .choice() + .when(simple("${body} == null")) + // .to("direct:getNewMHW") + .endChoice(); + + /* + from("direct:getNewMHW") + // get already taken keys + .inOut("planetary:select 'key' from mhw_assignment") + // compute list of free and available keys + .bean(thisWorkflow, "getFreeAvailableKeys") + // choose one key based on user info + .bean(thisWorkflow, "getNewMHW") + .choice() + .when(simple("${body} == null")) + .end() + .endChoice() + */ + } + + @Override + public boolean handleMessage(AlexRoute route, String namespace, + String type, Exchange exchange) { + + if (type.equals("GetServices")) { + NewService serv = new NewService(); + String host = "http://localhost:8181/sally"; + serv.setIcon(host+"/planetary/libs/mhwsettings.png"); + serv.setId("mhwsettings"); + serv.setName("Math Hub Worker Settings"); + serv.setType("toolbar"); + serv.setUrl(host+"/planetary/mhwsettings?id="+route.getDocQueue()); + String xml = MarshallUtils.marshallToXML("planetaryclient", serv, getClass().getClassLoader()); + log.info("sending back"+xml); + exchange.getIn().setBody(xml); + return true; + } + return false; + } + + @Override + public void stop() { + + } + +} diff --git a/docmanager/pom.xml b/docmanager/pom.xml index c9303c21a576834f3143d3dd4538de4bd8f4ea18..44e46ce9a9e997ea9f4e8a2833174e57d95833ac 100644 --- a/docmanager/pom.xml +++ b/docmanager/pom.xml @@ -42,13 +42,19 @@ <artifactId>activemq</artifactId> <version>${sally4.version}</version> </dependency> - + <dependency> <groupId>info.kwarc.sally4</groupId> <artifactId>utils</artifactId> <version>${sally4.version}</version> </dependency> + <dependency> + <groupId>info.kwarc.sally4</groupId> + <artifactId>servlet</artifactId> + <version>${sally4.version}</version> + </dependency> + <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.ipojo.annotations</artifactId> diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/AlexRoute.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/AlexRoute.java index b41d18c2521459f18cfafc3178ce50fa89649d54..5ba51ffdef4697f6cd70538a016041dbeb12b975 100644 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/AlexRoute.java +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/AlexRoute.java @@ -1,15 +1,17 @@ package info.kwarc.sally4.docmanager; import info.kwarc.sally4.components.ProducerConsumerSplitterComponent; +import info.kwarc.sally4.processors.TypedCallback; +import info.kwarc.sally4.processors.XMLMessageWithTypeInfo; public interface AlexRoute { - public String getID(); - public String getAlexStateQueue(); - public String getAlexQueue(); + public String getDocStateQueue(); + public String getDocQueue(); public String getEnvironmentID(); public String getUserID(); public ProducerConsumerSplitterComponent getAlexComponent(); public void addOnStopHandler(Runnable r); + public void setMessageHandler(TypedCallback<XMLMessageWithTypeInfo> callback); } diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflow.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflow.java index 009763aef063b4ae363f0866b3a38d7f030cc099..df32659eb70670ff15b4ba8b5a724e256e5ab009 100644 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflow.java +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflow.java @@ -1,11 +1,9 @@ package info.kwarc.sally4.docmanager; -import org.apache.camel.Exchange; public interface IDocWorkflow { String [] getInterfaceRequirements(); String [] getHandlingNamespaces(); - boolean handleMessage(AlexRoute route, String namespace, String type, Exchange exchange); - void onNewDocument(AlexRoute route); + IDocWorkflowInstance createDocumentInstance(AlexRoute route); } diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflowInstance.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflowInstance.java new file mode 100644 index 0000000000000000000000000000000000000000..7b1afefc8db3f025b9d009fc04503c0f6bf78877 --- /dev/null +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/IDocWorkflowInstance.java @@ -0,0 +1,9 @@ +package info.kwarc.sally4.docmanager; + +import org.apache.camel.Exchange; + +public interface IDocWorkflowInstance { + boolean handleMessage(AlexRoute route, String namespace, String type, Exchange exchange); + + void stop(); +} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/TestMain.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/TestMain.java index 4563d6a20c83d75bc1523268a351d44ada5a27af..44b99418e0609c75a478af9f719bb7982d02a2f0 100644 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/TestMain.java +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/TestMain.java @@ -4,7 +4,6 @@ import info.kwarc.sally.comm.core.Heartbeatrequest; import info.kwarc.sally.comm.core.Heartbeatresponse; import info.kwarc.sally.comm.core.Registerdocument; import info.kwarc.sally.comm.core.Registerdocumentresponse; -import info.kwarc.sally4.docmanager.routes.SallyRegisterRoute; import info.kwarc.sally4.marshalling.CommUtils; import info.kwarc.sally4.predicates.BodyHasType; @@ -61,7 +60,7 @@ public class TestMain extends RouteBuilder { from("direct:client-register") .marshal(core) .to("log:too") - .inOut("activemq:queue:"+SallyRegisterRoute.sallyRegisterQueue) + //.inOut("activemq:queue:"+SallyRegisterRoute.sallyRegisterQueue) .unmarshal(core) .process(new Processor() { public void process(Exchange exchange) throws Exception { diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/AlexRouteImpl.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/AlexRouteImpl.java index 51bac57e6aa13cf5044a07e026e2f206f1b7679e..1ff0d42636ef7c4ae40624bb9c67a84ffed4203e 100644 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/AlexRouteImpl.java +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/AlexRouteImpl.java @@ -1,41 +1,37 @@ package info.kwarc.sally4.docmanager.impl; +import info.kwarc.sally.comm.core.Heartbeatrequest; import info.kwarc.sally4.components.ProducerConsumerSplitterComponent; import info.kwarc.sally4.docmanager.AlexRoute; -import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.marshalling.CommUtils; import info.kwarc.sally4.processors.EnrichMessageProperties; +import info.kwarc.sally4.processors.TypedCallback; +import info.kwarc.sally4.processors.XMLMessageWithTypeInfo; -import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Queue; -import java.util.UUID; import org.apache.camel.Exchange; -import org.apache.camel.Header; +import org.apache.camel.ExchangeTimedOutException; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.spi.DataFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class AlexRouteImpl implements AlexRoute { +public class AlexRouteImpl extends RouteBuilder implements AlexRoute { - String alexQueue; + String docQueue; String environmentid; String userid; - HashSet<String> interfaces; + String docStateQueue; + + String[] interfaces; List<Runnable> stopHandlers; - - Queue<IDocWorkflow> workflows; - String ID; - + TypedCallback<XMLMessageWithTypeInfo> messageHandler; Logger log; - String alexStateQueue; - String generateUUID(String doc_queue) { //"/queue/sally_doc_"+UUID.randomUUID().toString() return "sally_doc_"+doc_queue; @@ -49,62 +45,38 @@ public class AlexRouteImpl implements AlexRoute { return userid; } - public void forwardMessage(Exchange e, - @Header(EnrichMessageProperties.MessageNamespace) String namespace, - @Header(EnrichMessageProperties.MessageType) String msgType) { - - Iterator<IDocWorkflow> iter = workflows.iterator(); - while (iter.hasNext()) { - IDocWorkflow work = iter.next(); - for (String s : work.getHandlingNamespaces()) { - if (s.equals(namespace)) { - if (work.handleMessage(this, namespace, msgType, e)) { - return; - } - } - } - } - } - - public AlexRouteImpl(String alexQueue, String environmentid, String userid, Collection<String> interfaces) { + public AlexRouteImpl(String alexQueue, String environmentid, String userid, String[] interfaces) { log = LoggerFactory.getLogger(getClass()); - this.alexQueue = alexQueue; + this.docQueue = alexQueue; this.environmentid = environmentid; this.userid = userid; - this.interfaces = new HashSet<String>(interfaces); - this.alexStateQueue = generateUUID(alexQueue); + this.interfaces = interfaces; + this.docStateQueue = generateUUID(alexQueue); stopHandlers = new ArrayList<Runnable>(); - workflows = new ArrayDeque<IDocWorkflow>(); - ID = UUID.randomUUID().toString(); } - public void addDocumentWorkflow(IDocWorkflow workflow) { - workflows.add(workflow); - workflow.onNewDocument(this); - } - - public void removeDocumentWorkflow(IDocWorkflow workflow) { - workflows.remove(workflow); + public Heartbeatrequest generateHeartbeat() { + return new Heartbeatrequest(); } - public String getAlexStateQueue() { - return alexStateQueue; + public String getDocStateQueue() { + return docStateQueue; } - public String getAlexQueue() { - return alexQueue; + public String getDocQueue() { + return docQueue; } public void addOnStopHandler(Runnable stopHandler) { stopHandlers.add(stopHandler); } - public HashSet<String> getInterfaces() { + public String[] getInterfaces() { return interfaces; } - public void stop() { + public void notifyStop() { for (Runnable r : stopHandlers) { try { r.run(); @@ -112,27 +84,67 @@ public class AlexRouteImpl implements AlexRoute { e.printStackTrace(); } } - } - - @Override - public String getID() { - return ID; + try { + getContext().stopRoute("timer"); + getContext().stop(); + } catch (Exception e) { + e.printStackTrace(); + } } @Override public ProducerConsumerSplitterComponent getAlexComponent() { - return new ProducerConsumerSplitterComponent("activemq:queue:"+alexStateQueue, "activemq:queue:"+alexQueue); + return new ProducerConsumerSplitterComponent("activemq:queue:"+docStateQueue, "activemq:queue:"+docQueue); } @Override public String getEnvironmentID() { - // TODO Auto-generated method stub - return null; + return environmentid; } @Override public String getUserID() { - // TODO Auto-generated method stub - return null; + return userid; + } + + @Override + public void configure() throws Exception { + DataFormat core = CommUtils.getDataFormat("core", getClass().getClassLoader()); + + /** + * Sends a Heartbeat message to the Alex. if it does not respond after 20sec, this route will shutdown. + */ + from("timer://foo?fixedRate=true&period=60000") + .id("timer") + .bean(method(this, "generateHeartbeat")) + .marshal(core) + .doTry() + .inOut("alex:default") + .doCatch(ExchangeTimedOutException.class) + .bean(method(this, "notifyStop")) + .stop(); + + /** + * + */ + from("alex:defaultin") + .convertBodyTo(String.class) + .process(new EnrichMessageProperties()) + .bean(method(this, "triggerOnMessageHandlers")) + .to("log:willsend"); + } + + @Override + public void setMessageHandler(TypedCallback<XMLMessageWithTypeInfo> callback) { + messageHandler = callback; + } + + public String triggerOnMessageHandlers(Exchange exchange) { + XMLMessageWithTypeInfo info = exchange.getIn().getBody(XMLMessageWithTypeInfo.class); + info.setExchange(exchange); + if (messageHandler != null) { + messageHandler.run(info); + } + return exchange.getIn().getBody(String.class); } } diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapter.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..d75eec45835807e04094a68daa1daad8ba48969b --- /dev/null +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapter.java @@ -0,0 +1,153 @@ +package info.kwarc.sally4.docmanager.impl; + +import info.kwarc.sally.comm.core.Registerdocument; +import info.kwarc.sally.comm.core.Registerdocumentresponse; +import info.kwarc.sally4.activemq.ActiveMQService; +import info.kwarc.sally4.components.TemplatingComponent; +import info.kwarc.sally4.core.CamelContextProvider; +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.DocumentManager; +import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.marshalling.CommUtils; +import info.kwarc.sally4.servlet.SallyServlet; + +import java.util.HashMap; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.spi.DataFormat; +import org.apache.felix.ipojo.annotations.Bind; +import org.apache.felix.ipojo.annotations.Component; +import org.apache.felix.ipojo.annotations.Instantiate; +import org.apache.felix.ipojo.annotations.Invalidate; +import org.apache.felix.ipojo.annotations.Provides; +import org.apache.felix.ipojo.annotations.Requires; +import org.apache.felix.ipojo.annotations.Unbind; +import org.apache.felix.ipojo.annotations.Validate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This is the adapter class that manages all documents handled by Sally. + * @author Constantin Jucovschi + * + */ +@Component +@Instantiate +@Provides +public class DocumentManagerAdapter extends RouteBuilder implements DocumentManager { + public static final String sallyRegisterQueue = "sally_register"; + + @Requires(optional=true) + IDocWorkflow[] workflows; + + @Requires SallyServlet servlet; + @Requires ActiveMQService activeMQ; + + DocumentManagerModel model; + + @Requires + CamelContextProvider camelContextProvider; + + CamelContext camelContext; + Logger log; + + public HashMap<String, Object> prepareDocManagement() { + HashMap<String, Object> result = new HashMap<String, Object>(); + result.put("routes", model.getRoutes()); + return result; + } + + public Registerdocumentresponse createRouteContext(AlexRouteImpl route) throws Exception { + final CamelContext alexRouteContext = new DefaultCamelContext(); + alexRouteContext.addComponent("activemq", camelContextProvider.getComponent("activemq")); + alexRouteContext.addComponent("alex", route.getAlexComponent()); + + alexRouteContext.addRoutes(route); + alexRouteContext.getShutdownStrategy().setTimeout(10); + alexRouteContext.start(); + + /* + route.addOnStopHandler(new Runnable() { + + public void run() { + try { + alexRouteContext.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + */ + + Registerdocumentresponse response = new Registerdocumentresponse(); + response.setSallyqueue(route.getDocStateQueue()); + return response; + } + + @Override + public void configure() throws Exception { + DataFormat core = CommUtils.getDataFormat("core", getClass().getClassLoader()); + + getContext().addComponent("freemarker", new TemplatingComponent("templates/", getClass().getClassLoader())); + + from("sallyservlet:///docmanager") + .bean(method(this, "prepareDocManagement")) + .to("freemarker:test.html"); + + from("activemq:queue:"+sallyRegisterQueue) + .unmarshal(core) + .bean(method(this, "registerDocument")) + .setProperty("route", body()) + .bean(method(this, "createRouteContext")) + .marshal(core); + } + + public DocumentManagerAdapter() { + log = LoggerFactory.getLogger(getClass()); + model = new DocumentManagerModel(); + } + + @Bind(aggregate=true, optional=true) + private void bindWorkflow(IDocWorkflow workflow) + { + model.addWorkflow(workflow); + } + + @Unbind(aggregate=true, optional=true) + private void unbindWorkflow(IDocWorkflow workflow) + { + model.removeWorkflow(workflow); + } + + + @Validate + public void start() throws Exception{ + camelContext = new DefaultCamelContext(); + camelContext.addComponent("activemq", camelContextProvider.getComponent("activemq")); + camelContext.addComponent("sallyservlet", camelContextProvider.getComponent("sallyservlet")); + camelContext.addRoutes(this); + camelContext.start(); + } + + @Invalidate + public void stop() throws Exception { + camelContext.stop(); + model.stopAllRoutes(); + } + + @Override + public AlexRoute registerDocument(Registerdocument doc) { + final AlexRoute route = model.addDocument(doc.getDocumentqueue(), doc.getDocumentqueue(), doc.getUserid(), doc.getInterfaces().toArray(new String[0])); + route.addOnStopHandler(new Runnable() { + + @Override + public void run() { + model.removeDocument(route.getDocQueue()); + } + }); + return route; + } + +} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerImpl.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerImpl.java deleted file mode 100644 index 90edf9894c00e452426661ac5534e9b8f9c5f41d..0000000000000000000000000000000000000000 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerImpl.java +++ /dev/null @@ -1,139 +0,0 @@ -package info.kwarc.sally4.docmanager.impl; - -import info.kwarc.sally.comm.core.Registerdocument; -import info.kwarc.sally4.activemq.ActiveMQService; -import info.kwarc.sally4.core.CamelContextProvider; -import info.kwarc.sally4.docmanager.AlexRoute; -import info.kwarc.sally4.docmanager.DocumentManager; -import info.kwarc.sally4.docmanager.IDocWorkflow; -import info.kwarc.sally4.docmanager.routes.DocumentManagementRoute; -import info.kwarc.sally4.docmanager.routes.SallyRegisterRoute; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -import org.apache.camel.CamelContext; -import org.apache.camel.impl.DefaultCamelContext; -import org.apache.felix.ipojo.annotations.Bind; -import org.apache.felix.ipojo.annotations.Component; -import org.apache.felix.ipojo.annotations.Instantiate; -import org.apache.felix.ipojo.annotations.Invalidate; -import org.apache.felix.ipojo.annotations.Provides; -import org.apache.felix.ipojo.annotations.Requires; -import org.apache.felix.ipojo.annotations.Unbind; -import org.apache.felix.ipojo.annotations.Validate; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Component -@Instantiate -@Provides -public class DocumentManagerImpl implements DocumentManager { - - @Requires(optional=true) - IDocWorkflow[] workflows; - - @Requires - ActiveMQService activeMQ; - - @Requires - CamelContextProvider camelContextProvider; - - Map<String, AlexRouteImpl> docs; - SallyRegisterRoute registerRoute; - - CamelContext camelContext; - - Logger log; - - - public DocumentManagerImpl() { - docs = new HashMap<String, AlexRouteImpl>(); - registerRoute = new SallyRegisterRoute(this); - log = LoggerFactory.getLogger(getClass()); - } - - public AlexRoute registerDocument(Registerdocument doc) { - if (docs.containsKey(doc.getDocumentqueue())) - return docs.get(doc.getDocumentqueue()); - - final AlexRouteImpl route = new AlexRouteImpl(doc.getDocumentqueue(), doc.getEnvironmentid(), doc.getUserid(), doc.getInterfaces()); - route.addOnStopHandler(new Runnable() { - - @Override - public void run() { - docs.remove(route.getAlexQueue()); - } - }); - docs.put(doc.getDocumentqueue(), route); - - return route; - } - - public void addRouteToWorkflows(AlexRouteImpl route) { - for (IDocWorkflow workflow : workflows) { - HashSet<String> required = new HashSet<String>(Arrays.asList(workflow.getInterfaceRequirements())); - if (route.getInterfaces().containsAll(required)) { - route.addDocumentWorkflow(workflow); - } - } - } - - public HashMap<String, Object> prepareDocManagement() { - HashMap<String, Object> result = new HashMap<String, Object>(); - result.put("routes", docs.values()); - return result; - } - - - @Bind(aggregate=true, optional=true) - private void bindWorkflow(IDocWorkflow workflow) - { - HashSet<String> required = new HashSet<String>(Arrays.asList(workflow.getInterfaceRequirements())); - for (AlexRouteImpl route : docs.values()) { - if (route.getInterfaces().containsAll(required)) { - route.addDocumentWorkflow(workflow); - } - } - } - - @Unbind(aggregate=true, optional=true) - private void unbindWorkflow(IDocWorkflow workflow) - { - for (AlexRouteImpl route : docs.values()) { - route.removeDocumentWorkflow(workflow); - } - } - - - @Validate - public void start() { - try { - camelContext = new DefaultCamelContext(); - camelContext.addComponent("activemq", camelContextProvider.getComponent("activemq")); - camelContext.addComponent("sallyservlet", camelContextProvider.getComponent("sallyservlet")); - camelContext.addRoutes(registerRoute); - camelContext.addRoutes(new DocumentManagementRoute(this)); - camelContext.start(); - } catch (Exception e) { - log.info(e.getMessage()); - e.printStackTrace(); - } - - } - - @Invalidate - public void stop() { - try { - camelContext.stop(); - for (AlexRouteImpl route : docs.values()) { - route.stop(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModel.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModel.java new file mode 100644 index 0000000000000000000000000000000000000000..7ef58c469a38a9f91bc6792f380e635f20f690ae --- /dev/null +++ b/docmanager/src/main/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModel.java @@ -0,0 +1,134 @@ +package info.kwarc.sally4.docmanager.impl; + +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; +import info.kwarc.sally4.processors.TypedCallback; +import info.kwarc.sally4.processors.XMLMessageWithTypeInfo; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; + +public class DocumentManagerModel { + Map<String, AlexRouteImpl> documents; + HashSet<IDocWorkflow> workflows; + + HashMap<String, HashMap<IDocWorkflow, IDocWorkflowInstance>> workflowDocInstances; + + public DocumentManagerModel() { + documents = new HashMap<String, AlexRouteImpl>(); + workflows = new HashSet<IDocWorkflow>(); + + workflowDocInstances = new HashMap<String, HashMap<IDocWorkflow,IDocWorkflowInstance>>(); + } + + // N^2 algo but the strings list are small so will be faster + public boolean containsAll(String[] required, String[] available) { + boolean ok; + for (String req : required) { + ok = false; + for (String avail : available) { + if (req.equals(avail)) { + ok = true; + break; + } + } + if (!ok) + return false; + } + return true; + } + + public AlexRoute addDocument(String docQueue, String environment, String userid, String[] interfaces) { + if (documents.containsKey(docQueue)) + return documents.get(docQueue); + + final AlexRouteImpl route = new AlexRouteImpl(docQueue, environment, userid, interfaces); + documents.put(docQueue, route); + route.setMessageHandler(new TypedCallback<XMLMessageWithTypeInfo>() { + + @Override + public void run(XMLMessageWithTypeInfo obj) { + forwardMessage(route, obj); + } + }); + + HashMap<IDocWorkflow,IDocWorkflowInstance> workflowInstances = new HashMap<IDocWorkflow, IDocWorkflowInstance>(); + for (IDocWorkflow workflow : workflows) { + if (containsAll(workflow.getInterfaceRequirements(), interfaces)) { + IDocWorkflowInstance instance = workflow.createDocumentInstance(route); + workflowInstances.put(workflow, instance); + } + } + workflowDocInstances.put(docQueue, workflowInstances); + return route; + } + + public void removeDocument(String docQueue) { + if (!documents.containsKey(docQueue)) + return; + documents.remove(docQueue); + for (IDocWorkflowInstance instances : workflowDocInstances.get(docQueue).values()) { + instances.stop(); + } + workflowDocInstances.remove(docQueue); + } + + public void addWorkflow(IDocWorkflow workflow) { + workflows.add(workflow); + + for (AlexRouteImpl route : getRoutes()) { + if (containsAll(workflow.getInterfaceRequirements(), route.getInterfaces())) { + workflowDocInstances.get(route.getDocQueue()).put(workflow, workflow.createDocumentInstance(route)); + } + } + } + + public void removeWorkflow(IDocWorkflow workflow) { + workflows.remove(workflow); + for (AlexRouteImpl route : getRoutes()) { + final HashMap<IDocWorkflow, IDocWorkflowInstance> instanceMap = workflowDocInstances.get(route.getDocQueue()); + + IDocWorkflowInstance t = instanceMap.get(workflow); + if (t == null) + continue; + t.stop(); + instanceMap.remove(workflow); + } + } + + + public void forwardMessage(AlexRoute r, XMLMessageWithTypeInfo info) { + final HashMap<IDocWorkflow, IDocWorkflowInstance> workflows = workflowDocInstances.get(r.getDocQueue()); + for (Entry<IDocWorkflow, IDocWorkflowInstance> work : workflows.entrySet()) { + if (containsAll(new String[] {info.getXmlMessageNamespace()}, work.getKey().getHandlingNamespaces())) { + if (work.getValue().handleMessage(r, info.getXmlMessageNamespace(), info.getXmlMessageType(), info.getExchange())) { + return; + } + } + } + } + + public Collection<AlexRouteImpl> getRoutes() { + return documents.values(); + } + + public void stopAllRoutes() { + for (String routeID : workflowDocInstances.keySet()) { + for (IDocWorkflow workflow : workflowDocInstances.get(routeID).keySet()) { + workflowDocInstances.get(routeID).get(workflow).stop(); + } + try { + documents.get(routeID).getContext().stop(); + } catch (Exception e) { + e.printStackTrace(); + } + workflowDocInstances.get(routeID).clear(); + } + workflowDocInstances.clear(); + documents.clear(); + } +} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/DocumentManagementRoute.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/DocumentManagementRoute.java deleted file mode 100644 index fd00dff93795d59e12b175ca558873f8955ec104..0000000000000000000000000000000000000000 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/DocumentManagementRoute.java +++ /dev/null @@ -1,24 +0,0 @@ -package info.kwarc.sally4.docmanager.routes; - -import info.kwarc.sally4.components.TemplatingComponent; -import info.kwarc.sally4.docmanager.impl.DocumentManagerImpl; - -import org.apache.camel.builder.RouteBuilder; - -public class DocumentManagementRoute extends RouteBuilder { - DocumentManagerImpl manager; - - public DocumentManagementRoute(DocumentManagerImpl manager) { - this.manager = manager; - } - - @Override - public void configure() throws Exception { - getContext().addComponent("freemarker", new TemplatingComponent("templates/", getClass().getClassLoader())); - - from("sallyservlet:///docmanager") - .bean(method(manager, "prepareDocManagement")) - .to("freemarker:test.html"); - } - -} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyAlexRoute.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyAlexRoute.java deleted file mode 100644 index b7251f4676e26f476e293c565daca4024b5edac9..0000000000000000000000000000000000000000 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyAlexRoute.java +++ /dev/null @@ -1,61 +0,0 @@ -package info.kwarc.sally4.docmanager.routes; - -import info.kwarc.sally.comm.core.Heartbeatrequest; -import info.kwarc.sally4.docmanager.impl.AlexRouteImpl; -import info.kwarc.sally4.docmanager.impl.DocumentManagerImpl; -import info.kwarc.sally4.marshalling.CommUtils; -import info.kwarc.sally4.processors.EnrichMessageProperties; - -import org.apache.camel.ExchangeTimedOutException; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.spi.DataFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SallyAlexRoute extends RouteBuilder { - - Logger log; - AlexRouteImpl thisAlexRoute; - DocumentManagerImpl docManager; - - public Heartbeatrequest generateHeartbeat() { - return new Heartbeatrequest(); - } - - public void stopSallyRoute() { - thisAlexRoute.stop(); - } - - SallyAlexRoute(AlexRouteImpl thisAlexRoute) { - log = LoggerFactory.getLogger(getClass()); - this.thisAlexRoute = thisAlexRoute; - } - - @Override - public void configure() throws Exception { - DataFormat core = CommUtils.getDataFormat("core", getClass().getClassLoader()); - - /** - * Sends a Heartbeat message to the Alex. if it does not respond after 20sec, this route will shutdown. - */ - from("timer://foo?fixedRate=true&period=60000") - .bean(method(this, "generateHeartbeat")) - .marshal(core) - .doTry() - .inOut("alex:default") - .doCatch(ExchangeTimedOutException.class) - .bean(method(this, "stopSallyRoute")); - - /** - * - */ - from("alex:defaultin") - .convertBodyTo(String.class) - .process(new EnrichMessageProperties()) - .bean(thisAlexRoute, "forwardMessage"); - //.to("alex:defaultout"); - } - - - -} diff --git a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyRegisterRoute.java b/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyRegisterRoute.java deleted file mode 100644 index 446b9a4fa71f8313969331ad09344ba4e39d3e9b..0000000000000000000000000000000000000000 --- a/docmanager/src/main/java/info/kwarc/sally4/docmanager/routes/SallyRegisterRoute.java +++ /dev/null @@ -1,75 +0,0 @@ -package info.kwarc.sally4.docmanager.routes; - -import info.kwarc.sally.comm.core.Registerdocumentresponse; -import info.kwarc.sally4.docmanager.impl.AlexRouteImpl; -import info.kwarc.sally4.docmanager.impl.DocumentManagerImpl; -import info.kwarc.sally4.marshalling.CommUtils; - -import org.apache.camel.CamelContext; -import org.apache.camel.ExchangePattern; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.jms.JmsConstants; -import org.apache.camel.impl.DefaultCamelContext; -import org.apache.camel.spi.DataFormat; - -public class SallyRegisterRoute extends RouteBuilder { - - public static final String sallyRegisterQueue = "sally_register"; - public static final String directSallyRegisterQueue = "direct:/queue/sally_register"; - public static final String mockSallyRegisterQueueOutput = "mock:/queue/sally_register_out"; - - DocumentManagerImpl docManager; - - public SallyRegisterRoute(DocumentManagerImpl docManager) { - this.docManager = docManager; - } - - public Registerdocumentresponse createRouteContext(AlexRouteImpl route) throws Exception { - final CamelContext alexRouteContext = new DefaultCamelContext(); - alexRouteContext.addComponent("activemq", getContext().getComponent("activemq")); - alexRouteContext.addComponent("alex", route.getAlexComponent()); - - alexRouteContext.addRoutes(new SallyAlexRoute(route)); - alexRouteContext.getShutdownStrategy().setTimeout(10); - alexRouteContext.start(); - - route.addOnStopHandler(new Runnable() { - - public void run() { - try { - alexRouteContext.stop(); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - Registerdocumentresponse response = new Registerdocumentresponse(); - response.setSallyqueue(route.getAlexStateQueue()); - return response; - } - - @Override - public void configure() throws Exception { - DataFormat core = CommUtils.getDataFormat("core", getClass().getClassLoader()); - - from("activemq:queue:"+sallyRegisterQueue) - .unmarshal(core) - .bean(docManager, "registerDocument") - .setProperty("route", body()) - .bean(method(this, "createRouteContext")) - .setExchangePattern(ExchangePattern.InOnly) - .multicast().parallelProcessing() - .to("direct:sendResponse", "direct:alexRoute"); - - from("direct:alexRoute") - .setBody(property("route")) - .bean(docManager, "addRouteToWorkflows") - .end(); - - from("direct:sendResponse") - .marshal(core) - .setHeader(JmsConstants.JMS_DESTINATION, header("JMSReplyTo")) - .to("activemq:mock"); - } - -} diff --git a/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapterTest.java b/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..51752f1a1b4ba41036de243393ca82760abd42d4 --- /dev/null +++ b/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerAdapterTest.java @@ -0,0 +1,40 @@ +package info.kwarc.sally4.docmanager.impl; + +import info.kwarc.sally.comm.core.Registerdocument; +import info.kwarc.sally4.docmanager.mocks.MockGlobalContextProvider; +import info.kwarc.sally4.marshalling.MarshallUtils; + +import org.apache.camel.ProducerTemplate; +import org.junit.Test; + +public class DocumentManagerAdapterTest { + + Registerdocument r1; + String r1xml; + + public DocumentManagerAdapterTest() { + r1 = new Registerdocument(); + r1.setDocumentqueue("d1"); + r1.setEnvironmentid("e1"); + r1xml = MarshallUtils.marshallToXML("core", r1, getClass().getClassLoader()); + } + + @Test + public void testStartingAndStopping() throws Exception { + DocumentManagerAdapter adapter = new DocumentManagerAdapter(); + adapter.camelContextProvider = new MockGlobalContextProvider(); + adapter.start(); + adapter.stop(); + } + + @Test + public void testRegisteringNewDocument() throws Exception { + DocumentManagerAdapter adapter = new DocumentManagerAdapter(); + adapter.camelContextProvider = new MockGlobalContextProvider(); + adapter.start(); + ProducerTemplate temp = adapter.camelContext.createProducerTemplate(); + temp.sendBody("activemq:queue:"+DocumentManagerAdapter.sallyRegisterQueue, r1); + adapter.stop(); + } + +} diff --git a/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModelTest.java b/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModelTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a96b5367665890666db421cf4b7e84e5d246b691 --- /dev/null +++ b/docmanager/src/test/java/info/kwarc/sally4/docmanager/impl/DocumentManagerModelTest.java @@ -0,0 +1,165 @@ +package info.kwarc.sally4.docmanager.impl; + +import static org.junit.Assert.*; +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.mocks.MockCountingWorkflow; + +import org.junit.Test; + +public class DocumentManagerModelTest { + + DocumentManagerModel model; + + public DocumentManagerModelTest() { + model = new DocumentManagerModel(); + } + + @Test + public void testSameQueueSameRoute() { + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2"}); + AlexRoute route2 = model.addDocument("doc1", "env2", "user2", new String[] {"i1", "i2"}); + + assertEquals("env1", route2.getEnvironmentID()); + assertEquals("user1", route2.getUserID()); + } + + @Test + public void testRemovingRoute() { + AlexRoute route1 = model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2"}); + model.removeDocument(route1.getDocQueue()); + + AlexRoute route2 = model.addDocument("doc1", "env2", "user2", new String[] {"i1", "i2"}); + assertEquals("env2", route2.getEnvironmentID()); + assertEquals("user2", route2.getUserID()); + } + + @Test + public void testRemovingAllRoutes() { + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2"}); + model.addDocument("doc2", "env1", "user1", new String[] {"i1", "i2"}); + model.addDocument("doc3", "env1", "user1", new String[] {"i1", "i2"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2"}); + model.removeDocument("doc1"); + model.removeDocument("doc2"); + model.removeDocument("doc3"); + assertEquals(0, model.getRoutes().size()); + } + + @Test + public void testMatchingRouteAndWorkflow() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + model.addWorkflow(cnt1); + assertEquals(2, cnt1.getInstances()); + model.addWorkflow(cnt2); + assertEquals(1, cnt2.getInstances()); + } + + @Test + public void testMatchingRouteAndWorkflowAndRemovingRoute() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + model.addWorkflow(cnt1); + assertEquals(2, cnt1.getInstances()); + model.addWorkflow(cnt2); + assertEquals(1, cnt2.getInstances()); + model.removeDocument("doc1"); + + assertEquals(1, cnt1.getInstances()); + assertEquals(0, cnt2.getInstances()); + } + + @Test + public void testMatchingRouteAndWorkflowAndRemovingWorkflow() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + model.addWorkflow(cnt1); + assertEquals(2, cnt1.getInstances()); + model.addWorkflow(cnt2); + assertEquals(1, cnt2.getInstances()); + model.removeWorkflow(cnt1); + + assertEquals(0, cnt1.getInstances()); + assertEquals(1, cnt2.getInstances()); + } + + @Test + public void testMatchingRouteAndWorkflowAndRemovingAllWorkflows() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + model.addWorkflow(cnt1); + assertEquals(2, cnt1.getInstances()); + model.addWorkflow(cnt2); + assertEquals(1, cnt2.getInstances()); + model.removeWorkflow(cnt1); + model.removeWorkflow(cnt2); + + assertEquals(0, cnt1.getInstances()); + assertEquals(0, cnt2.getInstances()); + } + + @Test + public void testMatchingWorkflowAndRoute() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + + model.addWorkflow(cnt1); + + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + assertEquals(1, cnt1.getInstances()); + model.addWorkflow(cnt2); + assertEquals(1, cnt2.getInstances()); + + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + + assertEquals(2, cnt1.getInstances()); + assertEquals(1, cnt2.getInstances()); + model.removeWorkflow(cnt1); + model.removeWorkflow(cnt2); + + assertEquals(0, cnt1.getInstances()); + assertEquals(0, cnt2.getInstances()); + } + + @Test + public void testRemovingRouteTwice() { + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.removeDocument("doc1"); + model.removeDocument("doc1"); + assertEquals(0, model.getRoutes().size()); + } + + @Test + public void testWorkflowTwice() { + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + model.removeWorkflow(cnt1); + model.removeWorkflow(cnt1); + } + + @Test + public void testStoppingAllRoutes() { + MockCountingWorkflow cnt1 = new MockCountingWorkflow(new String[]{"i1"}, new String[]{"n1"}); + MockCountingWorkflow cnt2 = new MockCountingWorkflow(new String[]{"i1", "i3"}, new String[]{"n1"}); + model.addDocument("doc1", "env1", "user1", new String[] {"i1", "i2", "i3"}); + model.addDocument("doc2", "env2", "user2", new String[] {"i1", "i2"}); + model.addWorkflow(cnt1); + model.addWorkflow(cnt2); + + model.stopAllRoutes(); + + assertEquals(0, cnt1.getInstances()); + assertEquals(0, cnt2.getInstances()); + assertEquals(0, model.getRoutes().size()); + } + + +} diff --git a/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockAbstractWorkflow.java b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockAbstractWorkflow.java new file mode 100644 index 0000000000000000000000000000000000000000..a85c97ed424e5fdee7e6acfb791b7aea24751d9b --- /dev/null +++ b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockAbstractWorkflow.java @@ -0,0 +1,31 @@ +package info.kwarc.sally4.docmanager.mocks; + +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; + +public class MockAbstractWorkflow implements IDocWorkflow { + String [] ifaces; + String [] namespaces; + + public MockAbstractWorkflow(String [] ifaces, String [] namespaces) { + this.ifaces = ifaces; + this.namespaces = namespaces; + } + + @Override + public String[] getInterfaceRequirements() { + return ifaces; + } + + @Override + public String[] getHandlingNamespaces() { + return namespaces; + } + + @Override + public IDocWorkflowInstance createDocumentInstance(AlexRoute route) { + return null; + } + +} diff --git a/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockCountingWorkflow.java b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockCountingWorkflow.java new file mode 100644 index 0000000000000000000000000000000000000000..5455b308c3a26ba95c4cae4ade4c88bf98af137f --- /dev/null +++ b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockCountingWorkflow.java @@ -0,0 +1,52 @@ +package info.kwarc.sally4.docmanager.mocks; + +import org.apache.camel.Exchange; + +import info.kwarc.sally4.docmanager.AlexRoute; +import info.kwarc.sally4.docmanager.IDocWorkflow; +import info.kwarc.sally4.docmanager.IDocWorkflowInstance; + +public class MockCountingWorkflow implements IDocWorkflow { + String [] ifaces; + String [] namespaces; + int instances; + + public MockCountingWorkflow(String [] ifaces, String [] namespaces) { + this.ifaces = ifaces; + this.namespaces = namespaces; + instances = 0; + } + + @Override + public String[] getInterfaceRequirements() { + return ifaces; + } + + @Override + public String[] getHandlingNamespaces() { + return namespaces; + } + + public int getInstances() { + return instances; + } + + @Override + public IDocWorkflowInstance createDocumentInstance(AlexRoute route) { + instances++; + return new IDocWorkflowInstance() { + + @Override + public void stop() { + instances--; + } + + @Override + public boolean handleMessage(AlexRoute route, String namespace, + String type, Exchange exchange) { + return false; + } + }; + } + +} diff --git a/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockGlobalContextProvider.java b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockGlobalContextProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..c2b3362213f533c2f5a7a8248e475f9b1562f3dd --- /dev/null +++ b/docmanager/src/test/java/info/kwarc/sally4/docmanager/mocks/MockGlobalContextProvider.java @@ -0,0 +1,32 @@ +package info.kwarc.sally4.docmanager.mocks; + +import info.kwarc.sally4.core.CamelContextProvider; + +import org.apache.camel.Component; +import org.apache.camel.component.direct.DirectComponent; + +public class MockGlobalContextProvider implements CamelContextProvider { + + @Override + public Component getComponent(String componentName) { + return new DirectComponent(); + } + + @Override + public void registerGlobalComponent(String componentName, + Component component) { + + } + + @Override + public void unregisterGlobalComponent(String componentName) { + // TODO Auto-generated method stub + + } + + @Override + public String getName() { + return "mockery"; + } + +} diff --git a/utils/src/main/java/info/kwarc/sally4/processors/EnrichMessageProperties.java b/utils/src/main/java/info/kwarc/sally4/processors/EnrichMessageProperties.java index f56a3550bc591e5cae7391e9548a3380ad58f7fd..3e27ff2350556540a095e1acdbcc6cdd7d9f12a8 100644 --- a/utils/src/main/java/info/kwarc/sally4/processors/EnrichMessageProperties.java +++ b/utils/src/main/java/info/kwarc/sally4/processors/EnrichMessageProperties.java @@ -17,12 +17,15 @@ public class EnrichMessageProperties implements Processor { Pattern xmlNamespace = Pattern.compile("<(\\w+)\\s+xmlns=\"([\\w/:.]+)\"/>"); public void process(Exchange exchange) throws Exception { - Matcher m = xmlNamespace.matcher(exchange.getIn().getBody(String.class)); + XMLMessageWithTypeInfo result = new XMLMessageWithTypeInfo(); + String body = exchange.getIn().getBody(String.class); + Matcher m = xmlNamespace.matcher(body); if (m.find()) { String msgType = m.group(1); String namespace = m.group(2); - exchange.getIn().setHeader(MessageType, msgType); - exchange.getIn().setHeader(MessageNamespace, namespace); + result.setXmlMessageNamespace(namespace); + result.setXmlMessageType(msgType); + exchange.getIn().setBody(result); } else { exchange.setException(new Exception("Could not detect namespace in incoming message")); } diff --git a/utils/src/main/java/info/kwarc/sally4/processors/TypedCallback.java b/utils/src/main/java/info/kwarc/sally4/processors/TypedCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..6d1f87f50e7004f360d05396b0989230d7e057b7 --- /dev/null +++ b/utils/src/main/java/info/kwarc/sally4/processors/TypedCallback.java @@ -0,0 +1,5 @@ +package info.kwarc.sally4.processors; + +public interface TypedCallback<T> { + void run(T obj); +} diff --git a/utils/src/main/java/info/kwarc/sally4/processors/XMLMessageWithTypeInfo.java b/utils/src/main/java/info/kwarc/sally4/processors/XMLMessageWithTypeInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..041e8ac9510d51c52cd468e7656600fa98f21e22 --- /dev/null +++ b/utils/src/main/java/info/kwarc/sally4/processors/XMLMessageWithTypeInfo.java @@ -0,0 +1,32 @@ +package info.kwarc.sally4.processors; + +import org.apache.camel.Exchange; + +public class XMLMessageWithTypeInfo { + Exchange exchange; + String xmlMessageType; + String xmlMessageNamespace; + + public XMLMessageWithTypeInfo() { + } + + public Exchange getExchange() { + return exchange; + } + public void setExchange(Exchange exchange) { + this.exchange = exchange; + } + public String getXmlMessageType() { + return xmlMessageType; + } + public void setXmlMessageType(String xmlMessageType) { + this.xmlMessageType = xmlMessageType; + } + + public String getXmlMessageNamespace() { + return xmlMessageNamespace; + } + public void setXmlMessageNamespace(String xmlMessageNamespace) { + this.xmlMessageNamespace = xmlMessageNamespace; + } +}