Tag Archives: JBoss

How to Get and Update Process Variable in jBPM 6 via REST API – Part 1

The GET part is fairly simple, you just need to form a URL with the right values.

So assuming you have a BPM process running on a remote server (business-central) and you would like to get/read the Process Variables, lets see how.

JBPM has published REST APIs to interact with it and get mostĀ of the information.

For our case, the REST URL to get the process variable information has this pattern:

/runtime/{deploymentId}/process/instance/{procInstanceID}/variable/{varId}

It’s HTTP GET which returns the variable from a given process instance.

A complete URL may look like below:

http://localhost:8080/business-central/rest/runtime/com.prashantp.demo:bpm-sample:0.1.0/process/instance/4545/variable/person

The above would return the XML value of the variable (person), so if you had a POJO then this can be thought of as the XML version of the same. (JAXB at play).

Writing code to fetch the information can be in plain Java without any BPM libraries, after all its just a REST API which returns XML, the only complexity could be about BASIC AUTH.

Here’s a sample code for retrieving the variable value.


import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.logging.Logger;

import org.apache.commons.codec.binary.Base64;

/**
 * A general Helper class that once configured would return the XML value of a given Variable
 * under a process instance.
 *
 * Sample URL used for REST API of JBPM 6:
 * http://localhost:8080/business-central/rest/runtime
 * /com.infibeam.sapphire:bpm-order-activation:0.3.9
 * /process/instance/4545
 * /variable/person
 *
 * @author prashantp.org
 *
 */
public class BPMGetVariable {
	private Logger logger = Logger.getLogger(BPMGetVariable.class.getName());

	private String variableName;
	private String bpmUrl;
	private String username;
	private String password;

	public BPMGetVariable(long processId, String variableName, String bpmUrl,
			String username, String password, String deploymentId) {
		this.variableName = variableName;
		this.bpmUrl = bpmUrl + deploymentId + "/process/instance/" + processId + "/variable/" + variableName;
		this.username = username;
		this.password = password;
	}

	public static void main(String[] args) throws Exception {
		long processId = 4545;
		String variableName = "person";
		String name = "bpmsAdmin";
		String password = "bpmspasswordhere";
		String deploymentId = "com.prashantp.demo:bpm-sample:0.1.0";

		BPMGetVariable bpmGetVariable = BPMGetVariable.builder()
				.bpmUrl("http://localhost:38080/business-central")
				.credentials(name, password).addDeploymentId(deploymentId)
				.processId(processId).variableName(variableName).build();
		//Save as XML
		Files.write(Paths.get("./" + processId + "_" + variableName + ".xml"),
				bpmGetVariable.getValue().getBytes());
	}

	public String getValue()
			throws MalformedURLException, IOException {

		String variableValue = getFromSecureRESTUrl(bpmUrl, username, password);
		logger.info("Variable Name=" + variableName + ", value=" + variableValue);

		return variableValue;
	}

	private String getFromSecureRESTUrl(String webpageUrl, String username,
			String password) throws MalformedURLException, IOException {
		logger.info(webpageUrl);
		URL url = new URL(webpageUrl);
		URLConnection urlConnection = url.openConnection();
		setSecurityCredentials(urlConnection, username, password);
		return readResponse(urlConnection);
	}

	private void setSecurityCredentials(URLConnection toSecure,
			String username, String password) {
		String authString = username + ":" + password;
		byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());

		toSecure.setRequestProperty("Authorization", "Basic "
				+ new String(authEncBytes));
	}

	private String readResponse(URLConnection urlConnection) throws IOException {
		InputStream is = urlConnection.getInputStream();
		InputStreamReader isr = new InputStreamReader(is);

		int numCharsRead;
		char[] charArray = new char[1024];
		StringBuffer sb = new StringBuffer();
		while ((numCharsRead = isr.read(charArray)) > 0) {
			sb.append(charArray, 0, numCharsRead);
		}
		return sb.toString();
	}

	public static BPMGetVariableBuilder builder() {
		return new BPMGetVariableBuilder();
	}

	static class BPMGetVariableBuilder {
		private long processId;
		private String variableName;
		private String bpmUrl;
		private String username;
		private String password;
		private String deploymentId;

		public BPMGetVariableBuilder processId(long processId) {
			this.processId = processId;
			return this;
		}

		public BPMGetVariableBuilder variableName(String variableName) {
			this.variableName = variableName;
			return this;
		}

		public BPMGetVariableBuilder bpmUrl(String bpmUrl) {
			this.bpmUrl = bpmUrl;
			if (this.bpmUrl.endsWith("/")) {
				this.bpmUrl = this.bpmUrl + "rest/runtime/";
			} else {
				this.bpmUrl = this.bpmUrl + "/rest/runtime/";
			}
			return this;
		}

		public BPMGetVariableBuilder credentials(String name, String password) {
			this.username = name;
			this.password = password;
			return this;
		}

		public BPMGetVariableBuilder addDeploymentId(String deploymentId) {
			this.deploymentId = deploymentId;
			return this;
		}

		public BPMGetVariable build() {
			if (processId == 0 || Objects.isNull(variableName)
					|| Objects.isNull(bpmUrl) || Objects.isNull(username)
					|| Objects.isNull(password) || Objects.isNull(deploymentId)) {
				throw new IllegalStateException();
			}
			return new BPMGetVariable(processId,variableName,bpmUrl,username,password,deploymentId);
		}

	}

}

Now that we have done the GET part how about updating the same Process Variable via the REST API, lets see how.

That’s coming in Part 2 soon.

 

Advertisements

Jboss 5.1 and Seam 2 Redeployment issue workaround

When trying to work with Seam 2.2 applications in JBoss 5.1 you might have come across a very annoying redeploy cycle of your application. I will document the issue and workaround here.
Beginning with Seam 2.2 and JBoss 5.1 is pretty straight forward. But you could soon run into issues if you don’t pay attention to the details.

The Journey

  1. I had decided to give Seam a try after having dig into some seam docs. The first thing was to try out the examples that come bundled with seam.
  2. Seam is pretty easy to start off with. You just need to get a copy of JBoss 5.1 and Seam 2.2 (the latest during this post). Then as mentioned in the Running Seam in Jboss Just do the below two steps:
    1. Edit build.properties in your Seam directory and configure the jboss.home property to be your JBoss AS installation directory.
    2. In the jboss-seam/examples/booking directory, type ant deploy. (Here booking is one example you can do it with any other)
  3. ant deploy command will generate the (War/Ear/Ejb) artifacts and dump it into the deploy folder of JBoss AS.
  4. If JBoss is running you should see the console output showing the deployment taking place.
  5. Just point your browser to the deployed apps URL and voila.

When you start building your own application using either the seam commands or Jboss Tools plugin for Eclipse, you will notice quite a few artifacts getting generated (Not all are needed).

When you deploy your project and find that none of the @Name annotated classes are getting found. Check for seam.properties file this must be in your classpath. It’s an empty file but acts like a marker which triggers the scanning of your seam components. Without that file you will need to register each component in your components.xml file.

This should solve your problem, but under JBoss 5.1 you might run into another issue of constant undeploy/deploy of your project without any details as to why in the logs. If you look in the Seam documentation WhatHappensWhenYouDeploySeamAppInJBoss5 and couple of other JBoss JIRA pages you will find that mostly this happens due to IDE generated files getting placed under WEB-INF check for these and delete them. The files get generated when you open the pages.xml or web.xml kind of files in Visual Editor.

Even after following the simple & complex advice the problem sometimes just won’t go. What i noticed was that the presence of seam.properties file under WEB-INF/classes will also trigger the dreadful redeployment of your application. If you look in the seam reference docs for possible locations of seam.properties, you will find that it needs to be in your classes/ root or META-INF directory of a JAR. So an easier solutions is to just “move the seam.properties from WEB-INF/classes to WEB-INF/classes/META-INF” and voila the problem should be solved without any fancy modification to your JBoss AS.

I hope this helps you to get on with building your Seam applications.