patkua@work

The intersection of technology and leadership

Page 17 of 53

Updating a Dynamics CRM Customer Record via HTTP

My current project integrates with the Microsoft Dynamics CRM system for managing customer records. We already spiked out authenticating and our next step was attempting to update a record via its “REST Endpoint“.

On retrieving a record, you follow the OData style for finding something of relevant. Updating a record is interesting as we only want to send the fields that need to change remotely. Looking at their sample code, you need to:

  • Create an authenticated POST request
  • Set the X-HTTP-Method to MERGE
  • Set the appropriate content type for the content you intend on sending. In our case, set the header Accept to application/json and the Content-Type to application/json; charset=utf-8

Our end point for a contact looked something like:

https://crm.thekua.com/xrmservices/2011/organizationdata.svc/ContactSet(guid'867dc3f2-909e-e111-9912-0050569c2d72')

.

Updating simple fields off a contact is easy. We post something like:

{
  "EMailAddress1":"spike.jones4@gmail.com",
  "MobilePhone":"33335"
}

We receive a HTTP 204 (No Content) on a success. Posting an invalid attribute (i.e. one that does not exist on the ContactSet such as “EMailAddreXXXs1”) results in a HTTP 400 (Bad request) and a nice description about what’s wrong. You will also get a HTTP 400 if you post the wrong datatype such as sending a string where they expect a number. If you pass invalid values (but of the correct datatype) for a field, your response is a HTTP 500 with a message like The value of 'gendercode' on record of type 'contact' is outside the valid range."

Updating Option Set Values

Updating simple datatypes is easy and obvious from a JSON point of view. You have a couple of complex datatypes, such as the standard GenderCode. When you query for a record, you get back something that looks like

{"GenderCode"=>{"__metadata"=>{"type"=>"Microsoft.Crm.Sdk.Data.Services.OptionSetValue"}, "Value"=>1}}

To update something like this, you need to send a nested JSON object. The example follows

{
  "EMailAddress1":"spike.jones4@gmail.com",
  "MobilePhone":"33335",
  "GenderCode": { 
    "Value" : "1"
  }
}

A HTTP 204 (No Content) response indicates a success. Viola!

Time Configuration Values for Nginx

A lot of the documentation for the configuration values for Nginx keep referring to the time value. These pages don’t directly link to the right page (so not helpful if you come in via a search engine) but you’ll find the documentation under the “References” section titled generically “Configuration Notation Reference”.

I’m saving this link here for my own future reference.

Constructor work in Scala

In the java/ruby world, I am used to ensuring my objects are created in a valid state. This often means validating/converting constructor arguments into a format necessary for the rest of the class to do its work. In java, the code (non-compilable) might look like:

public class MyObject {
  ...

  public MyObject(Set<String> values) {
     this.internalRepresentation = convertToLowerCase(values)
  }

  ...
}

In scala, most examples out there seem to only chain constructors, and not necessarily do any work to that. I looked on stackoverflow and found this answer although it doesn’t feel particularly clean to me for some reason. My scala code now looks like this:

class MyObject(var values: Set[String]) {
  values = values.map(s => s.toLowerCase)
  ...
}

What I don’t like about this is that I had to elevate my field to being mutable, or had to have two immutable fields on the class (the temporary one for the constructor, and the one that I really want to use). The tests are passing, but I’m sure there is a better way.

Simplicity of Leaving Things Out

Last year, I worked on an in-house application replacing a 3rd party product our client picked. The 3rd party product had numerous problems such as reports that threw “SQL column not found” errors at end users and a clunky interface that required so many clicks to accomplish a single task. More importantly the vendor could not meet new hosting requirements demanded by new geographic legislation. We involved a User Experience designer very early on in the rebuild, focusing on who used the system and what they needed it to do.

In the end, we ended up with a very simple application. We did nothing special from a technical point of view but we fought hard to keep unnecessary features out until we validated how it would be used by end users. I’m glad we did it as well.

Our Product Owner took the Net Promoter Score (NPS) for the original tool. This score is something that apparently Apple rely on heavily for user feedback. The 3rd party tool scored a disappointing -27%. Our Product Owner took the score again a couple of weeks after the release of the new tool. This new tool got an amazing +63% (a 90 point change!).

Our endeavour to keep the application as simple as possible paid off. Users had a much easier time accomplishing what they needed to do instead of clicking all over the place.

Tapping into dynamic programming with Ruby

I had a task to analyse the value of a cookie set by a tool on the subdomain. The value of the cookie set looked something like this:

"18337|20120404|True#Q0A|18342|21-30|20120404|18344#Q1|18349|NO PARTNER|20120404|18351#Q2|18352|EMPLOYED|20120404|18353#Q4|18432|STRUGGLING|18539|WANT|20120404|18541#Q3|18358|EMPLOYED|20120404|18359#"

My task was to try to decipher the values of set inside the cookie and how they changed depending on the progress through the application that set the values. I was told the answers to questions sat next to the ID of the question. For example, the answer to the “age” question (21-30) was related to the question 18342 and would always appear as |18342|21-30|. I started out with some tests and ended up with a method like this:

class Answers
  attr_accessor :age, :employment_status, :has_partner

  def parse(cookie_contents)
    items = cookie_contents.split("|")
    items.each_index do | i |
       current = items[i]
       if (current == "18342")  
         @age = items[i+1]
       elsif (current == "18352") 
         @employment_status = items[i+1]
       elsif (current == "18349") 
         @current_partner = items[i+1]
       end
    end    
  end
end

Of course, I wanted to avoid the growing if-else statement so found a way that I could do it dynamically and focus just on the mapping from an ID to an attribute. The resulting code looked like this:

class Answers
  attr_accessor :age, :employment_status, :has_partner
  
  Mappings = {
    "18342" => :age=, 
    "18352" => :employment_status=, 
    "18349" => :has_partner=
  }  

  def parse(cookie_contents)
    items = cookie_contents.split("|")
    items.each_index do | i |
       current = items[i]
       if (Mappings.has_key?(current))
          self.public_send(Mappings[current], items[i+1])
       end
    end    
  end
end

By the end of the analysis, I discovered that multiple IDs mapped to the same properties and all I had to do was add another entry into the map defining which ID mapped to what property on the object. With java/.net being more of my background, I was pleased to see how brief the code turned out to be.

8 years at ThoughtWorks

Friday marked eight years since working at ThoughtWorks and thought it’d be a useful exercise to reflect on it. During that time, I’ve seen the company grow and the number of opportunities grow with it as well. I was at the pub last night (one of those ThoughtWorks UK traditions) and was trying to explain my role to someone. On my business card, it’s the title of Generalising Specialist. I’m a developer most of the time and although as a Technical Leader you don’t develop 100% of the time (who does?) I still get to do a huge amount.

Reflecting on the past
I’ve had plenty of opportunities to do a lot of public speaking and was proud to be invited to speak at Øredev, QCon and this year to Goto Aarhus (formerly JAOO). I see it as a great way to share knowledge and contribute back to the development community and to continue to spread great ideas. As I always tell people there is a lot of value in being a meme-carrier and helping introduce memes into newer communities.

At the same time, I’ve worked as a trainer, facilitator and an advisor doing some short term pure consulting engagements working with CTOs and CIOs on how they run their software organisation, how they’ve architected their software systems and helping them build a roadmap to a better pace. My passion for Systems Thinking, Lean thinking and the belief of constantly being open to new approaches and ideas helps me see and explain things that others often get stuck on.

Work wise, I’ve now worked in many places. Last year I spent a significant portion of that time in Germany, Berlin to be exact. It’s not the best place to learn German, but my passion for learning drove me to self-learn enough that I can hold a conversation in a bar reasonably well. I’ve got plenty more to go before I can start writing any blog entries or immerse myself in a completely German speaking work environment but pretty happy with the progress so far. Overall I’ve worked in Australia, Canada, Denmark, Germany and the United Kingdom for my clients with travel for conferences to many more.

I continue to appreciate the different opportunities and the continuous mix of people that I get to work with. As an example, we have a project of about 15 people all representing about 12 different nationalities. We have four females on our project (2 of which are developers) and so many interesting approaches and conversations with a consistent focus on trying to do the right thing for the client. I have to always remind myself other companies or contractors do not stand for the same values and I constantly appreciate.

Thinking about the future
Although I’ve been published in a book before, my goal is to finish a book, The Retrospective Handbook some time this year. Leave a comment to let me know what you think or tell me about your interest.

I will continue to write code, although this year I plan to specifically deepen my javascript and ruby skills. I will continue applying systems thinking but deepen its application into the software realm and how it can be made more appropriate.

I plan on cutting back on the number of speaking engagements. Last year it was almost one or more every month and the variety proved rather stressful at times when trying to balance life and work.

Book Review: Liftoff

At this year’s OOP Conference, Diana Larsen gave me a copy of her latest book, “Liftoff: Launching Agile Teams & Projects” and I promised to write her a review. I found myself with some time on a flight to Chicago and finally got around to reading it. I’m pleased that I did. It’s not a very thick book, but it’s definitely packed with great advice for teams from both Diana and her co-author Ainsley Nies.

Roughly broken into two sections, the book covers why teams should do a Liftoff and great recommendations on how to go about doing it. I agree completely with their premise at the start of the book – a lot about the productivity of teams and organisations often get set in the beginning. Whilst there is great value running a Liftoff even in the midst of a project, if one hasn’t yet run, it offers an opportunity for working relationships to start right at the beginning.

Liftoff Book

It many ways, the Liftoff overlaps with several of the activities we often run during a ThoughtWorks Inception (covered a lot in the Jonathan Rasmussen’s Agile Samurai book). During these periods, we try to help businesses shape the project, and even help them question whether or not the project should even run (fail fast!)

The book offers even more value by focusing on, given a project vision, helping align everyone in a way that helps them work towards that vision. The authors often refer to the trio of elements to cover including Purpose-Alignment-Context to which they describe some very practical advice on planning and running a project liftoff.

I like the way that they’ve also used a number of examples, including one for their own book, that shares examples of the positive impact that liftoffs done well can have for organisations. The book is dense with lots of advice such as detailing who should be involved, what sort of activities you might run, and a set of principles to plan and run your liftoff with.

The second half of the book focuses on agile chartering, making it relevant for teams working today in an agile environment, and who will most likely pick up a copy of this book. I see it as a useful example of applying the first section (liftoffs in general), to a particular working environment and making it more concrete as a guided walkthrough backed by even more real life stories throughout.

I see a lot of value in this for many teams. So many initiatives often get started that people forget about spending time on establishing a real sense of culture and purpose. The result is clear – a group of people that constantly “step around” issues, or a group of people all pulling in different directions clearly visible in the final solution.

What I also like about this practice, is that it doesn’t even have to be about software initiatives and is relevant for any group of people working towards a common purpose.

I think a lot of people will like the fact that it is such a short book. If you’ve read Diana’s other book, Agile Retrospectives, you’ll be familiar with a set of activities that are useful in a different context. This book doesn’t detail the activities that you might choose to run – I see this as too much for a book like this, but covers the important aspects around the thinking behind the activities you might run for your project liftoff.

Learning with lunchtime videos

One of the greatest things I appreciate about my work colleagues is their passion for learning and growing themselves as people. As an example, one of my work colleagues, Duana (@starkcoffee), brought in the practice of Friday lunchtime video sessions at a common client of ours last year.

To make it effective, and to make it relevant to all people, she worked with everyone to brainstorm a list of videos that we could watch over lunch. We would bring sandwiches, or grab food to bring back to the office where we sat in a meeting room watching these videos over lunch. The goal was to try to watch a video that worked not just one part of the brain that we used in day-to-day programming, but to watch videos that would inspire and exercise the other half.

I really enjoyed the practice and need to remind myself of this great ritual. It brought people together from different parts of the organisations, and was great watching a number of different topics from different areas. We watched a number of videos from technical sources loaded onto places like InfoQ, or Vimeo and sourced a number of other “alternative” videos from sites like TED or Youtube. The challenge was finding two short videos that you could watch over a lunch-hour, so we tended to go for 15-20 minute videos.

Here’s a list of great videos to get you started:

« Older posts Newer posts »

© 2024 patkua@work

Theme by Anders NorenUp ↑