You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by Jim Gomes <jg...@apache.org> on 2015/11/08 00:58:34 UTC

Re: ActiveMQ and the Windows world

Jarmo,

I have included my PowerShell script below that uses the NMS libraries for
sending and receiving messages. This is offered with no warranties or
support, but in the hopes that you (and others) will be able to use it as a
guideline in creating your own solution.

This script is meant to be used to create an interactive shell, rather than
running as a standard unit test. This means that when you run it, it will
modify the current PowerShell instance and create new functions that can be
called from the command-line.  In order to get that functionality, the
script *must* be invoked into the current scope. This is accomplished by
prefixing the script invocation with a period '.' when it is executed. Here
is a sample command-line (the prompt is shown as a place holder):

PS> . nmstest.ps1

This syntax is a *period* (space) *scriptname*.

Once the script has run, all of the functions are available in the current
scope. They modify global variables, so the functions are stateful. This
allows you to load the NMS assemblies, create consumers and producers, and
continue to use them with different test functions.

The first function you will want to run is *load-nms*. It is not possible
to unload assemblies, so they will stay loaded until the PowerShell
instance is closed. You can then use *connect-amq* and *disconnect-amq* to
connect and disconnect from the broker.

Please remember that this is a code sample only, and not all of the
supporting files are included. Specifically, the message assembly and the
configuration file are not included. However, it should be clear what their
role is in the sample code, and can be easily replaced with your project's
specific implementation or equivalent. With all of that said, here is the
PowerShell script. This code sample is under the Apache 2.0 license, so
feel free to use it however you wish.

Best,
Jim


-------------- 8<  CUT HERE  >8 -----------

function load-nms()
{
    $private:testdir = "$(get-location)\testing"
    if(!(test-path $private:testdir))
    {
        mkdir $private:testdir
    }

    write-host Loading NMS and Msgs Assembly...
    copy lib\msgs\Msgs.dll $private:testdir
    copy lib\apache.nms\apache.nms.dll $private:testdir
    copy lib\apache.nms.activemq\apache.nms.activemq.dll $private:testdir
    copy lib\log4net\log4net.dll $private:testdir
    copy MyApp\app.config $private:testdir

    $global:msgs_asm =
[System.Reflection.Assembly]::LoadFrom("$private:testdir\Msgs.dll")
    $global:nms_asm =
[System.Reflection.Assembly]::LoadFrom("$private:testdir\apache.nms.dll")

    $global:cmdmsg_serializer = new
System.Xml.Serialization.XmlSerializer([MyApp.Msgs.AppCmdMsg])
    $global:appconfig = [xml] (get-content $private:testdir\app.config)
    $global:nextmsgid = 1
}

function get-appconfig($configparam, $defaultval)
{
    $private:confignode =
$global:appconfig.SelectSingleNode("/configuration/appSettings/add[@key='$configparam']")
    if($private:confignode)
    {
        return $private:confignode.value
    }

    return $defaultval
}

function connect-amq($casenum = "1", $clientid = "msgtest")
{
    if($global:amqcf)
    {
        write-warning "Alreading connected to Test server.  Disconnect
first."
        return
    }

    $global:amqcf = new Apache.NMS.NMSConnectionFactory((get-appconfig
NMSProviderUri), $clientid)
    if(!$global:amqcf)
    {
        write-warning "Could not connect to NMS provider."
        disconnect-amq
        return
    }

    $global:amqconn = $global:amqcf.CreateConnection()
    $global:amqsession = $global:amqconn.CreateSession()
    $global:sndmsgtopic = $global:amqsession.GetTopic((get-appconfig
SendMsgTopic))
    if(!$global:sndmsgtopic)
    {
        write-warning "Could not connect to SendMsg topic."
        disconnect-amq
        return
    }

    $global:msgproducer =
$global:amqsession.CreateProducer($global:sndmsgtopic)
    $global:msgproducer.TimeToLive = [System.TimeSpan]::FromMinutes(2)

    $global:rqrsqueue = $global:amqsession.GetQueue((get-appconfig
RequestResponseQueue))
    if(!$global:rqrsqueue)
    {
        write-warning "Could not connect to Request/Response queue."
        disconnect-amq
        return
    }

    $global:finishcmdqueue = $global:amqsession.GetQueue((get-appconfig
FinishMsgQueue))
    if(!$global:finishcmdqueue)
    {
        write-warning "Could not connect to Finshed Message queue."
        disconnect-amq
        return
    }

    set-testcase $casenum
    write-host Connected to Test server.
}

function disconnect-amq()
{
    remove-item variable:sndmsgtopic
    remove-item variable:rqrsqueue

    if($global:msgproducer)
    {
        $global:msgproducer.Close()
        remove-item variable:msgproducer
    }

    if($global:amqsession)
    {
        $global:amqsession.Close()
        remove-item variable:amqsession
    }

    if($global:amqconn)
    {
        $global:amqconn.Close()
        remove-item variable:amqconn
    }

    remove-item variable:amqcf

    write-host Disconnected from Test server.
}

function set-testcase($newcasenum)
{
    $global:testcase = $newcasenum
    write-host "Test Case is now: $newcasenum"
}

function new-rqmsg()
{
    $private:msg = new MyApp.Msgs.AppCmdMsg.RequestMsg
    $private:msg.id = $global:nextmsgid++
    return $private:msg
}

function new-resetmsg()
{
    $private:msg = new MyApp.Msgs.AppCmdMsg.ResetMsg
    $private:msg.id = $global:nextmsgid++
    return $private:msg
}

function send-rqmsg($rqmsg, $case = $global:testcase)
{
    $private:wrt = new System.IO.StringWriter(new
System.Text.StringBuilder(4096))
    $global:cmdmsg_serializer.Serialize($private:wrt, $rqmsg)
    $private:textmessage =
$global:msgproducer.CreateTextMessage($private:wrt.ToString())

    $private:textmessage.NMSType = "RQMSG"
    $private:textmessage.Properties["caseType"] = "UnitTestFailure"
    $private:textmessage.Properties["case"] = $case

    write-host "Sending message..."
    $global:msgproducer.Send($private:textmessage)
}

function check-connectedtonms()
{
    if($global:msgproducer -eq $null)
    {
        write-warning "You must connect to the Test server first."
        return $false
    }

    return $true
}

function send-resetmsg(
        $resettag,
        $tripped,
        $case = $global:testcase)
{
    if(!(check-connectedtonms))
    {
        return
    }

    $private:rqmsg = new-rqmsg
    $private:rqmsg.tagID = $resettag
    if($tripped)
    {
        $private:rqmsg.type = [MyApp.Msgs.AppCmdMsg.Status]::TrippedFlag
    }
    else
    {
        $private:rqmsg.type = [MyApp.Msgs.AppCmdMsg.Status]::ReadyFlag
    }

    send-rqmsg $private:rqmsg $case
}

function handle-msglookup()
{
    try
    {
        $private:msgconsumer =
$global:amqsession.CreateConsumer($global:rqrsqueue)
        if(!$private:msgconsumer)
        {
            write-warning "Did not create message consumer."
            return
        }

        write-host "Waiting for App Message."
        $private:msmsg =
$private:msgconsumer.Receive([System.TimeSpan]::FromSeconds(30))
        if(!$private:msmsg)
        {
            write-warning "Did not receive App Message request."
            return
        }

        if(!$private:msmsg.NMSReplyTo)
        {
            write-warning "No reply to queue specified in App Message
request."
            return
        }

        write-host "Received App Message."

        $private:msreplyproducer =
$global:amqsession.CreateProducer($private:msmsg.NMSReplyTo)
        if(!$private:msreplyproducer)
        {
            write-warning "Could not create reply queue producer."
            return
        }

        $private:msreplyproducer.Persistent = $false

        $private:cmd = $private:msmsg.Properties["CMD"]
        $private:response = $global:amqsession.CreateTextMessage()
        $private:response.Properties.SetString("CMD", $private:cmd)
        switch -regex ($private:cmd)
        {
            "CMD1"
            {
                write-host "Received CMD1." -b Gray -f Black
                $private:response.Properties.SetBool("STATE1_FLAG", $true)
            }

            "CMD2"
            {
                write-host "Received CMD2." -b Gray -f Black
                $private:response.Properties.SetBool("STATE2_FLAG", $true)
                $private:response.Properties.SetString("STATE2_REASON", "By
Request")
            }

            "CMD3"
            {
                write-host "Received CMD3." -b Gray -f Black
                $private:response.Properties.SetString("STATE3_FLAG",
"Commit")
            }

            "CMD4"
            {
                write-host "Received CMD4." -b Gray -f Black
                $private:response.Properties.SetString("STATE4_FLAG",
"Ready")
            }
        }

        write-host "Sending msg lookup response." -b Gray -f Black
        $private:msreplyproducer.Send($private:response)
    }
    finally
    {
        if($private:msgconsumer)
        {
            $private:msgconsumer.Close()
        }

        if($private:msreplyproducer)
        {
            $private:msreplyproducer.Close()
        }
    }
}

function waitfor-finishmsg()
{
    try
    {
        $private:finishconsumer =
$global:amqsession.CreateConsumer($global:finishcmdqueue)
        if(!$private:finishconsumer)
        {
            write-warning "Did not create finished command message
consumer."
            return
        }

        while($true)
        {
            write-host "Waiting for Finished Command Message."
            $private:finishmsg =
$private:finishconsumer.Receive([System.TimeSpan]::FromSeconds(30))
            if(!$private:finishmsg)
            {
                write-warning "Did not receive finished message."
                $private:shouldcontinue = read-host -prompt "Press 'Y' to
continue waiting"
                if($private:shouldcontinue -imatch "^Y")
                {
                    continue
                }
            }

            break
        }
    }
    finally
    {
        if($private:finishconsumer)
        {
            $private:finishconsumer.Close()
        }
    }
}

function test-resetmsg($tripped = $false, $case = $global:testcase)
{
    if(!(check-connectedtonms))
    {
        return
    }

    send-resetmsg CMD3 $tripped $case
    if($tripped)
    {
        write-host "Text should read: Unknown" -b Yellow -f Black
    }
    else
    {
        handle-msglookup
        write-host "Text should read: OK" -b Green -f Black
    }
    waitfor-finishmsg

    send-resetmsg CMD4 $tripped $case
    if($tripped -ne $true)
    {
        handle-msglookup
    }
    write-host "Text should read: Unknown" -b Yellow -f Black
    waitfor-finishmsg

    send-resetmsg CMD1 $tripped $case
    if($tripped)
    {
        write-host "Text should read: Unknown" -b Yellow -f Black
    }
    else
    {
        handle-msglookup
        write-host "Text should read: STATE1" -b DarkRed -f White
    }
    waitfor-finishmsg

    send-resetmsg CMD2 $tripped $case
    if($tripped)
    {
        write-host "Text should read: Unknown" -b Yellow -f Black
    }
    else
    {
        handle-msglookup
        write-host "Text should read: OK" -b Green -f Black
    }
    waitfor-finishmsg

    send-resetmsg CMD3-CMD4-CMD2 $tripped $case
    if($tripped)
    {
        write-host "Text should read: Unknown" -b Yellow -f Black
    }
    else
    {
        handle-msglookup
        write-host "Text should read: OK" -b Green -f Black
    }
    waitfor-finishmsg

    send-resetmsg CMD3-CMD4-CMD2-CMD1 $tripped $case
    if($tripped)
    {
        write-host "Text should read: Unknown" -b Yellow -f Black
    }
    else
    {
        handle-msglookup
        write-host "Text should read: STATE1" -b DarkRed -f White
    }
    waitfor-finishmsg
}



-------------- 8<  CUT HERE  >8 -----------







On Thu, Oct 1, 2015 at 1:34 PM, Jarmo Sorvari <ja...@tamk.fi> wrote:

> On 01.10.2015 16:48, Jim Gomes wrote:
>
>> You're welcome. You can use the NMS libraries from PowerShell. I've done
>> it
>> many times for writing test scripts and other things. It's actually quite
>> easy. If you want some sample code, let me know. You can then take that
>> into a full C# app with little difficulty.
>>
>
> Thank you for the offer. I will look at this with our windows guy in the
> near future!
>
> Jarmo
>
>
>
>> On Thu, Oct 1, 2015, 12:05 AM Jarmo Sorvari <ja...@tamk.fi>
>> wrote:
>>
>> From: tbain98@gmail.com [mailto:tbain98@gmail.com] On Behalf Of Tim Bain
>>>> Sent: 30. syyskuuta 2015 15:42
>>>> To: ActiveMQ Users
>>>> Subject: Re: ActiveMQ and the Windows world
>>>>
>>>> Most people on both Windows and Linux use the Java or C++ client
>>>>
>>> libraries
>>>
>>>> to read and write messages from/to ActiveMQ.  Do you have requirements
>>>> that preclude that approach?  If so, what are you trying to do and under
>>>>
>>> what
>>>
>>>> constraints, so we can try to help you find a solution that works for
>>>>
>>> you?
>>>
>>>
>>> The need is to be able to use the same scripting language that our
>>> windows
>>> guy would use for the rest of the integration. A ready PowerShell module
>>> would be ideal. Having to compile things or use Java (just to load a
>>> message) creates a threshold of some sort.
>>>
>>> Thanks to Jim Gomes, too. We will look at the NMS library!
>>>
>>> Jarmo
>>>
>>>
>>> Tim
>>>> On Sep 30, 2015 3:21 AM, "Jarmo Sorvari" <ja...@tamk.fi> wrote:
>>>>
>>>> Hi
>>>>>
>>>>> Some Googling did not give me much on this, so I ask here:
>>>>>
>>>>> How do people here read and write the ActiveMQ from the windows
>>>>>
>>>> world?
>>>>
>>>>> Preferably using PowerShell, but anything goes...
>>>>>
>>>>> Tried to find STOMP implementations or native jms speakers, but it was
>>>>> surprisingly scant. My present guess is that we would be best off
>>>>> reading and writing queues using ActiveMQ's REST interface. Seems to
>>>>> me, though, that in that case, running amq from the ServiceMix package
>>>>> is not possible (how do you activate amq's REST there?), but rather
>>>>>
>>>> install
>>>
>>>> amq on its own.
>>>>
>>>>> Jarmo Sorvari
>>>>> Tampere University of Applied Sciences Finland
>>>>>
>>>>>
>