Saturday, 25 June 2016

BaaS with Kinvey and Delphi 10.1 Berlin

In this article I will show you how to connect your desktop and mobile applications to a mobile backend as a service (mBaaS) with Delphi 10.1 Berlin. I normally use as a backend but as they announced that they will close their mBaaS service I will use Kinvey instead.
If you are interested in you can read my previous articles about creating your own self-hosted Parse server and deploying a Parse server to Heroku which achieves similar result to what I want to explain you today (basically having your data hosted anywhere in the cloud either using Kinvey as an mBaaS or Parse + Heroku as a PaaS).
 There are plenty of articles online about these topics and I just want to give you my input and how I dealt with some of the challenges I faced during development.

Join Kinvey and create your App environment
First step is to join Kinvey and create your application environment. Kinvey offers a Free plan for developers that it is ideal to test your applications. It includes the core mBaaS features and 1GB of data storage. Once you move your solution into production you can switch over one of the other plans available.
Once you are in the console management, press "New App" and enter the name of your backend:
Now you should see your enviromnent created:
Click on the Development label and the dashboard will be shown:
At this moment in time, you should know what data you are going to store. In this example I have created a simple collection that includes several fields for a sample application that I'm building and that the source code can be found here:
Here is my collection of values:
*Note that if you POST data to a non-existing collection, this will be created automatically.

Handling collections
Now it's time to start using the collection and querying/adding data via Http REST. For this task you will have to identify the required headers that are needed for your GET/POST requests. You can see one example here for Parse.

Kinvey follows a different approach than Parse in terms of security. Kinvey offers basic and session authentiation. Basic authentication uses the HTTP header "Authorization" with the components "Basic" and Base64Encode(AppId:MasterSecret). Session authentication sends a login request to collct an auth token from Kinvey backend and then this token is used in subsequent REST requests.

I will focus on Basic authentication as Session authentication is as simple but with more steps.

The first example is by using REST via IdHttp so you can see how GET/POST are handled manually and the second example is just by using the Kinvey provider component available with our Delphi 10.1 Berlin that will make our life easier.

Here it's my Win64 example that uses Kinvey BaaS:

Add action, adds data into the collection and reload just brings the data back from the cloud and displays it in a listview component.

Here is the code behind it:
Add item:
Load data:
As you can see, each method uses a POST/GET command to baas.kinvey url with some arguments, headers and options. I find this way really useful as you can clearly see what's going on and easily map what you could do via curl:

If you want to run this example successfully you'll need to include libeay32.dll and ssleay32.dll from OpenSSL.

You can test this app and its mobile companion app using the source code here.

Using Kinvey Provider component
Delphi 10.1 Berlin has a KinveyProvider component that we can use directly without having to worry about the request details. You'll see below that to do the same as the code sample above we will need just few lines of code:
The KinveyProvider needs the parameters:

  • AppKey
  • AppSecret
  • MasterSecret
Get those from the Kinvey dashboard and off you go.

Then connect the BackEndStorage component to the KinveyProvider component.

Now, here is the code to Add items to the collection and to load the collection via components:
Load Data:
Add Item:
As you can see now it's way simpler.

And here my android app up and running:
Now I have a Win64 app and an Android app that share the same back end using Kinvey BaaS.

And the data in Kinvey:

Although this article it's quite long I'm sure you will find it quite interesting if you still haven't played with these components and the cloud.

Note that this BackEnd service will cease to exist shortly (as the appkey is hardcoded in the android app and the source code is available).

Do not hesitate to contact me if you have any questions.

Monday, 6 June 2016

Invoke PowerShell remote command with parameters with spaces via TeamCity

One of the coolest things to do with TeamCity is to run some external applications via PowerShell. This will allow us to invoke remote commands without having to install an additional agent on the remote target and it will allow us to centralise those commands from our build agent environment.

The idea behind it is as follows:
I have a centralised Build Agent environment and I need to run a command line application en two additional machines. I don't want to install any TeamCity agent on those machines as these are just deployment machines and should be independent of the bulding process. I just need to remote deploy some binaries there via Powershell and then execute the application.
These two additional machines are in the same network and WinRM is configured in every instance with the correct permissions so TeamCity can run the commands without problems.
There are loads of guides over the internet regarding WinRM configuration. Here is the screenshot from my local configuration on my Win10 machine. I run the same on the TeamCity agent, a Win2012 machine:

I had to tweak first with the wifi connection as it was set to public by default and it needs to be private. Then just enable PSRemoting and add the trusteshosts as all (*). Then to test it out, run the Test-WSMan myRemoteMachine and you should see something similar to the image above.

In TeamCity, there are two additional steps, one to copy some binaries to a remote machine and the second one to run the binaries remotely. Both steps running powershell:

Here is the command for each step:

And the remote execution from Powershell: