Blog about things

blogging experiment about hacking

Apache Apollo Start

Getting started with Apache Apollo, follow-up project to ActiveMQ

Apache apollo is an all-dancing, all-singing message broker, queue manager, integration engine, etc. written in scala, running on a JVM. It is the follow on to activeMQ, written in scala.

Web Site: http://activemq.apache.org/apollo/

My steps to install a new v1.7 apollo broker for first steps testing and proof of concept …

  • download the gzip’d tar file
  • i uncompressed and exploded into /opt/apache-apollo-1.7/
  • created a broker named okc-broker
1
$ sudo /opt/apache-apollo-1.7/bin/apollo okc-broker
  • created link for init service
1
$ sudo ln -s /opt/okc-broker/bin/apollo-broker-service /etc/init.d/apollo-broker-
  • start service
1
$ sudo service service apollo-broker-service start

python test client CLI for stomp messaging protocol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ sudo pip install stomp.py

$ python /usr/local/lib/python2.7/dist-packages/stomp -H localhost -P 61613 -V VERBOSE -U admin -W password
 -- or -- stomp ... || stomp --help

> subscribe /topic/okcra-api-ops
Subscribing to "/topic/okcra-api-ops" with acknowledge set to "auto", id set to "1"

> send /topic/okcra-api-ops 'howdy'

'howdy'

> unsubscribe /topic/okcra-api-ops
Unsubscribing from "/topic/okcra-api-ops"
> send /topic/okcra-api-ops 'howdy'
> subscribe /topic/okcra-api-ops
Subscribing to "/topic/okcra-api-ops" with acknowledge set to "auto", id set to "2"
>
> send /topic/okcra-api-ops 'howdy again'

'howdy again'

> exit

The default config requires user authentication. There is one configured user with all rights - admin:password.

The broker configuration, logs, data, etc are under the broker directory; mine was created at /opt/okc-broker.

a PHP stomp client

I haven’t used PHP in a very long time and then knew nothing about frameworks, autoloaders, etc so this is a bit of a struggle but it’s a start.

install the client package

Our backend app uses composer to load packages so I’m going to integrate with that. I also found PECL packages but picked composer for this attempt.

I browsed packages at https://packagist.org/ and found fusesource/stomp-php.

I added this line to the app’s composer.json file “fusesource/stomp-php”:“2.1.1”

I then installed composer locally following instructions at composer and ran the command to update the app’s dependencies.

1
2
3
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
$ composer update

php code

There are example programs in the stomp-php package, under /vendor/fusesource/stomp-php/examples/.

first.php is, suprisingly enough, the first example I looked at. I want to send a message to my apollo broker running on my host, listening on port tcp:61613 so I’m going to borrow some of the easy-looking code.

first.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
require __DIR__.'/../vendor/autoload.php';
// include a library

use FuseSource\Stomp\Stomp;
// make a connection
$con = new Stomp("tcp://localhost:61613");
// connect
$con->connect();
// send a message to the queue
$con->send("/queue/test", "test");
echo "Sent message with body 'test'\n";
// subscribe to the queue
$con->subscribe("/queue/test");
// receive a message from the queue
$msg = $con->readFrame();

// do what you want with the message
if ( $msg != null) {
    echo "Received message with body '$msg->body'\n";
    // mark the message as received in the queue
    $con->ack($msg);
} else {
    echo "Failed to receive a message\n";
}

// disconnect
$con->disconnect();
?>

I put some of the code in my routes.php file to do a quick connect->send->disconnect test by hitting a new route without messing with controllers or authorizations, etc.

routes.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
  use FuseSource\Stomp\Stomp;
...
Route::get('sendStompMessage', function() {
  $queue  = '/topic/okcra-api-ops';
  $msg    = 'message from sendStompMessage handler';

  /* connection */
  try {
    $stomp = new Stomp('tcp://localhost:61613');
    $stomp->connect();
  } catch(StompException $e) {
    return('stomp connection failed: ' . $e->getMessage());
  }

  /* send a message to the queue */
  $stomp->send($queue, $msg);

  // close connection
  unset($stomp);

  return 'sent stomp message';
});
...
?>

After some fiddling with whether i needed the use statement and it’s placement when it did seem necessary I got this message when hitting the new route: {“message”:“Authentication failed. Credentials=[user=]”, …

That counts for some progress I suppose. Documentation is kind of lacking here but I need to add user and password somewhere, probably either the connection uri or the connect() call. Alternatively, I could turn off authorization but I think I’ll leave it on and work through getting connected. There are other available parameters, like timeouts, virtual hosts, etc.

$stomp->connect(“admin”, “password”); does the trick. When the route is hit, it connects, sends a message and disconnects!

http://php.net/manual/en/stomp.construct.php shows the optional username and password parameters plus another optional parameter to supply headers like receipt, timeouts, etc. as an associative array.

To finish up this initial proof of concept I will subsribe to the topic on the virtual machine using the python stomp CLI while hitting the route in web browser on the host box. If all goes well I’ll see messages emmitted at the python client.

$ stomp -H localhost -P 61613 -V VERBOSE -U admin -W password

> subscribe /topic/okcra-api-ops
Subscribing to "/topic/okcra-api-ops" with acknowledge set to "auto", id set to "1"

- hit URL in browser -
message from sendStompMessage handler

- hit URL in browser -
message from sendStompMessage handler

Woohoo! We have completed our quick and dirty proof of concept to emit messages from the server upon some internal event which can be acted upon by loosely-coupled processes interested in some or all the events.
One such use case we have is client notification when resource(s) of interest have been modified or used.