Wednesday, 4 January 2017

Grails on Bluemix: Set up fully automated CI/CD Environment

Java Developers love Grails Framework and Good News is that Bluemix WAS Liberty Buildpack also supports running Grails applications.
However, most of the sample applications showcase that you need to compile WAR file locally and then has to be pushed to Bluemix.
This is not the desired option where most of the developers expect a completely automated CI/CD environment.

I have setup a Bluemix environment for Grails 3 CI/CD setup using Bluemix DevOps capabilities. As a developer, you need to just commit and push your code to Git repository either on Bluemix or Github and then the Bluemix Delivery Pipeline will perform Grails Build process to create WAR file and then can be deployed to either CloudFoundry or Docker Containers runtime on Bluemix.
Use this as a starter project to setup a delivery pipeline to develop on local environment, commit and push the changes to Git repository and then automatically build and deploy the application on Bluemix Cloud Foundry.

Bluemix Devops project:

Github Code Repository:

This one is developed with Gradle 3, but I have used the following command to create the War file in cloud: ./gradlew clean assemble. We can try the similar approach with your existing Grails build tool as well.

Delivery Pipeline Configuration

Build Command:
./gradlew clean assemble

Tuesday, 6 December 2016

Manage Bluemix Apps in your own Code using CloudFoundry APIs – Part 2

This post is second part of first section where I outlined the business requirement and possibilities of using Cloud Foundry APIs to schedule the Auto-Start/Stop of Applications in a particular Space.

Link to first Part: Part 1

You can access the Source code of application on Github:

Live Demo:

Screenshot of Application:

Tuesday, 3 May 2016

Manage Bluemix Apps in your own Code using CloudFoundry APIs – Part 1

Bluemix provides a wonderful platform for rapidly developing innovative apps. The following series will guide how you can manage Bluemix applications from your own code.

This capability can be relevant to many UseCases like:

  • Auto-Schedule Start/Stop of Applications in Bluemix Dev Space based on team’s worktime.
  • Integrate Bluemix Application Deployment process with Organization’s Business Process.
  • Create Custom Dashboard displaying All Apps, Services, Billing Details, Usage
  • Setup Custom Notifications based on Bluemix account Usage details.

The Application provided is developed using NodeJS, Bootstrap V3 UI, CloudFoundry APIs, Cloudant Database, Bluemix SSO, Workload Scheduler service.

Following is the screenshot of Application and deployed at following URL:

In next parts of the series, I’ll cover how to develop such capability.


Tuesday, 9 February 2016

Writing Blogs On the Move – Use ‘Open Live Writer’

I was using Windows Live Writer till last year, but Microsoft stopped updating the same sometime back..

Recently, the code was OpenSourced and a new Project “Open Live Writer” has been launched in Github !

This tool is the future of Windows Live Writer and already contains Security enhancements. So, now you can connect your favourite Blogs to OLW !

I am publishing this post from Open Live Writer..




Welcome to my blog !

Welcome to my blog !!

Installing Syntax Highlighting..

Use one of the following formats to enable highlighting code in blog post.

<!--?prettify lang=js linenums=true?-->
<pre class="prettyprint">
addEventListener('load', function() {
  var code = document.querySelector('#code');
  var worker = new Worker('worker.js');
  worker.onmessage = function(event) { code.innerHTML =; }

<pre class="prettyprint linenums">
addEventListener('load', function() {
  var code = document.querySelector('#code');
  var worker = new Worker('worker.js');
  worker.onmessage = function(event) { code.innerHTML =; }

Tuesday, 25 August 2015

IBM VERSE: Synchronize Recent Contacts from Notes Client to VERSE

Customers appreciate the new User Experience of IBM Verse, but the moment they start using it, the first problem they face is that while typing name, recent contacts are not available, which are there in Notes Client. So, customers were forced to either search customer emails or copy from Notes Client.

To avoid the same, I created a script to copy the Recent Contacts to My Contacts and Sync it to Server.

Steps are as follows: :

1.Create a Notes button using following code to Migrate Recent Contacts in Notes Client to My Contacts.

Sub Click(Source As Button)
    Dim s As New NotesSession
    Dim vw As NotesView
    Dim doc As NotesDocument
    Dim db As NotesDatabase
    Dim doc2 As NotesDocument
    On Err Goto ErrHandler
    Dim total As Integer, cnt As Integer
    msg = "Please ensure that you don't run this code multiple times, else it will create duplicates in your Addressbook. " + Chr(10) & _
    "Are you sure to run this code ?"
    If Messagebox(msg, 36, "Are you sure ? ") = 7  Then
        Msgbox "The action has been cancelled", 64, "Cancelled"
        Exit Sub
    End If
    Set db = s.GetDatabase("", "names.nsf")
    Set vw = db.GetView("RecentCollaborators")
    total = vw.AllEntries.Count
    cnt = 0
    Set doc = vw.GetFirstDocument
    While Not doc Is Nothing
        cnt = cnt + 1
        Print "Processing " & cnt & " / " & total & " document"
        Set doc2 = vw.GetNextDocument(doc)
        RCtype = doc.GetItemValue("type")
        If Lcase(RCtype(0)) = "group" Then
            'Skip the doc
            'Move to My Contacts
            Call RCReplace(doc, db)
        End If
        Set doc = doc2
    Messagebox "Migration process has completed.", 64, "Complete"
    Exit Sub
    Goto NextDoc
End Sub

Sub RCReplace(RCDoc As notesdocument, db As NotesDatabase)   
    On Error Resume Next
    Call RCDoc.replaceitemvalue("Form", "Person")  'DNT
    If Lcase(rcDoc.getitemvalue("Type")(0)) <> Lcase("PeRsOn") Then
        Call RCDoc.replaceitemvalue("Type", "Person")   'DNT
        'this code is in place for Mail-In Database records, with only  hierarchical name in Fullname item
        RCFN = rcdoc.getitemvalue("Fullname")
        If Ubound(RCFN) = 0 Then
            Dim FNname As New notesname(RCFN(0))
            CanonFN = FNname.canonical
            If CanonFN <> "" Then
                Redim NewFN(1)               
            End If
            NewFN(0) = FNname.canonical
            NewFN(1) = FNname.common
            Call RCdoc.replaceitemvalue("Fullname", NewFN)
        End If
        ' /end Mail-In Db specific code
    End If   
    Call RCdoc.replaceitemvalue("$AutoCreatedList", "")
    Call RCdoc.replaceitemvalue("$DPABState", "")
    Call RCdoc.replaceitemvalue("$DPAB_State", "")   
    Set newContact = RCdoc.CopyToDatabase( db )
    Call RCDoc.remove(True)
End Sub

Note: Click "Yes" if any prompt comes up for Trusting Code.

2. Goto Notes Client --> File Menu --> Preferences.

3. Open Contacts section and ensure "Enable Synchronize Contacts" option is enabled.


4. Goto Replication and Sync Tab and ensure that "Synchronize Contacts Replication is Enabled.


5. Once Synced, All the Recent Contacts will be available in IBM Verse as well !

For more details, refer to IBM Wiki.

IBM VERSE Hybrid Deployment via Pass-thru only environment – without Internet Connection at each Machine

For a BFSI Customer, I recently implemented IBM Verse Hybrid deployment as a PoC. The major requirements were as follows:

  • No Internet connection to be provided at each individual machine.
  • Internet Proxy license not available for majority of users. If needed for Mailing, the cost of Proxy license to be added to TCO.
  • No direct connection from any Domino Server in MZ to Internet

IBM Verse Hybrid deployment System requirement clearly states that Internet connectivity is required from each machine for Notes Client configuration. Also, each Domino Server should be able to reach to Cloud Servers for Mail routing.

We addressed the challenge in two parts:

1. Configured On-premise Domino Servers to reach Cloud Servers via Pass-thru.

  • To achieve the same, create Connection document to Cloud Server OU via Pass-thru server.
  • In Pass-thru server, allow “*/CLOUD/<CUSTOMER_ORG>” as Allowed Destination via Pass-thru server. Also, allow all users to access the Pass-thru server by adding “*” to the “Who can access the Server” field.
  • Once done, trace the Cloud Servers from On-premise server. The connection should get established via Pass-thru server.

2.  Configure Notes Client to connect to Cloud servers via Pass-thru:

  • In this scenario, default method of downloading config.nsf and running won’t work, as config.nsf require internet connectivity over port 1352 NRPC to connect to Cloud servers.
  • To overcome this challenge, I created below script, which creates one Connection document to Pass-thru Server, one connection document to Cloud Servers using Pass-thru server.
  • Also, it modifies current location to ensure that Cloud Server is now configured as Home Mail Server in Notes Client. This information is available in On-premise directory (replicated via Directory Sync).
  • Additional Location doc can be created as well to allow users to connect directly to Cloud servers from Home using Internet connectivity from their Laptops.

Sub Click(Source As Button)
    Dim Workspace As New NotesUIWorkspace
    Dim UIDdoc As NotesUIDocument
    'Create Connection Doc to Pass-thru Server
    Set uidoc = workspace.composedocument("","names.nsf","Connection")
    Call uidoc.fieldsettext("ConnectionType","Local Area Network")
    Call uidoc.refreshhideformulas
    Call uidoc.fieldsettext("PortName","TCPIP")
    Call uidoc.fieldsettext("LanPortName","TCPIP")
    Call uidoc.fieldsettext("ConnectionLocation","*")
    Call uidoc.refreshhideformulas
    Call uidoc.fieldsettext("Destination","<PASS_THRU_SERVER>/<OU>/<CUSTOMER_ORG>")
    Call uidoc.fieldsettext("OptionalNetworkAddress","<IP_ADDRESS_OF_PASS_THRU>")
    Call uidoc.fieldsettext("Source","*")
    Call uidoc.refresh
    Call uidoc.close
    Set uidoc = workspace.composedocument("","names.nsf","Connection")
    Call uidoc.fieldsettext("ConnectionType","Passthru Server")
    Call uidoc.refreshhideformulas
    Call uidoc.fieldsettext("PassthruServer","<PASS_THRU_SERVER>/<OU>/<CUSTOMER_ORG>")
    Call uidoc.fieldsettext("ConnectionLocation","*")
    Call uidoc.refreshhideformulas
    Call uidoc.fieldsettext("Destination","*/CLOUD/<CUSTOMER_ORG>")
    Call uidoc.fieldsettext("Source","*")
    Call uidoc.refresh
    Call uidoc.close
    'Modify Current Location Document
    Dim session As New NotesSession
    Dim pnab As New NotesDatabase("", "names.nsf")
    Dim dbNab As NotesDatabase
    Dim currlocdoc As NotesDocument
    Dim vw As NotesView
    Dim doc As NotesDocument
    ' Pick out the second argument in Location INI variable (i.e. the Note IDof current location)
    'Following string extraction cannot be done with R5 StrLeft() StrRight() fcns b/c it won't work in R4 client, hence good old @formula Evaluate() to the rescue...
    CurrLocation$=session.GetEnvironmentString("Location", True)
    CurrLocationNoteID=Evaluate( { @Left(@Right("} & CurrLocation$ & {"; ",");",") } )
    Set currlocdoc=pnab.GetDocumentbyID( CurrLocationNoteID(0) )
    'Get the new Home Mail Server information from the Directory. Since directory is synchronized with Cloud, therefore On-premise directory will also contain the new Server information in updated person document of user.
    Set dbNab = session.GetDatabase("<IP_ADDRESS_ANY_ON_PREMISE_DIRECTORY_SERVER>", "names.nsf")
    Set vw = dbNab.GetView("People")
    Set doc = vw.GetDocumentByKey(session.UserName, True)
    If Not doc Is Nothing Then
        Call currlocdoc.replaceitemvalue ("MailServer", doc.MailServer(0))
        Call (True,True)
        Messagebox "Person Document not found. Please configure Location Document Manually.", 48, "Error Occured"
        Exit Sub
    End If
    Messagebox "Notes Client Configuration has completed successfully.", 64, "Configuration Complete"   
End Sub


Please feel free to reach me if any clarification required for the above description.