Azure ServiceBus Topic using REST API – Part 2

8 במרץ 2012

7 comments

In the last post I described why to use REST API when working with Azure service bus and demonstrated how to create a topic and subscription.


In this post we will actually send a message to the topic.


When sending a http request with a message to a topic we have to provide two special headers
1. Authorization header with the token we received from ACS
2.  BrokerProperties with Json serialization of metadata of metadata about our message.


To do that let us create a special class that will help us represent and serialize the metadata.




Broker Properties



  1. /// <summary>

  2. /// Container for general properties of messages that are placed in the "BrokerProperties" http header and can be used to filter messages

  3. /// </summary>

  4. [DataContract]

  5. public sealed class BrokerProperties

  6. {

  7.     private static readonly DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(BrokerProperties));


  8.     [DataMember(EmitDefaultValue = false)]

  9.     public string CorrelationId { get; set; }


  10.     [DataMember(EmitDefaultValue = false)]

  11.     public string SessionId { get; set; }


  12.     [DataMember(EmitDefaultValue = false)]

  13.     public int? DeliveryCount { get; set; }


  14.     [DataMember(EmitDefaultValue = false)]

  15.     public Guid? LockToken { get; set; }


  16.     [DataMember(EmitDefaultValue = false)]

  17.     public string MessageId { get; set; }


  18.     [DataMember(EmitDefaultValue = false)]

  19.     public string Label { get; set; }


  20.     [DataMember(EmitDefaultValue = false)]

  21.     public string ReplyTo { get; set; }


  22.     [DataMember(EmitDefaultValue = false)]

  23.     public long? SequenceNumber { get; set; }


  24.     [DataMember(EmitDefaultValue = false)]

  25.     public string To { get; set; }


  26.     public DateTime? LockedUntilUtc { get; set; }


  27.     public DateTime? ScheduledEnqueueTimeUtc { get; set; }


  28.     public TimeSpan? TimeToLive { get; set; }


  29.     [DataMember(EmitDefaultValue = false)]

  30.     public string ReplyToSessionId { get; set; }


  31.     [DataMember(Name = "LockedUntilUtc", EmitDefaultValue = false)]

  32.     public string LockedUntilUtcString

  33.     {

  34.         get

  35.         {

  36.             if (this.LockedUntilUtc != null && this.LockedUntilUtc.HasValue)

  37.             {

  38.                 return this.LockedUntilUtc.Value.ToString("r");

  39.             }


  40.             return null;

  41.         }


  42.         set

  43.         {

  44.             try

  45.             {

  46.                 // When deserializing from JSON format, attempt to parse the value.

  47.                 // If the value cannot be parsed as a date time, ignore it.

  48.                 this.LockedUntilUtc = DateTime.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

  49.             }

  50.             catch

  51.             {

  52.             }

  53.         }

  54.     }


  55.     [DataMember(Name = "ScheduledEnqueueTimeUtc", EmitDefaultValue = false)]

  56.     public string ScheduledEnqueueTimeUtcString

  57.     {

  58.         get

  59.         {

  60.             if (this.ScheduledEnqueueTimeUtc != null && this.ScheduledEnqueueTimeUtc.HasValue)

  61.             {

  62.                 return this.ScheduledEnqueueTimeUtc.Value.ToString("r");

  63.             }


  64.             return null;

  65.         }


  66.         set

  67.         {

  68.             try

  69.             {

  70.                 // When deserializing from JSON format, attempt to parse the value.

  71.                 // If the value cannot be parsed as a date time, ignore it.

  72.                 this.ScheduledEnqueueTimeUtc = DateTime.Parse(value, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

  73.             }

  74.             catch

  75.             {

  76.             }

  77.         }

  78.     }


  79.     [DataMember(Name = "TimeToLive", EmitDefaultValue = false)]

  80.     public double TimeToLiveString

  81.     {

  82.         get

  83.         {

  84.             if (this.TimeToLive != null && this.TimeToLive.HasValue)

  85.             {

  86.                 return this.TimeToLive.Value.TotalSeconds;

  87.             }


  88.             return 0;

  89.         }


  90.         set

  91.         {

  92.             // This is needed as TimeSpan.FromSeconds(TimeSpan.MaxValue.TotalSeconds) throws Overflow exception.

  93.             if (TimeSpan.MaxValue.TotalSeconds == value)

  94.             {

  95.                 this.TimeToLive = TimeSpan.MaxValue;

  96.             }

  97.             else

  98.             {

  99.                 this.TimeToLive = TimeSpan.FromSeconds(value);

  100.             }

  101.         }

  102.     }


  103.     public static BrokerProperties Deserialize(string jsonString)

  104.     {

  105.         using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))

  106.         {

  107.             return (BrokerProperties)serializer.ReadObject(ms);

  108.         }

  109.     }


  110.     public string Serialize()

  111.     {

  112.         using (MemoryStream memoryStream = new MemoryStream())

  113.         {

  114.             serializer.WriteObject(memoryStream, this);


  115.             memoryStream.Position = 0;

  116.             using (StreamReader reader = new StreamReader(memoryStream))

  117.             {

  118.                 return reader.ReadToEnd();

  119.             }

  120.         }

  121.     }

  122. }

Now we know how to create a token (previous post) and represent metadata. so let us send a message




Code Snippet



  1. public static void SendMessage<T>(string serviceNamespace, string topicName,

  2.     T content, string token, string receiverName) where T : class

  3. {

  4.     var fullAddress = string.Format("https://{0}.{1}/{2}//messages?timeout=60",

  5.         serviceNamespace, sbHostName, topicName);


  6.     BrokerProperties brokeredProparties = new BrokerProperties();

  7.     brokeredProparties.To = receiverName;


  8.     WebClient webClient = new WebClient();

  9.     webClient.Headers[HttpRequestHeader.Authorization] = token;            

  10.     webClient.Headers["BrokerProperties"] = brokeredProparties.Serialize();

  11.                 

  12.     //All the message's properties are propagated so they can be used in a Sql Filter

  13.     foreach (var prop in typeof(T).GetProperties())

  14.     {

  15.         webClient.Headers[prop.Name] = prop.GetValue(content, null).ToString();

  16.     }            


  17.     webClient.UploadData(fullAddress, "POST", Serialize(content));

  18. }

As you can see I put the receiver name in the "To" properties of the BrokerProperties object. This will allow us later to create a rule that filter the messages accordingly (e.g. To=receiver)


Also you can see that I propagated all of the message's properties. A propagated property is placed as a Http header and provide the ability to later filter messages according to its value by creating a relevant rule.
In production I assume that you will propagate only the properties you need !!!


The body message contains the DataContract Serialization of our data.
All we need to do is send the Http Request (using POST verb) to our topic at:
https://{namespace}.{appfabric.windows.net}/{topicname}//messages?timeout=60




Serialization



  1. private static byte[] Serialize<T>(T content) where T : class

  2. {

  3.     try

  4.     {

  5.         var serializer = new DataContractSerializer(typeof(T));

  6.         MemoryStream memstream = new MemoryStream();

  7.         var writer = XmlDictionaryWriter.CreateTextWriter(memstream, Encoding.UTF8);

  8.         serializer.WriteObject(writer, content);

  9.         writer.Flush();


  10.         return memstream.ToArray();

  11.     }

  12.     catch (Exception)

  13.     {

  14.         // log this

  15.         return null;

  16.     }           

  17. }


Enjoy


Manu

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

7 comments

  1. Lior22 במרץ 2012 ב 20:14

    you should add the links to your past posts in the current post,
    It is not convient to find them without this link

    Reply
  2. Boawnwani12 באפריל 2012 ב 21:47

    There are basically two tests, one is a test on your urine, and the other one is a test on your blood. It also prevents from the moisture covers in the air that may play a major role in its disfunctioning. It is the duty of the doctor to exercise reasonable skills and to act diligently to his duties.
    Hsbc costco credit card customer service – http://www.ventures-me.com/UserFiles/Image/hall/seach_key.php?key=hsbc+malaysia+call+centre – Discover rewards hsbc
    Leukemia and Fanconi's Anemia are just some of the diseases treated by umbilical cord blood. Avoid using any of these products if you are allergic to it. Asthmatic bronchitis is mostly caused by exposure to external irritants rather than viruses and bacteria.

    Reply
  3. Hurihoido19 באפריל 2012 ב 21:07

    Easy solution, help your car out by going to a full stop in advance of shifting gears. Acne sufferers must be advised to cleanse their skin gently using a non-comedogenic moisturizer. If you normally eat four sandwiches, now only have two or three.
    absa branch roodepoort – http://absa-ben.co.uk/seach_key.php?key=absa+bank+swift+code
    Cloud Data Center enables organizations to adjust to modifying engineering far more quickly just because a computer software bring up to date which may have taken many months before now takes just several weeks. A little research into the notional value of chocolate brings some revelations over which candy lovers everywhere can rejoice – chocolate can be good for us, especially those that are sugar free and low in fat. This is because fungi grow well in damp airless places, like inside shoes, and on warm sweaty feet, and false nails do restrict the flow of air around the nail. Rarely are children allowed to express their feelings about the situation. How can we stop repugnance crimes against Catholics or at lowest possible achieve them recognised as such? Every weekend theres another report of a suspected sectarian attack against a Catholic, usually in Derry or north Antrim.
    branch code absa internet banking – http://absa-ben.co.uk/seach_key.php?key=absa+branch+times
    IBS is a very common condition and, as a large percent of sufferers do not see their GP, the incidence could be as high as 20% globally. Fasting, detox diets, herbal detox, detox baths, skin cleansing, use of antioxidants, use of enzymes and colon cleansing are some of the popular detoxification methods that you can use. Extensive studies have shown that many common illnesses (such as Eczema, Arthritis and many other problems) are related to deficiencies or imbalances of specific fatty acids, and in particular, Omega 3, 6 & 9. It has been said that you are what you eat, so it's very important to think about the food that we put in our mouths and how it affects the overall digestive process and residual effects on the body. The carbohydrate content of glycoproteins ranges from 1% to 85% by weight.

    Reply
  4. hugob16 באוגוסט 2012 ב 20:52

    Thanks. By this post I finally succeeded in sending my own properties via REST from an Android device to the ServiceBus. The ServiceBus.Messaging.BrokeredMessage class has a member Properties for application specific properties. And the MS documentation suggests that you add them as an json key/value pair array to a Properties member of e.g. your serialized BrokerProperties class. But that does not work. You have to flatten them and add them directly in the http header as your code shows (I translated this into Java for Android).
    BTW, on the WCF receiver that I am using, the application specific properties are delivered in the Properties member of the incoming message deserialized as BrokeredMessage. So ServiceBus collects them from the http header.

    Reply
  5. BluellubyJeon23 בנובמבר 2012 ב 13:25

    @CourtneyWillcox im sorry but its not christmas yet honey!!

    ——————————————————
    lightsmade.com

    Reply
  6. pseumpFiesk18 ביוני 2013 ב 2:55

    My various friend Bess, was ohio wearing Murano necklace, this a minimum of one emerald environmentally She had a multi function little black strapless decide what to wear and the necklace was really showing on the its chock – full glory. isglasses.com

    Reply