/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.tasks.test; import divconq.bus.IService; import divconq.bus.Message; import divconq.bus.ServiceResult; import divconq.hub.Hub; import divconq.lang.CountDownCallback; import divconq.lang.op.OperationCallback; import divconq.lang.op.OperationContext; import divconq.schema.Schema; import divconq.struct.RecordStruct; import divconq.struct.Struct; import divconq.work.IWork; import divconq.work.TaskRun; import divconq.xml.XAttribute; import divconq.xml.XElement; public class TestBusAndContext implements IWork { @Override public void run(final TaskRun testrun) { XElement myschema = new XElement("Schema", new XElement("Services", new XElement("Service", new XAttribute("Name", "TestBusService"), new XElement("Secure", new XAttribute("Tags", "Guest,User"), new XElement("Feature", new XAttribute("Name", "Test"), new XElement("Op", new XAttribute("Name", "NoOp"), new XElement("Request", new XAttribute("Inherits", "RequestMessage")), new XElement("Response", new XAttribute("Inherits", "ResponseMessage")) ) ) ) ) ) ); Schema s = new Schema("@Internal", Hub.instance.getSchema()); s.loadSchema(myschema); if (testrun.hasErrors()) { testrun.error("Could not complete the test, bad schema!"); testrun.complete(); return; } final OperationContext testctx = testrun.getContext(); Hub.instance.getBus().getLocalHub().registerService(new IService() { protected int callcnt = 0; @Override public String serviceName() { return "TestBusService"; } @Override public void handle(TaskRun request) { this.callcnt++; // with services, log to the context via operation result request.info("Service got call!"); OperationContext myctx = OperationContext.get(); request.info("Service operation id is " + myctx.getOpId()); //opresult.info("Service bucket is " + myctx.getBucket()); request.info("Service is elevated " + myctx.isElevated()); request.info("Service user is " + myctx.getUserContext().getUsername()); if (myctx.getOpId().equals(testctx.getOpId())) request.info("Our operation id matches"); else request.error("Our operation id does not match"); //if (myctx.getBucket().equals(testctx.getBucket())) // opresult.info("Our bucket matches"); //else // opresult.error("Our bucket does not match"); // user context switch testing - become a root if (callcnt == 2) { // all we have to do is change the user context, bus will return the context OperationContext.use(myctx.toBuilder().withRootUserTemplate()); request.info("Service user is now " + OperationContext.get().getUserContext().getUsername()); } request.complete(); } }); testrun.info("Test operation id is " + testctx.getOpId()); //testrun.info("Test bucket is " + testctx.getBucket()); testrun.info("Test is elevated " + testctx.isElevated()); testrun.info("Test user is " + testctx.getUserContext().getUsername()); testrun.info("Now make the service call"); int runcnt = 2; final CountDownCallback countdown = new CountDownCallback(runcnt, new OperationCallback() { @Override public void callback() { testrun.info("TestBusAndConext finishing up."); OperationContext testctx = OperationContext.get(); // should be the same as testrun.getContext(); testrun.info("Test operation id is " + testctx.getOpId()); //testrun.info("Test bucket is " + testctx.getBucket()); testrun.info("Test is elevated " + testctx.isElevated()); testrun.info("Test user is " + testctx.getUserContext().getUsername()); testrun.info("Here are all of the messages for run, including those from service: "); for (Struct m : testrun.getMessages().getItems()) { RecordStruct msg = (RecordStruct) m; testrun.info(msg.getFieldAsString("Code") + " - " + msg.getFieldAsString("Message")); } testrun.info("TestBusAndConext is cleaning up."); // cleanup by removing the schema and service Hub.instance.getBus().getLocalHub().removeService("TestBusService"); Hub.instance.getSchema().removeService("TestBusService"); // done if (testrun.hasErrors()) testrun.info("TestBusAndConext completed with errors: " + testrun.getMessage()); else testrun.info("TestBusAndConext completed successfully"); testrun.complete(); } }); // send two messages, the second should have an altered user context for (int i = 0; i < runcnt; i++) { Message msg = new Message("TestBusService", "Test", "NoOp"); Hub.instance.getBus().sendMessage(msg, new ServiceResult() { @Override public void callback() { // we now have a record of all the messages from the service testrun.info("TestBusAndConext context after call:."); OperationContext testctx = testrun.getContext(); testrun.info("Test operation id is " + testctx.getOpId()); //testrun.info("Test bucket is " + testctx.getBucket()); testrun.info("Test is elevated " + testctx.isElevated()); testrun.info("Test user is " + testctx.getUserContext().getUsername()); countdown.countDown(); } }); // wait a little before next call try { Thread.sleep(1000); } catch (InterruptedException x) { testrun.complete(); break; } } } }