James Mann's Blog

The blog of James Mann

Azure Web Apps-Deploying Java Servlets to Azure App Service Web Apps

If you are considering to move to hosting your websites in Azure but either have a lot of legacy applications written in Java or your organisation is Java focussed, then Azure App Services provide the option to host Java code (Java Servlets, JSPs etc.) in the same way that they can host .NET code (ASP.NET Web Api, Forms, MVC etc.)

To test this, I have taken a pre-built WAR file containing a single Java Servlet, and see how much effort was required to host it in an Azure Web App.

The approach to hosting Java is as follows:

1. Create the Web App.

2. Go into the Web App, Enable the Java runtime and select your application server (Tomcat and Jetty are available).

image image

3. Upload your WAR file to the Web App. I chose FTP, but there are a number of options for publishing.  To reiterate, the process of publishing a Java Web App is exactly the same as if you were publishing a .NET Web App (except that you don’t have the option of using Visual Studio to publish).  Note: put your WAR file in the “site\wwroot\webapps” folder.  This isn’t immediately obvious and can be one of two places depending on how the web app was provisioned.  See this article for more information.

image

4. Confirm it as running.

That’s all there is to it.

Granted, this is a simple scenario, but Azure web apps have the capability to reach on to your on-premise network using things like Site-to-site VPN, ExpressRoute or Hybrid Connections to give you access to resources like databases, line-of-business systems etc. on your network.

Azure Logic Apps-The template language function 'json' parameter is not valid.

This is a follow up from my original blog post Azure Logic Apps–Parsing JSON message from service bus

If you see the following error from a Logic App using Service Bus trigger:

{"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'Next_action' inputs at line '1' and column '11': 'The template language function 'json' parameter is not valid. The provided value 'eydlbWFpbCcgOiAndGVzdEB0ZXN0LmNvbSd9' cannot be parsed: 'Unexpected character encountered while parsing value: e. Path '', line 0, position 0.'. Please see https://aka.ms/logicexpressions#json for usage details.'."}

It’s because messages that from service bus topic triggers are now presented as base 64 encoded messages rather than plain text.  Fortunately the fix is straightforward, Logic Apps give you a decodeBase64 function that you can use in the Logic App. 

You need to switch the Logic App to to code view, and use the decodeBase64 function before parsing the json.  So

image

becomes (note the call to decodeBase64 before the call to json):

image

UWP-Using WebAccountManager API to connect your Windows 10 to Microsoft Account

Prior to Windows 10 UWP the recommendation for federated authentication in Windows was (and still is) to use ADAL.net.

If you have a Windows 10 UWP application you have a new platform capability available to you called the WebAccountManager. This is the recommended approach going forward from Windows 10.

The Windows 10 UWP samples available on github https://github.com/Microsoft/Windows-universal-samples contain a sample WebAccountManagement which shows you how to integrate your app with Azure AD, Live connect, Local, and other identity providers.

I’ve been through the sample and distilled the key points for Microsoft Account integration.

  1. Provide a handler for AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested.  This is the method that windows will execute when the ‘login’ dialog is shown in your app.  At this stage you add the identity providers you want users to be able to log in with.
  2. Per provider, provide a handler for WebAccountProviderCommand. This is the method that windows will execute when the user has selected the identity provider from the list defined at stage 1.  At this stage, you will be physically issuing a login request using the WebAuthenticationCoreManager.  At the end of this handler, you should have a login result (success/fail) and a token which you can use in downstream processing.
  3. From your client (UWP app), tell the app to show the action settings page using Windows.UI.ApplicationSettings.AccountsSettingsPane.Show().  This will start the login process, and accordingly trigger the above handlers when users have interacted with the account settings pane.

   Below is the code to implement steps 1 and 2.  Note in this example I am using MVVM light dispatcher (Messenger.Default.Send) to deliver an event based message to subscribers.  You can use something like event aggregator or your flavour of pub/sub framework to achieve the same result:

public class Authenticator

{

    public Authenticator()

    {

        AccountsSettingsPane.GetForCurrentView().AccountCommandsRequested += Authenticator_AccountCommandsRequested;

    }

 

    private async void Authenticator_AccountCommandsRequested(AccountsSettingsPane sender, AccountsSettingsPaneCommandsRequestedEventArgs e)

    {

        AccountsSettingsPaneEventDeferral deferral = e.GetDeferral();

        var provider =

            await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", "consumers");

        WebAccountProviderCommand providerCommand = new WebAccountProviderCommand(provider, WebAccountProviderCommandInvoked);

        e.WebAccountProviderCommands.Add(providerCommand);

        e.HeaderText = "Please select an account to log in with";

        deferral.Complete();

    }

 

    private async void WebAccountProviderCommandInvoked(WebAccountProviderCommand command)

    {

        WebTokenRequest webTokenRequest = new WebTokenRequest(command.WebAccountProvider, "wl.basic", "none");

        WebTokenRequestResult webTokenRequestResult = await WebAuthenticationCoreManager.RequestTokenAsync(webTokenRequest);

        var token = webTokenRequestResult.ResponseData[0].Token;

        // sends a message with MVVM Light messenger. This is solution specific, typically you want to use the token to

        // query a service (for example live connect)

        Messenger.Default.Send(new AuthenticatedMessage() { Token = token});

    }

}

 

And below is the code to implement step 3:

Windows.UI.ApplicationSettings.AccountsSettingsPane.Show();

 

 Further reading

I’d encourage you to have a good look at the WebAccountManagement sample in https://github.com/Microsoft/Windows-universal-samples.  This samples contains more detail and different usage scenarios for reference.

Also have a look at Vittorio Bertocci’s post at https://blogs.technet.microsoft.com/ad/2015/08/03/develop-windows-universal-apps-with-azure-ad-and-the-windows-10-identity-api/ which gives a bit of background, explains when you should use ADAL.NET vs WebAccountmanager and has example of integrating with Azure AD.

LUIS.ai-First steps with Language Understanding Intelligent Sevice (beta)

LUIS is part of the suite of Microsoft Cognitive Services announced at build.  It allows you to process unstructured language queries and use them to interface with your applications.  It has particular relevance any business process which benefits from human interaction patterns (support, customer service etc.).  Having looked at LUIS from the point of absolute novice, I’ve put together a few points which may be useful to others.

I’ve broken this down into ‘things to do’ when getting started. To illustrate the steps, I’ll use the very simple example of ordering a sandwich.  A sandwich has a number of toppings and can also have sauce on it. 

The role of LUIS is to take plain English and parse it into a structure that my app can process.  When I say “can I order a bacon sandwich with brown sauce” I want LUIS to tell me that a) an order has been placed, b) the topping is bacon, c) the sauce is brown.  Once LUIS has provided that data then my app can act accordingly.

So for LUIS to understand the sandwich ordering language: You need to define entities, define intents and then train and test the model before using it.  Read on to understand what I mean by these high level statements. 

1. Define your ‘entities’

These are the ‘things’ you are talking about.  For me, my entities are ‘sauce’, and ‘topping’.  I also have ‘extra’ which is a generalisation of any other unstructured information the customer might want to provide – so things like Gluten free, no butter etc.

2. Define your ‘intents’

These are the context in which the entities are used.  For me, I only have one intent defined which is ‘order’.

3. Test/train the model – use ‘utterances’

After entities and intents have been defined you can begin to test the model. 

Initially, the untrained LUIS will be really bad at understanding you.  That’s the nature of machine learning. But as it is trained with more language patterns and told what these mean it will become increasingly accurate.

To begin the process LUIS needs to be interacted with.  LUIS calls interactions ‘utterances’.  An utterance is an unstructured sentence that hasn’t been processed in any way.

In the portal you can enter an utterance to train or test the model. 

Here, I am adding the utterance “can I order a sausage sandwich with tomato sauce”.  I’ll select the entities that are part of that utterance (sausage and tomato sauce) and tell LUIS what they are.

image

You can repeat this process with as many variations of language as possible, for example “give me a bacon sandwich”, and  “I want a sausage sandwich with brown sauce” etc. It’s recommended to try this exercise with different people as different people will say the same thing with unique speech patterns. The more trained variations the better, basically.  You can, and will come back to train it later though, so don’t feel it has to be 100% at this stage.

Once you go live with the model - LUIS will come across patterns that it cannot fully process, for this the feedback loop for training is very important.  LUIS will log all the interactions it has had, you can access them using the publish button.

imageimage

These logs are important as they give you insight into your customers language.  You should use this data to train LUIS and improve its future accuracy.

4. Use the model

Finally, and I guess most importantly you need to use the model. If you look in the screenshot above there is a box where you can type in a query, aka an utterance. The query string will look something like this:

https://api.projectoxford.ai/luis/v1/application?id=<appid>&subscription-key=<subscriptionkey>&q=can%20i%20order%20a%20bacon%20sandwich%20with%20brown%20sauce

This basically issues a HTTP GET against the LUIS API and returns the processed result in a JSON object. 

image

I’ve annotated the diagram so you can see:

A) the query supplied to LUIS.

B) the topping entity that it picked out.

C) the sauce entity that it picked out.

In addition to this, you will see other things such as the recognised intent, the confidence of the results, etc.  I encourage you to explore the structure of this data.  You can use this data in any application that can issue a HTTP get, and process them accordingly. 

I’ll write later on bot framework which has built in forms engine to interface with LUIS models, enhancing the language capabilities with structured processing.

This is a simple example but hopefully it shows the potential use cases for this, and gives you some pointers to get started.

Azure Logic Apps-Service Bus connector not automatically triggering?

By default logic apps will be set to trigger every 60 minutes which, if you are not aware, may lead you to thinking that your logic app isn’t working at all!

As Logic Apps are preview there are some features that are not available through the designer yet, but you can do a lot through the Code view.

In this instance you can set the frequency to Second, Minute, Hour, Day, Week, Month or Year.  For a frequency of every minute it is required to be on a standard service plan or better. If your service plan doesn’t allow the frequency you will get an error as soon as you try and save the logic app.  Here’s what I set to have it run every minute.

. image

More information can be found at https://msdn.microsoft.com/en-us/library/azure/dn948511.aspx.

Azure Logic Apps–Parsing JSON message from service bus

What I want: When the logic app trigger receives a JSON formatted message from Azure Service Bus topic, I want to send a notification to the “email” field.  My sample message structure looks like this:

image

What happens: Because a message received on service bus doesn’t have a predefined format – it could be JSON, XML, or anything else – so Logic Apps doesn’t know the structure of the message.  So in the designer, it looks like:

image

Which is great, but it just dumps out the entire object, and not the email field that I need.

How to fix it: Fortunately the fix is pretty easy, basically you need

1) Select the Content output (above), you are going to edit this value.

2) Switch over to ‘Code view’ and manually type the expression (below).

If you haven't used it before, code view can be found in the toolbar:

image

Once you are in the code view, scroll down to the connector you are interested in. You will see the expression for the trigger body. This is the entire message received from the trigger, basically.

image

You need to modify this to parse the entire message using the ‘json’ function, then you can access it’s typed fields.

If you have ever used JSON.parse (or any object deserialization in pretty much any language for that matter) this concept should be familiar to you.  When I was done I ended up with:

image

I’ve broken the entire segment into two parts, a) parses the content and b) accesses the ‘email’ field of the parsed JSON object.

Hope this helps someone!

 

Update: if you are seeing an error when trying to parse see my new blog post Azure Logic Apps-The template language function 'json' parameter is not valid.

Generate my namespace based on InfoPath URN

There is a direct correlation between a form template URN and the my namespace uri that is required by infopath forms referencing the template.

This little method will give you the namespace required for a given template URN. This is nothing complex, but is handy nontheless.

public static string GetInfoPathNamespaceForUrn(string urn)
{
  string inputdate = new Regex(".*myXSD-(?<date>.*)").Match(urn).Groups["date"].Value;
  string outputdate = DateTime.ParseExact(inputdate, "yyyy-MM-ddTHH-mm-ss", CultureInfo.InvariantCulture).ToString("yyyy-MM-ddTHH:mm:ss");
  return string.Format(@"http://schemas.microsoft.com/office/infopath/2003/myXSD/{0}", outputdate);
}

 

Enumerate web applications on a sharepoint farm

To enumerate site collections on a farm:
SPWebService contentService = SPWebService.ContentService;

foreach(SPWebApplication app in contentService.WebApplications) 
{
  if (app.Sites.Count > 0) 
  {
    // pick the first site (root site)
    SPSite rootSite = app.Sites[0];
    
    Trace.WriteLine(site.Url);
  }
}

Get the item a SharePoint workflow task is associated with

This is handy. SharePoint helpfully populates the meta data with the GUID of the list and the ID of the item a WF instance is associated with. These are stored in "ows_WorkflowListId" and "ows_WorkflowItemId" fields on the task list item.

 An example of using this is from an InfoPath form in the form load code behind.

SPListItem currentListItem = SPContext.Current.ListItem;
if (currentListItem != null)
{
  object associatedWfListId = currentListItem["ows_WorkflowListId"];
  object associatedWfItemId = currentListItem["ows_WorkflowItemId"];
 
  if (associatedWfItemId != null && associatedWfListId != null)
  {
    SPListItem item = web.Lists.GetList(new Guid(associatedWfListId.ToString()), false).GetItemById(int.Parse(associatedWfItemId.ToString()));
    // THE ABOVE ITEM IS THE ASSOCIATED LIST ITEM
  }
}