My first Bluemix XPages application

Sunday, August 30, 2015 6:31 PM UTC

Last week I had a great call with some of the members of the team of IBM Bluemix and Domino. Thank you very much, Pete Janzen, Martin Donnelly, Eamon Muldon and Padraic Edwards for answering my questions and for offering help and support on my journey with XPages on Bluemix. I must admit that I didn't find the time until now to dabble around with it but this call was a motivation. Here is what I did and experienced in the past days.

My start

I wanted to start with an own application instead of starting with the demo application for the XPages runtime and the Domino NoSQL service. I started with setting up the Domino data service and later bound it to the XSP runtime. When you set up the data service you will be offered a special Notes ID which you should download to your client data folder (or somewhere else). Please note down the login credentials and address informations for it. Notice the database details section: it clearly tells you which NSF filepath and filename is used to store data. Of course you can use other databases - with a little trick I'll explain later.

Preparation

For your development environment you should prepare your Domino server and your DDE. Let's start with DDE: download the latest Extension Library (v13) and install it on your DDE. To use the new Java classes for accessing Bluemix you have to install it on your server, too. I will use a bean to access my data store even when I am working locally. Next steo is to cross certify the Bluemix Notes ID on your server. If you don't have access to the certifier ID then you have to setup a completely new server where you have the cert ID. I set up an own server for Bluemix development as I am not able to access the cert ID of my sdefault server. If you don't know how to cross certify an ID on your system then please google for it. It's a simple administrative process.
After you installed Extlib 13 on DDE you should see a new section in the DDE preferences called "IBM Bluemix". Please setup your ownn Bluemix access data and test the connection. It's important that the endpoint is the same as you used for setting up the XSP runtime, e.g. https://api.ng.bluemix.net.

Think different

There are some things you have to reconsider when developing for Bluemix. First of all: separate your design from the data. You got used to have both in the same container (aka NSF) but now you have to drop this. The data is stored in an NSF residing on a Domino server which the Domino NoSQL service is offering. You can access the server with the Notes client, too. Of course you can copy a NSF to it (you cannot create a replica at the moment). You can start with an existing XPages application which you have to "clone". The part that contains the data already (if so) can be used as the data store. Copy this NSF to the Bluemix Domino server and sign it with the Bluemix ID. You won't deal with it later. If you want to create methods to access this data store for yourself (i.e. using the methods that are described on the Bluemix docs at https://www.ng.bluemix.net/docs/services/XPagesNoSQLDatabase/index.html#xpservice_portexisting) you must name the NSF on the server "tododata.nsf" and it must be stored in the folders shown on the service's homepage. If you use my DAO bean you can name it what you like - more on this later in this post.
You also have to remember the classic !! notation for declaring source database servers and paths, e.g. slaney/Bluemix!!yourName/dev/tododata.nsf. As your application will work on different machines you always have to name the server, too. The server's name is currently static, but beware future changes here! Better use the methods that the BluemixContext class offers you. See the documentation above.

Setup the XSP part

When you used an existing application with XPages then you use this a your design container which will be published on the XSP runtime. Publishing this is different from deploying the data part as you can't access a Domino server to copy it there. Instead you have to use the Bluemix plugin in DDE and/or the build service on Bluemix DevOps - more later on this. For the first approach we will use the DDE plugin.
When you setup the XPages application on your local server always use the Bluemix ID to create and edit the design. If you don't want this then please sign the database with that ID before you publish it.
When developing you can of course use the same database to store the data but you are more flexible when you also think of a separate database even locally. You have to modify all of your XPages that access data, i.e. that use view panels or document datasources. Also check your application for data access in pure code such as SSJS and embedded scripts in XPages or Custom Controls. You have to remove the static database access to the code on the documentation (see above) which I call a "switch point". But I really encourage you to use my bean instead which I will explain now.

The DAOBean

For me it was a bit inconvenient to use the code in the documentation. It is simply too much code that I have to put on every XPage that uses data. There are two kinds of computations we need:

  • the database path
  • the whole database as object

The view names are static because these are the same views as before. The DAOBean computes both of the types shown above, has getters for both and you can use the bean notation like

database="#{dao.dbpath}"

See the whole code of the bean here: http://notesx.net:8090/obusse/Bluemix_Bookmarks/blob/master/ODP/Code/Java/com/hp/DaoBean.java
To set it up in your application you have to create an entry in your faces-config.xml that is shown here: http://notesx.net:8090/obusse/Bluemix_Bookmarks/blob/master/ODP/WebContent/WEB-INF/faces-config.xml
As you can see some methods are using a datasource.properties file. You CAN create this file to define the database NSF for your local environment and to define a different NSF name on the Bluemix environment. If you don't use the latter one then your database must be named tododata.nsf. If you define another name here then you can create it on the Bluemix environment with a different name - that's the trick!
You will use this since at least you want to use more than only one datasource for another XSP runtime. 

Publishing strategies

Your first approach should be using the DDE plugin. It will ask you to setup the deployment options at first run. This wizard will simply create the manifest.yml file for you. Please review it afterwards by opening the new entry in the application navigator.

Here you can modify or setup the name of the NSF file that resides on the Domino server in Bluemix. Please also define the bound service for Domino NoSQL in the services section:

After you modified all XPages to access the datasource via the DAOBean (or the default methods) you can publish it to your XSP runtime. Click the Bluemix icon in the DDE toolbar and choose "Deploy Application". The plugin will create a copy of the NSF in the folder you defined in the setp before. Right after that it contacts the service and uploads the droplet. If you experience timeouts then set the timeout amount from 180 to 300 in the DDE Bluemix preferences page (don't change the timeout value in the manifest settings - this will result in an error). If this also fails then you should use the CF tool to push it to Bluemix which brings the benefit of showing a log output. You can cancel the wizard when you see something like "Connecting to Cloudspace" as the copy of the NSF is already created.

Using the CF tool

If you haven't installed the CF tool then please do it now. You can download it here: https://github.com/cloudfoundry/cli/releases You can find a documentation here: https://www.ng.bluemix.net/docs/cli/cli.html
This is by far the most preferably way to upload your stuff as you will be presented with a log output and you can see what's going on during the deployment which may take some time (in my case with a 8MB NSF up to 6 minutes!). You can see the creation of the containers (cloud foundry) and setup of the droplet (your NSF with the whole Domino environment). We will only use 3 different commands.
Open a command line and navigate to the directory in which the prepared deployment, which the Bluemix plugin created, resides. Set the endpoint to the API: 

cf api https://api.ng.bluemix.net

Then login with the credentials:

cf login -u yourUserName

Enter your Bluemix password, not the one from the Notes ID.

Then push the application to Bluemix with

cf push yourAppName

and watch the numerous outputs that will be created. At the end you should see green letters that say "App started"
Now you can test the application under the URL of your Bluemix app.

You can find my first app here: http://nxbookmarks.eu-gb.mybluemix.net/

And a second playground here: http://greets.eu-gb.mybluemix.net

Some limitations

I found out that some of the Extlib components cannot be used with the dynamic data binding via the bean as they simply don't have a database property to set up a different NSF name, i.e. the Tagcloud control. I created an issue for it here: https://github.com/OpenNTF/XPagesExtensionLibrary/issues/29

You also cannot create replicas or cross certify your cert ID to the Bluemix server to setup scheduled replication from an on-premise Domino server. User management is also a problem as you only can setup new web users to access your apps but there might be a chance to couple your LDAP directories or setting up additonal NABs with Directory Access.

Also check your application for login mechanisms: you cannot authenticate against the names.nsf e.g. when using custom login forms in your application that post data against the /names.nsf?login URL. Please use the basic login function with a URL like myDatabase.nsf?login.

Happy coding! Grinsend

 





Latest comments to this post

Oliver Busse wrote on 14.03.2016, 16:48

@Patrick: you can use it just like you did but make sure you set up the properties file corresponding to your local path and the db name on bluemix. See my sample.

 Link to this comment
Patrick Kwinten wrote on 14.03.2016, 16:46

I notice dao.getDatabase() returns bluemix\patrick_kwinten_gmail_com\dev\tododata_1.nsf 

 

and bluemixContext.isRunningOnBluemix()? bluemixContext.getDataService().atDbName():@DbName return  5.10.125.34,bluemix/patrick_kwinten_gmail_com/dev/tododata_1.nsf

 

so my @DbColumn(dao.getDatabase(), 'MissionLookup', 4) was failing

 

How usefull is the daobean for @formula's on bluemix or have i just been using it wrong?

 

 

 Link to this comment
Scott Rigby wrote on 13.11.2015, 06:44

Hi Oliver,

"Also check your application for login mechanisms: you cannot authenticate against the names.nsf e.g. when using custom login forms in your application that post data against the /names.nsf?login URL. Please use the basic login function with a URL like myDatabase.nsf?login"

If I try this then I get the bluemix xpages login page but it give me a :You are not authorized to access database.nsf" error.

I have given default no access as I want to force a login.

Any idea what I am doing wrong?

 

Regards,  Scott

 Link to this comment
Patrick Kwinten wrote on 19.10.2015, 16:24

"Of course the DAO class incl. the package must be set up correctly in the faces-config.xml 

I think have made the correct setup.

"why would you want to use the bean object in your own class?"

The methods how to load which documents from which views are defined in my own classes. The reference to which database the data resides was defined as followed:

NotesContext nct = NotesContext.getCurrent();
Database db = nct.getCurrentDatabase();

I want to switch that into:

Database db = dao.getDatabase();

BTW I am version 13 of ExtLib, from what I read in this popst that should not be a problem.

 

 Link to this comment
Oliver Busse wrote on 19.10.2015, 16:06

Of course the DAO class incl. the package must be set up correctly in the faces-config.xml (it reads as they are different). 

But: why would you want to use the bean object in your own class? Dou you get it via the variable resolver?

 Link to this comment
Patrick Kwinten wrote on 19.10.2015, 16:02

Hi Olivier,

 

I have a question regarding the implementation of the DaoBean in an application.

. I created the DaoBean class (same package as other classes)

- I registered it as a managed bean (same settings as in your example)

- I created a private object in another class (private DaoBean doa )

- In the next step it goes wrong:

 

Database db = dao.getDatabase();

I get the following error:

[0F58:000C-0F78] 2015-10-19 15:57:54   HTTP JVM: com.ibm.xsp.webapp.FacesServlet$ExtendedServletException: com.ibm.xsp.exception.EvaluationExceptionEx: Error while executing JavaScript computed expression

 

 

Do you have any idea what I am doing wrong?

 Link to this comment
Patrick Kwinten wrote on 01.09.2015, 10:08

Interesting stuff! Thank you for sharing.

 Link to this comment

Leave a comment right here