Validating Json Schema in Azure Logic Apps

Hi All,

In this post we will show how we can validate Json schema against the message  in Logic Apps. I and Krishna Pochanapeddi working on building an interface service in Logic Apps. We need to send a request message to Logic Apps request connector. We need to validate the same message against the Json schema. There is no capability within Logic Apps to validate the names of the fields in the Json message. We can do this easily using Azure Function by passing the Schema and request message using Azure Function connector. However, we do not want to use Azure function to validate schema. We want to use Logic Apps as a complete solution for these validation issues. It is easy to validate XML Schema using Integration Account but Json message cannot be validated.

After wondering for few hours; reading Json best practices; we  found the basic and powerful Json capability which is the object option “required”. Now we can mentioned the required fields (field names) in the schema itself.

We created below mentioned Json schema

{
“$schema”: “http://json-schema.org/draft-04/schema#”,
“definitions”: {},
“id”: “http://example.com/example.json”,
“properties”: {
“ChangePasswordRequest”: {
“id”: “/properties/ChangePasswordRequest”,
“properties”: {
“CurrentPassword”: {
“default”: “currenthashedpassword”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/CurrentPassword”,
“title”: “The currentpassword schema”,
“type”: “string”
        },
“Identifier”: {
“default”: “126”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/Identifier”,
“title”: “The identifier schema”,
“type”: “string”
        },
“IdentifierScheme”: {
“default”: “test”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/IdentifierScheme”,
“title”: “The identifierscheme schema”,
“type”: “string”
        },
“MessageIdentifier”: {
“default”: “f7b351fb-ade4-4361-bfc3-9bb7df783880”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/MessageIdentifiers”,
“title”: “The messageidentifiers schema”,
“type”: “string”
        },
“MessageTimeStamp”: {
“default”: “2016-04-04T14:15:02.6476354+10:00”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/MessageTimeStamp”,
“title”: “The messagetimestamp schema”,
“type”: “string”
        },
“NewPassword”: {
“default”: “Pass126”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/NewPassword”,
“title”: “The newpassword schema”,
“type”: “string”
        },
“NotificationAddress”: {
“default”: “kcpochanapeddi@gmail.com”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/NotificationAddress”,
“title”: “The notificationaddress schema”,
“type”: “string”
        },
“NotificationPreference”: {
“default”: “Email”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/NotificationPreference”,
“title”: “The notificationpreference schema”,
“type”: “string”
        },
“OriginatingSystem”: {
“default”: “test”,
“description”: “An explanation about the purpose of this instance.”,
“id”: “/properties/ChangePasswordRequest/properties/OriginatingSystem”,
“title”: “The originatingsystem schema”,
“type”: “string”
        }
      },
required”: [
“MessageIdentifier”,
“NotificationAddress”,
“CurrentPassword”,
“Identifier”,
“OriginatingSystem”,
“NotificationPreference”,
“NewPassword”,
“IdentifierScheme”,
“MessageTimeStamp”
      ],
“type”: “object”
    }
  },
“required”: [
“ChangePasswordRequest”
  ],
“type”: “object”
}

Added this schema in the Logic app request connector and Parse Json connector.

image

If we send a invalid message  as per below:

{
“ChangePasswordRequest”: {
“MessageIdentifier”: “f7b351fb-ade4-4361-bfc3-9bb7df783880”,
“OriginatingSystem”: “test”,
“MessageTimeStamp”: “2016-04-04T14:15:02.6476354+10:00”,
“Identifie”: “125”, <Invalid field name; valid is Identifier>
“IdentifierScheme”: “test”,
“CurrentPassword”: “currenthashedpassword”,
“NewPassword”: “YGU0PCPEM”,
“NotificationPreference”: “Email”,
“NotificationAddress”: “kcpochanapeddi@gmail.com”
  }
}

The above message fails in the parse Json with the message “Requred properties are missing from object…” as per the below screen:

image

Now this can be handled in Logic Apps using “Add a Parallel branch->Add an Action” as per below screen.

image

Click on eclipses on action “Execute stored procedure” and “Response 4” and click on configure run after to configure the appropriate action.

image

Yay!!! Well Done Krishna Smile.

Regards

Shadab

Advertisements

Creating Azure Virtual Machine from Disk Image and continuous deployment using Bamboo.

In this post I will showing how to use Bamboo to create Azure Virtual machine from existing disk image and to do deployment of the projects/artefacts on the newly created virtual machine. The Idea was to create a Dev/Test environment in the cloud with all the application installed.

  1. Create New Plan in Bamboo.

Screen Shot 2017-07-24 at 3.29.30 pm

2. Click on Configure Plan.

Add Task – Choose Script. Enter the PowerShell script as per the below. The script will ask for Azure Login details, enter your azure subscription login details. The below script will create a txt file VirtualMachine.txt with the value “BizTalkIpAddress=<IPAddress>” of the newly created Virtual machine

Screen Shot 2017-07-24 at 3.33.07 pm

Login-AzureRmAccount

Get-AzureRmSubscription

Select-AzureRmSubscription -SubscriptionId “<your subscription id>”

Set-AzureSubscription -SubscriptionId “<your subscription id”

$resourceGroupName = “Dev-BizTalk-VM-ResourceGroup”

$sourceUri = “https://<storage Name>.blob.core.windows.net/vhds/bt2013R2Lab01btOSDisk.vhd” #Link to your existing disk image vhd file.

$location = “australiasoutheast”

$snapshotName = “bt2013R2Lab01btOSDisk_snapshot”

$StorageName = “btdevstorage”

$StorageType = “StandardLRS”

## Network

$InterfaceName = “btNetworkInterface0” + ${bamboo.buildNumber}

Write-Host “Inteface:”,${bamboo.buildNumber}

$Subnet1Name = “btSubnet01” 

$VNetName = “btVNet01”

$VNetAddressPrefix = “10.0.0.0/16

$VNetSubnetAddressPrefix = “10.0.0.0/24

## Compute

$VMName = “bt2013R2Lab0” + ${bamboo.buildNumber}

$ComputerName = “bt2013R2Lab0” + ${bamboo.buildNumber}

$VMSize = “Standard_DS2_v2”

$OSDiskName = $VMName + “btOSDisk”

$disk = Get-AzureRmDisk -ResourceGroupName $resourceGroupName -DiskName $dataDiskName 

$osDiskName = “bt2013R2Lab0” + ${bamboo.buildNumber} + “btOSDisk”

Write-Host “OSDiskName:”,$osDiskName

$osDisk = New-AzureRmDisk -DiskName $osDiskName -Disk `

    (New-AzureRmDiskConfig -AccountType StandardLRS  -Location $location -CreateOption Import `

    -SourceUri $sourceUri) `

    -ResourceGroupName $resourceGroupName

$storageacc = Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroupName 

# Network

$vnet   = Get-AzureRMVirtualNetwork -Name $VNetName -ResourceGroupName $ResourceGroupName

$pip = New-AzureRmPublicIpAddress -Name $InterfaceName -ResourceGroupName $ResourceGroupName -Location $Location `

   -AllocationMethod Dynamic

$nic = New-AzureRmNetworkInterface -Name $InterfaceName -ResourceGroupName $ResourceGroupName `

    -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id

$user = “admin”

$password = ”

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force

$Credential = New-Object System.Management.Automation.PSCredential ($user, $securePassword) 

$vmConfig = New-AzureRmVMConfig -VMName $vmName -VMSize “Standard_A2”

$vm = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $nic.Id

# Create the VM in Azure

$vm = Set-AzureRmVMOSDisk -VM $vm -ManagedDiskId $osDisk.Id -StorageAccountType $StorageType `

    -DiskSizeInGB 128 -CreateOption Attach -Windows

New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $location -VM $vm

Set-AzureRmVMAccessExtension -ResourceGroupName $resourceGroupName -VMName $VMName `

    -Name $ComputerName -Location $location -UserName $Credential.GetNetworkCredential().Username `

    -Password $Credential.GetNetworkCredential().Password -typeHandlerVersion “2.0”

$net=Get-AzureRmPublicIpAddress -ResourceGroupName $resourceGroupName -Name $InterfaceName

$ipAddress = $net.IpAddress

$Content = “BizTalkIpAddress=$ipAddress”

Write-Host $Content

write-output $Content | add-content ${bamboo.build.working.directory}\Packages\VirtualMachine.txt

3.  Create Deployment Steps.

  • Artifact Download

Screen Shot 2017-07-24 at 3.36.44 pm

  • Inject Bamboo Variables. This is used to get the IP Address of the newly created virtual machine.

Screen Shot 2017-07-24 at 3.36.56 pm

  • Copy Package to the Azure VM. This is used to copy the downloaded packages to the newly created virtual machine.

$biztalkmachineIP =  ${bamboo.Azure.BizTalkIpAddress}

Write-Host “BizTalkIpAddress:”,${bamboo.Azure.BizTalkIpAddress}

$user = “admin”

$password = ”

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force

$Credential = New-Object System.Management.Automation.PSCredential ($user, $securePassword) 

$InstallerFile = “C:\SRC\STT.Common.IaaS.Test\STT.Common.IaaS.Test\MSI\STT.Common.IaaS.msi”

New-PSDrive -Name Y -PSProvider filesystem -Root “\\${bamboo.Azure.BizTalkIpAddress}\C$” -Credential $Credential

Copy-Item $InstallerFile -destination Y:\ -recurse 

Remove-PSDrive Y

#$session = New-PSSession -ComputerName ${bamboo.Azure.BizTalkIpAddress}  -Credential $Credential  -ConfigurationName Microsoft.Powershell32

#$LASTEXITCODE = Invoke-Command -Session $session -ScriptBlock {msiexec.exe /i “C:\STT.Common.IaaS.msi” /passive /log “c:\log.txt”}

Screen Shot 2017-07-24 at 3.37.52 pm

  • Install Application : This script will execute the installer package. This is just to prove that the packages are getting installed on the new machine.

Write-Host “BizTalkIpAddress:”,${bamboo.Azure.BizTalkIpAddress}

$user = “admin”

$password = ”

$securePassword = ConvertTo-SecureString $password -AsPlainText -Force

$Credential = New-Object System.Management.Automation.PSCredential ($user, $securePassword) 

$session = New-PSSession -ComputerName ${bamboo.Azure.BizTalkIpAddress}  -Credential $Credential  -ConfigurationName Microsoft.Powershell32

$LASTEXITCODE = Invoke-Command -Session $session -ScriptBlock {msiexec.exe /i “C:\STT.Common.IaaS.msi” /passive /log “c:\log.txt”}

$exit_status = $LASTEXITCODE

exit $exit_status

Screen Shot 2017-07-24 at 3.37.32 pm

The whole idea is to how create instant environment in the Cloud. Once the environment is created we can download/build the packages from any repository and deploy to the new machine. I’ve just used bamboo because to give visual touch and use as an continuous Integration and deployment.

Note: This is not the BizTalk environment, with BizTalk there is still few things to be done on the machine.

Thanks.