Flexibility with SwiftMQLauncher

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Flexibility with SwiftMQLauncher

Eric Rizzo
In a Spring application I'm trying to use SwiftMQLauncher for my automated unit/integration tests, so they don't have a dependency on any external router. The problem is in the way that SwiftMQLauncher seems to want it's working directory and config file specified. The idea is that the Spring configuration that materializes for test runs should be totally self-contained and absent any details about the machine it's running on. But SwiftMQLauncher wants an absolute path for workingDir, which simply isn't possible in a Continuous Integration system. We can't hard-code a path that may or may not exist on the build machine or any developer's machine.
Is there any other way to configure SwiftMQLauncher in a more Spring-like way, where it does not rely on absolute paths? Ideally I'd expect workingDir to be optional and for SwiftMQLauncher to accept a Spring Resource object for configFile, so I could configure it with something like "classpath:swiftmq-router-config.xml" - that's how Spring-aware objects usually work.

If it helps in coming up with solutions or workarounds, this project is built using Maven.

Thanks,
Eric
Reply | Threaded
Open this post in threaded view
|

Re: Flexibility with SwiftMQLauncher

IIT Software
Administrator
A property placeholder like

      <property name="workingDir" value="${swiftmq.workingdir}"/>

will not work for you?
Reply | Threaded
Open this post in threaded view
|

Re: Flexibility with SwiftMQLauncher

Eric Rizzo
I don't think that helps, because in the end the path has to be absolute and stored somewhere in the project config, or it has to be passed in to the Environment at (test) run time. The inability of Swift to deal with relative or even classpath resources is the root of the problem.

If SwiftMQLauncher had a method like this instead of the simplistic setConfigFile(String) that it does have, it would be more "Spring-friendly" and easier to use in my opinion.

public void setConfigResource(Resource resource) {
        Assert.notNull(resource);
        if (! resource.isReadable()) {
                throw new IllegalArgumentException("Config resource " + resource + " is not readable.");
        }

        try {
                // Not using workingDir, so indicate that the config file path is absolute
                String filePath = SwiftUtilities.ABSOLUTEDIR_PREFIX + resource.getFile().getAbsolutePath();

                setConfigFile(SwiftUtilities.ABSOLUTEDIR_PREFIX + filePath);
        } catch (IOException ex) {
                throw new IllegalArgumentException("Config resource " + resource + " does not resolve to a file", ex);
        }
}
Reply | Threaded
Open this post in threaded view
|

Re: Flexibility with SwiftMQLauncher

IIT Software
Administrator
I see. But if you look at the routerconfig.xml (e.g. kernelpath element) you will realize that many components refer relative to the working directory. This is history and to change that would have much impact. So the working directory has to be specified somewhere. It is not only to fetch the routerconfig.xml from the classpath. I also don't think it is very uncommon that software needs a home directory specified in some env variable, e.g. JAVA_HOME. So if you put SWIFTMQ_WORKINGDIR in your .bashrc or the like, you are fine.
Reply | Threaded
Open this post in threaded view
|

Re: Flexibility with SwiftMQLauncher

Eric Rizzo
I think the trend in recent years is towards more "embedded" components that don't require any environmental setup (or at least can be configured via code that way as an alternate to environmentally sensitive).
In any case, I was able to get most of the way to an "embedded" Swift router by using "absolute:" paths that refer to the current working directory, but I still get an error on startup. Two questions about that:

A) What is the minimal router.xml configuration required to get a single non-persistent queue - I mean the absolute smallest config that actually works?

B) What could be the cause of this that I get at startup? Without any source code and poor exception messages, it's impossible to troubleshoot this stuff:

Booting SwiftMQ 9.7.1 Production ...
... startup: Trace Swiftlet
... startup: Log Swiftlet
... startup: Threadpool Swiftlet
... startup: Timer Swiftlet
... startup: Network Swiftlet
... startup: Store Swiftlet
... startup: Queue Manager Swiftlet
... startup: Topic Manager Swiftlet
... startup: Management Swiftlet
... startup: AMQP Swiftlet
SwiftMQ 9.7.1 Production is ready.
Got Exception:
    ThreadGroup: default
    ActiveTask : PipelineQueue, dispatchToken=Connector
Stack Trace:
java.lang.NullPointerException
        at com.swiftmq.net.client.IntraVMConnection$1.flush(Unknown Source)
        at com.swiftmq.tools.util.DataStreamOutputStream.flush(Unknown Source)
        at com.swiftmq.jms.v750.Connector.writeObject(Unknown Source)
        at com.swiftmq.jms.v750.Connector.visit(Unknown Source)
        at com.swiftmq.jms.v750.po.POVersionRequest.accept(Unknown Source)
        at com.swiftmq.tools.pipeline.PipelineQueue.process(Unknown Source)
        at com.swiftmq.tools.queue.SingleProcessorQueue.dequeue(Unknown Source)
        at com.swiftmq.tools.pipeline.PipelineQueue$QueueProcessor.run(Unknown Source)
        at com.swiftmq.impl.threadpool.standard.PoolThread.run(Unknown Source)

Thanks,
Eric
Reply | Threaded
Open this post in threaded view
|

Re: Flexibility with SwiftMQLauncher

IIT Software
Administrator
Concerning A) you can drop the config for the AMQP Swiftlet if you don't need it. The rest is required.

Concerning B) it seems your router doesn't start all Swiftlets, e.g. the Routing, JMS, JNDI Swiftlets are missing. Please use the default config and don't edit the start order element. SwiftMQ is not open source. If you want to hack source code you may use other stuff.