Bonita Engine API on the server

Hi everyone,

I wanted to know if anyone has dealt with Bonita engine API on the server. I have a process that works on localhost, but when I transfer it to the server it seems like the process is not passing variables that are used with Bonita engine API - apiAccessor.identityAPI to be exact. I saw somewhere in the documentation that there might be a file that needs to be re-configured from localhost to server address for the engine API once the application is on a server. Would anyone be able to help with this? Thanks in advance.

To be more specific:

I am using it in a connector out from my human task with groovy script (for more detail) and my script is sending a request using HTTP to another server which is not a bonita server. The variables I'm trying to pass in the message are my tokenValue & authenticationUsername.

I will paste the lines of code. This request works when I run the process locally talking to the external server, however, when I transfer this process to a Bonita portal on my test server trying to communicate to the external server - the tokenValue & authenticationUsername are transferred in the message as null.

Hello,

it's more simple than that. The Bonita Engine API is available everywhere (in Connector, Operation, REST API, Variables initialization) !

 but when I transfer it to the server it seems like the process is not passing variables that are used with Bonita engine API

I don't understand that sentence. What do you mean by "passing variables" ?

Where do you want to access this API?

* from a connector?

* from a REST API?

* From an external software, a client to communicate to a server?

In all this function, you have an "apiAccessor", then you can call (in a connector for example)

"IdentityAPI identityAPI = apiAccessor.getIndentityApi()" 

So you don't need to "pass a variable", just use the apiAccessor to get it.

Waiting your feedback,

Best,

 

Hello, 

I'm completely lost now.

So, if I resume:

You have a Bonita Server.

You have an external application, not running inside a Bonita server. A complete external application. Correct?

So, in your EXTERNAL application, you have this

map.put("server.url", "http://MyServerILove:PortNumberofTheBonitaApplicationOnMyServer");

If the process is deplyed on a Bonita server wouldn't that line have to be the server address and not localhost? (Correct)

// Set the username and password
final String username = "William.Jobs";
final String password = "bpm";
// get the LoginAPI using the TenantAPIAccessor
final LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
// log in to the tenant to create a session
final APISession session = loginAPI.login(username, password);

Then you get your IdentityAPI by

   final IdentityAPI identityAPI = TenantAPIAccessor.getIdentityAPI(session);

or a processAPI by

   final ProcessAPI processAPI = TenantAPIAccessor.getProcessAPI(session);

 

That when you say

def user = apiAccessor.identityAPI.getUser(taskAssigneeId);
==> Where the apiAccessor come from? You must have a compilation error.

or " if anyone has dealt with Bonita engine API on the server" : in fact, you are not "on the server", you are "outside the server", in an external Application, isn't it?

 

Please precise if you try to communicate with the Bonita Server OUTSIDE the Bonita server in an external application, or INSIDE the Bonita Server, in a process operation, a connector, a rest api, a custom page...

Thanks

 


 

Ok, there is nothing on the server side.

Now, could you send the CLIENT side ? 

} catch(Exception e ) {


StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionDetails = sw.toString();

logger.severe("Call Bonita "+e.getMessage()+" at "+exceptionDetails);

}

==> This part generate should generate an error, and it can't be a HTTP 500 because here, you don't use HTTP, but JAVA. So, you should have an Exception.

On which time zone are you? I can arrange a Meet then you can share your screen. Faster to figure out in 10 mn what's happen then doing a lot of text, isn't? I'm in PST (Califonia, USA).

Best,

Hi,

yes, I am using it in a connector out from my human task with groovy script (for more detail) and my script is sending a request using HTTP to another server. The variables I'm trying to pass in the message are my tokenValue & authenticationUsername.

I will paste the lines of code. This request works when I run the process locally talking to the external server, however, when I transfer this process to a Bonita portal on my test server trying to communicate to the external server - the tokenValue & authenticationUsername are transferred in the message as null.

---------------

def user = apiAccessor.identityAPI.getUser(taskAssigneeId);
def maxIndex = apiAccessor.identityAPI.getNumberOfCustomInfoDefinitions().toInteger();
def userCustomInfoList = apiAccessor.identityAPI.getCustomUserInfo(taskAssigneeId, 0.toInteger(), maxIndex);

def authenticationUsername = "";
def tokenValue = "";


def i=0;
while(i<maxIndex){
    def customInfo = userCustomInfoList.get(i);
    if(customInfo.getDefinition().getName().equals("authenticationUsername")){
        authenticationUsername = customInfo.getValue();
    }
    if(customInfo.getDefinition().getName().equals("tokenValue")){
        tokenValue = customInfo.getValue();
    }
    i++;
}

Hello,

Ok get it.

1/ in your code you share, you don't communicate with an another server, but with the local server. So, I assume you a) connect to an external Bonita server using 

   final Map<String, String> map = new HashMap<String, String>();
            map.put("server.url", "http://localhost:8080");
            map.put("application.name", "bonita");
            APITypeManager.setAPITypeAndParams(ApiAccessType.HTTP, map);

            // Set the username and password
            final String username = "William.Jobs";
            final String password = "bpm";
            // get the LoginAPI using the TenantAPIAccessor
            final LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
            // log in to the tenant to create a session
            final APISession session = loginAPI.login(username, password);
       

b) then your code?

 

2/ I'm very surprise that your studio can talk with an another Bonita server via the API. This is not possible normally. When you call

            APITypeManager.setAPITypeAndParams(ApiAccessType.HTTP, map);

you overwrite some static variable, then you lost the connection to your LOCAL server.

If you want to communicate between 2 servers, the only way is to use the REST CALL from JAVA. And this is not easy. If you arrive to do that, don't hesitate to share it!

 

 

Copy paste messed up the code. here it is:

def user = apiAccessor.identityAPI.getUser(taskAssigneeId);
def maxIndex = apiAccessor.identityAPI.getNumberOfCustomInfoDefinitions().toInteger();
def userCustomInfoList = apiAccessor.identityAPI.getCustomUserInfo(taskAssigneeId, 0.toInteger(), maxIndex);

def authenticationUsername = "";
def tokenValue = "";

def i=0;
while(i<maxIndex){
    def customInfo = userCustomInfoList.get(i);
    if(customInfo.getDefinition().getName().equals("authenticationUsername")){
        authenticationUsername = customInfo.getValue();
    }
    if(customInfo.getDefinition().getName().equals("tokenValue")){
        tokenValue = customInfo.getValue();
    }
    i++;
}

Yes, but 

def user = apiAccessor.identityAPI.getUser(taskAssigneeId);
 

==> You communicate with the LOCAL Bonita server, not an EXTERNAL bonita server doing that.

If you communicate to an EXTERNAL Bonita server, you must first CONNECT to this external server.

Or I miss something?

map.put("server.url", "http://localhost:8080");

If the process is deplyed on a Bonita server wouldn't that line have to be the server address and not localhost?

// Set the username and password
final String username = "William.Jobs";
final String password = "bpm";
// get the LoginAPI using the TenantAPIAccessor
final LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
// log in to the tenant to create a session
final APISession session = loginAPI.login(username, password);

what if each user has a different password?

I'm very surprise that your studio can talk with an another Bonita server via the API.

I think you didn't understand. I have a Bonita server/instance to which I'm deploying my local process to, then I'm communicating with a clients software to request information (which is not a bonita server). That connection is established before this task. Hope that helps understanding it more.

I really appreciate your help.

I tried your method, and it didn't work, unfortunately. Any other suggestions by chance? Thanks in advance.

Hello,

Could you send the log on your client side? During the operation, you must have at one moment a exception. Then log it, and provide it please

provide the pom.xml too (best is: create a simple project on github and share it).

Do something like

Logger logger = Logger.getLogger("mylog");

try 

{

// Set the username and password
final String username = "William.Jobs";
final String password = "bpm";
// get the LoginAPI using the TenantAPIAccessor
final LoginAPI loginAPI = TenantAPIAccessor.getLoginAPI();
// log in to the tenant to create a session
final APISession session = loginAPI.login(username, password);

...

} catch(Exception e ) {


StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionDetails = sw.toString();

logger.severe("Call Bonita "+e.getMessage()+" at "+exceptionDetails);

}

I did check the logs and this is the error I get : 

org.bonitasoft.console.common.server.login.credentials.LoginDatastore Error while logging in the engine API.

Now, when I also test bpm API from postman for my process I get this exception as well:

class org.bonitasoft.web.rest.server.framework.exception.APIMissingIdException

 

Let me know if that makes sense,I will try your method as well.

Hello,

I don't have enough information. Waiting the log from the JAVA code I sent you.

org.bonitasoft.console.common.server.login.credentials.LoginDatastore Error while logging in the engine API.

==> Please send the complete log

Now, when I also test bpm API from postman for my process I get this exception as well:

class org.bonitasoft.web.rest.server.framework.exception.APIMissingIdException

==> You should have a REST Code (400 ? 404 ? 500 ?)

THen on the Bonita log, you should have more information (tomcat/server/logs)

 

https://github.com/avitalv95/BonitaLogs

I've added the log file after adding these lines of code + added the pom.xml 

Let me know if that works for you.

In regards to the REST code, it is a 500 Internal Server Error.

To be exact I have a Bonita BPM instance installed on Ubuntu. Which is where I deploy all my processes to. My Bonita process is communicating with external software on a different server to request & receive HTTP messages which include information in JSON format. The EXTERNAL software on a different server is just expecting messages coming from my Bonita process. That process is working fine when I run the process locally from my Bonita Studio. My issue is that it's failing on the line of code that I sent once I install the process on the BONITA Ubuntu server as these variables are passed to the EXTERNAL software as null.

map.put("server.url", "http://MyServerILove:PortNumberofTheBonitaApplicationOnMyServer");

this line of code is in my bonita process in the same human task -> connector out groovy script where I sent my code from.

Where the apiAccessor come from? You must have a compilation error.

https://documentation.bonitasoft.com/javadoc/api/7.0/org/bonitasoft/engine/api/APIAccessor.html

keep in mind that I have community edition. And this apiAccessor works fine for it, since it works on my locally installed Community Edition Bonita Studio.

in fact, you are not "on the server", you are "outside the server", in an external Application, isn't it?

Please precise if you try to communicate with the Bonita Server OUTSIDE the Bonita server in an external application, or INSIDE the Bonita Server, in a process operation, a connector, a rest api, a custom page...

Hope the top portion clarifies this question as well.

Important to understand the EXTERNAL software / application has nothing to do with bonita. It is simply expecting a request to send out proper information in JSON format, that's all. The IdentityAPI I'm trying to get is from the current Bonita process installed on the ubuntu server.

Let me know if you are still having trouble to understand. Thanks in advance.

Hello.

It seem there is two issues in your answer

My issue is that it's failing on the line of code that I sent once I install the process on the BONITA Ubuntu server as these variables are passed to the EXTERNAL software as null

How do you pass the variables to the EXTERNAL software? You use a REST CONNECTOR ? 

this line of code is in my bonita process in the same human task -> connector out groovy script where I sent my code from.

So, here you are IN THE BONITA SERVER, not in an EXTERNAL SOFTWARE. In a Connector Groovy, you have an apiAccessor available. Just use "

IdentityAPI identityAPI = apiAccessor.getIdentityAPI()

DO NOT USE the Login, DO NOT USE 

map.put("server.url", "http://MyServerILove:PortNumberofTheBonitaApplicationOnMyServer");

 

To resume:

When the code is IN the BONITA SERVER (in a Groovy connector, an operation....) you have a apiAccessor variable.

When the code is OUT the BONITA SERVER, then you must first connect, and get an apiAccessor by the way I gave you.

Important to understand the EXTERNAL software / application has nothing to do with bonita. It is simply expecting a request to send out proper information in JSON format, that's all. The IdentityAPI I'm trying to get is from the current Bonita process installed on the ubuntu server.

=> OK, so here the "map.put("server".... At one moment, you must face an exception. When? At the login time? On the getIndentityAPI ? When you use the identityAPI object?

If the login failed, check that the API is "open". See here and check the "Server configuration".

https://documentation.bonitasoft.com/bonita/7.11/configure-client-of-bonita-bpm-engine

By default, it's open on the Studio. May be the server is close by default now?

 

Why it's working in the studio, not in the server?

That's very strange, I never face this kind of issue. A studio run a Bonita Server, same architecture.

 

I attached the exception that I'm getting to the other message.

The server is set up to accept HTTP connections so it should work.

Sorry for getting back to you just now. I appreciate your help a lot. I was able to figure it out, I split up my process into small sub-processes and connected them and it magically worked. Thanks again.