Jul 082014
 

Man, this was driving me nuts. Using identical code as successful queue/topic receive operations against the Azure Service Bus, I was perplexed to see “no valid sources” as if my broker address was wrong. I checked it repeatedly, and started doubting that I had the wrong broker settings.

In the end, it was the SAS policy key. Azure generates a healthily-long key. This was the first one I got that  had / (slash) and + (plus) characters in the key. As this key is part of the URI Qpid Proton uses to connect to the broker, it needs to be URL-encoded. Simple enough to fix in python:

import urllib
sasPolicyKey = "<your key from Azure with slashes and/or plus signs>"
safeSasPolicyKey = urllib.quote(sasPolicyKey, "")
Jul 052014
 

I’m really digging on IoT these days, and I see AMQP and the Azure Service Bus as the primary enablers. With two Raspberry Pis sitting around, I decided to put a temperature probe on one, and send hourly temp readings to my laptop two feet away via the Azure Service Bus. Not the most efficient thing I could do, but I’m simulating a scenario when a remote device (RPi) being located on a strawberry farm in California communicating with a Azure-hosted system that processes the data (my laptop).

Getting Started

The Raspberry Pi is a perfect device developer’s starter kit. I think Python is a great starter language too, so I quickly had my heart set on installing the Python AMQP Messenger bindings for Apache Qpid Proton and use the Python Examples to help me write code to send some test messages through the cloud. There are really only two implementations of Qpid Proton: C and Java. The C implementation also serves as the foundation for the Perl, PHP, Python, and Ruby bindings. Java is selfish (as expected) and only takes care of itself. Raspberry Pi being Linux can support all of these languages but I wanted to start slow with Python.

I really hoped that the Proton install was a 10-30 minute thing, but it took me quite a while to piece together everything I needed. Since I took the time to document the procedure that ended up working, I figure that I should post them here for the next person so they don’t struggle like I did. The documentation included in the  readme file is ok, I guess. The documentation on the project site could really benefit from some scenario-based examples or quick start tutorials if they’re looking for adoption. Maybe I should do that?

Setup Procedure

I started with a one-year-old Raspian Wheezy hard-float image. It already had PHP, Python, and Java. I also installed NodeJs a few months ago. To install the following packages and to make calls to Azure, you’ll also need to be connected to the Internet. The following procedure is very similar to the readme file, that fills in the gaps from the Raspbian image. Log into your pi and follow along:

  1. $ sudo apt-get install cmake uuid-dev
    This installs cmake so you can build the Proton assemblies. It also gets the UUID assemblies so you can communicate your device ID (IoT world requires some kind of device ID)
  2. $ sudo apt-get install openssl
    All calls to Azure Service Bus require a secure connection. This will install the latest, heartbleed-free, OpenSsl binaries and tools. If this was not already installed on your RPi, you may need to configure it.
  3. $ sudo apt-get install libssl-dev
    This installs the development files and headers for OpenSsl
  4. $ sudo apt-get install swig python-dev
    Install SWIG, that is a tool that facilitates the scripting languages “bindings” that connect to the C implementation of Proton (i.e. Proton-C)
  5. Make a new directory to hold the Qpid download
    $ mkdir /home/pi/qpid
    $ cd /home/pi/qpid
  6. Navigate to the the Proton project page, and click on the link for the latest version of Proton. At the time of writing, this is version 0.7 with a package named qpid-proton-0.7.tar.gz. When you click the link, you be taken to a page to select the closest mirror. Copy the link address for the mirror of your choosing, and then wget with that address:
    $ wget http://apache.petsads.us/qpid/proton/0.7/qpid-proton-0.7.tar.gz
  7. $ tar xvfz qpid-proton-0.7.tar.gz
    This will uncompress the package and place the downloaded files into a qpid-proton-0.7 directory
  8. $ cd qpid-proton-0.7
    $ mkdir build
    $ cd build

    This will create a build directory for cmake to stage its files to build Proton
  9. $ cmake .. –DCMAKE_INSTALL_PREFIX=/usr –DSYSINSTALL_BINDINGS=ON
    This will run cmake on the download directory (..) and prepare to install the binaries into /usr. It will also prepare bindings for all installed languages. If you are using python, make sure you don’t see error messages about swig missing. Also make sure that you see the language of your choice being prepared for bindings in the standard output.
  10. $ make all docs
    (Optional) This will prepare copy the documentation
  11. $ sudo make install
    This builds Proton-C, Proton-Java, and copies the bindings to the system-default directories (e.g. python bindings appear on my RPi in /usr/lib/python2.7/dist-packages (look for cproton.py)

That’s it. To test that it all worked, you can do something simple like:

$ python
>>> from proton import *

If you don’t see an error message, then the bindings are in place and you are ready to write some code.

Jul 032014
 

It feels wrong for a client or server to use the “owner” shared secret credentials in an Azure Service Bus connection string. It’s pure evil with 100s or 1000s of Azure Service Bus queue and topic clients sending messages. So how about I supplement the documentation and show how to easily change from using <sharedSecret> to <sharedAccessSignature>?

Step 1: Create some SAS policies

Log into the Azure management portal, click on your Service Bus queue (or topic), and then click Configure. Add one or more policies, choose their respective permissions, and click Save. After saving, the policy name and keys appear under the “shared access key generator” section below. Copy the primary key and move on to step 2.

image

Step 2: Modify your config file

If you’re like me, you like to keep your WCF hosting code free of configuration. If hosted in a console app, the following code is all I use to start a service.

ServiceHost testHost = new ServiceHost(typeof(TestManager));
testHost.Open();

When adding an additional endpoint for NetMessagingBinding, it’s really simple to just add a new endpoint and behavior configuration. The documentation in place today always shows <sharedSecret> being used. This is not a real-world scenario since every client and service should have their own credentials.

To use your new shared access keys, change this:

    <behaviors>
      <endpointBehaviors>
        <behavior name="ServiceBusTokenProvider">
          <transportClientEndpointBehavior>
            <tokenProvider>
              <sharedSecret issuerName="owner" issuerSecret="blAhblAh+Blah/blaH+BLAhblAhBLaHblAHBlahblaH=" />
            </tokenProvider>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
    </behaviors>

to something like this, using your newly-generated keys:

    <behaviors>
      <endpointBehaviors>
        <behavior name="SASPolicyTokenProvider">
          <transportClientEndpointBehavior>
            <tokenProvider>
              <sharedAccessSignature keyName="ingest-manager" key="SASkey+sAskEY/SASKeysaSKey+SaskeYsaSKEy/SaS=" />
            </tokenProvider>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
    </behaviors>

And that’s it.