Java Open Client communication with OpenEdge Application Ser

Posted by Dshebeko on 23-Dec-2014 08:00

Hi everyone!:)

I've tried to find out how Java Open Client interacts with OpenEdge AppServer and eventually joined your community.
The problem is I'm not sure whether my Java program works in correct way.
I mean I have some doubts in piece of code which is responsible for Java-OpenEdge communication.


I have OpenEdge Application Server running on State-free mode.
My java client is just a SOAP web-service web-application, which is deployed on Tomcat.
SOAP web-service server receives HTTP requests from external systems and fires progress procedure call on OpenEdge AppServer using AppObject, generated by ProxyGen Tool. I need to call the only progress non-persistent procedure named i-uek-all.p, so my proxy AppObject class (which in turn is called OpenEdgeProxy) also has just one method: iUekAll.


Here is Java service class, which makes requests to OpenEdge Application Server:



OpenEdgeServiceImpl.java

package ru.bis.integration.uek.service;

import org.apache.log4j.Logger;

import com.progress.open4gl.Open4GLException;
import com.progress.open4gl.RunTimeProperties;
import com.progress.open4gl.StringHolder;
import com.progress.open4gl.dynamicapi.Session;
import com.progress.open4gl.javaproxy.Connection;

import static ru.bis.integration.uek.util.UekConstants.*;
import ru.bis.integration.uek.proxy.OpenEdgeProxy;
import ru.bis.integration.uek.service.exception.NotConnectedException;
import ru.bis.integration.uek.service.exception.OpenEdgeCommunicationException;

/**
 * 
 * @author shds
 *
 */
public class OpenEdgeServiceImpl implements OpenEdgeService {
    private String url;
    private String userId;
    private String password;
    private String ifilial;
    private String appServerInfo;
    private OpenEdgeProxy proxy;
    private Connection conn;
    private static final Logger logger = Logger.getLogger(OpenEdgeServiceImpl.class);

    public OpenEdgeServiceImpl(String url, String userId, String password, String ifilial, String appServerInfo) {
        this.url = url;
        this.userId = userId;
        this.password = password;
        this.ifilial = ifilial;
        this.appServerInfo = appServerInfo;
        RunTimeProperties.setSessionModel(1);
        RunTimeProperties.setInitialConnections(10);
        logger.info("Session-free connection mode is used");
        try {
            conn = new Connection(url, userId, password, appServerInfo);
            proxy = new OpenEdgeProxy(conn);
            logger.info("Initial connection pool size set to " + conn.getSessionPool().size());
        } catch (Exception e) {
            logger.error(CONNECTION_ERROR_MESSAGE + LINE_SEPARATOR + e.getMessage());
            return;
        }
        logger.info(CONNECTION_ESTABLISHED);
    }

    @Override
    public String sendMessage(String message) throws OpenEdgeCommunicationException, NotConnectedException {
        if (proxy == null) {
            initProxy();
        }
        StringHolder response = new StringHolder();
        try {
            proxy.iUekAll(userId, password, ifilial, message, response);
            logger.info("RequestID:" + proxy._getRequestId());
        } catch (Exception e) {
            logger.error(COMMUNICATION_ERROR_MESSAGE + LINE_SEPARATOR + e + e.getMessage());
            throw new OpenEdgeCommunicationException(COMMUNICATION_ERROR_MESSAGE);
        }
        return response.getStringValue();
    }

    private void initProxy() throws NotConnectedException {
        try {
            proxy = new OpenEdgeProxy(conn);
        } catch (Exception e) {
            logger.error(CONNECTION_ERROR_MESSAGE + LINE_SEPARATOR + e);
            throw new NotConnectedException(CONNECTION_ERROR_MESSAGE);
        }
    }

    public void close() {
        try {
            proxy._cancelAllRequests();
            conn.releaseConnection();
            logger.info("Connections closed");
        } catch (Open4GLException e) {
            logger.error(e.getMessage());
        }
    }
}

OpenEdgeServiceImpl class is just Spring bean with singleton scope.
Both the constructor and close() methods are called once on Tomcat startup and shutdown events.
sendMessage(String message) method is called every time SOAP request comes to web-service. Thus, given multithreading nature of Tomcat, every request is running on separate thread, so each thread uses the same code from sendMessage(String message) method and the same proxy object.
When I give my program load testing, I notice that session pool is rapidly growing up which leads to increasing number of connections. But the session pool size is limited to 25, so no more than 25 connections gets established.

I need to find scalable decision that provides tolerance to high loadings.
I thought that Session-free mode is silver bullet, that allows for using as many as needed OpenEdge broker agents as the number of requests is growing up.
After all, given all previous facts I just like to know is this Java code correct??

Thanks in advance.

Dmitry Shebeko,

Banking Information Systems (http://www.bis.ru/eng/)

All Replies

Posted by Irfan on 23-Dec-2014 08:22

Hi Dshebeko,

When you mentioned the sessionpoolsize, where does it imply. Does it imply at the webserver(tomcat) or at the appserver broker.

As you are doing load testing on the OpenEdge Application server, I would like to know if you have applied the below setting at the OpenEdge Appservers to make sure maximum number of requests are been processed by it.

1. In tomcat(make sure that you  maxthreads >= number of threads you are running at your Java client)

2. Check for the below properties for the number of agents

initialSrvrInstance( The number of agents that you want to start as soon as you start your appserver broker)

maxSrvrInstance( maximum number of agents you want to have for a broker when you scale)

  In-addtion to that, the  property "maxClientInstance"  will tell you how many concurrent clients a broker could handle. By default this property is 512, so you need to think about if you client connections are more than that.

These settings are expected to configured before performing load testing. Let me know if you have any questions.

Posted by Dshebeko on 23-Dec-2014 08:45

Thanks for quick answer:) What about java code?)

Setting up RunTimeProperties.setInitialConnections(10) results in establishing 10 connections between Java client and OpenEdge AppServer after instantiating AppObject (in my case OpenEdgeProxy) class.  So conn.getSessionPool().size() returns 10; Obviously, both sides (java client and appserver) are implied cause every connection implies at least two sides.

1. Actually Tomcat is running threads according to Java Servlet API specification, I can't manage this, think it's is running at most 20 threads concurrently. Each such a thread calls sendMessage().

2. I set up initialSrvrInstance to 2, maxSrvrInstance to 35

Although I didn't change default maxClientInstance value, max number of client connections is 25. I see it in AppServer status after testing. Number of my client connections is limited when I run both java client and app server in State-free mode. It exactly equals to sessionPoolSize (25)

Dmitry Shebeko,

Banking Information Systems (http://www.bis.ru/eng/)

Posted by Irfan on 23-Dec-2014 09:28

In-order to set maximum number of connections and threads in tomcat, you can set the property maxThreads and maxConnections in server.xml file.

Did you see any errors in your client that the remaining client requests got failed. We might need to understand where the limit is set to connect the maximum requests.

When I need to run JavaOpenClient concurrently, I generally create a runnable interface.

Posted by Dshebeko on 29-Dec-2014 04:09

I spent some time on Java client's behaviour observation. I still cannot understand why the number  of agents that work on OpenEdge server equals to initialSrvrInstance, no more than that parameter value. Even if  number of requests grows up, no more than <initialSrvrInstance> agents gets involved in processing incoming requests, despite the increasing size of broker queue size. It's all about State-free operating mode.

Dmitry Shebeko,

Banking Information Systems (http://www.bis.ru/eng/)

This thread is closed