question

Upvotes
Accepted
1 1 1 1

Create "AuthorizationAgent" returns "AuthorizationConnection.CONNECTION_DOWN" state

Hi, I am writing some DACS API tests by following the java examples. Each test case creates a daemon connection, does something, then close the connection. All tests pass if I run them manually. But only the first test works if I run them together in a group. I did a lot debugging and found starting from the second test case, the agent.daemonConnectionState() is always "CONNECTION_DOWN" immediately after calling "createAuthorizationAgent". So the while loop checking for State "CONNECTION_PENDING" never gets executed. I feel like I might miss something when closing the daemonConnection of the first test case so the second tests (and others) never work. Interestingly, if I add a delay, then State will become "CONNECTION_PENDING". But we don't think this is a proper fix. Here is the snippet from my second test case. Thanks

// Create AuthorizationAgent
authorizationAgent = authorizationSystem.createAuthorizationAgent(_authorizationAgentName,true);

//The following line print the State is equal to "CONNECTION_DOWN"
//logger.info("Demon connection state is " + authorizationAgent.daemonConnectionState().toString());

//Thread.sleep(50) --> however if this delay is enabled, then the following State would work
while (authorizationAgent.daemonConnectionState() != AuthorizationConnection.CONNECTION_PENDING) {
    try {

        if (authorizationAgent.daemonConnectionState() == AuthorizationConnection.CONNECTION_UP) {
            logger.info("Demon connection state is UP: " + authorizationAgent.daemonConnectionState().toString() );
        }
        else if (authorizationAgent.daemonConnectionState() == AuthorizationConnection.CONNECTION_DOWN) {
            logger.info("Demon connection state is DOWN: " + authorizationAgent.daemonConnectionState().toString());
        }
        else if (authorizationAgent.daemonConnectionState() == AuthorizationConnection.CONNECTION_PENDING) {
            logger.info("Demon connection state is CONNECTION_PENDING: "  + authorizationAgent.daemonConnectionState().toString());
        }
        else {
            logger.info("Demon connection state is UNKNOWN: " + authorizationAgent.daemonConnectionState().toString());
        }
        Thread.sleep(1);
    }
javaDACSopen-dacs
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Monitored by @Wasin Waeosri

@tsun

Hi,

As your query is related to Open DACS, TREP APIs was not the right forum. I moved it to this Open DACS group.

Kind regards,
AHS

@tsun

Thank you for your participation in the forum.

Are any of the replies below satisfactory in resolving your query?

If yes please click the 'Accept' text next to the most appropriate reply. This will guide all community members who have a similar question.

Otherwise please post again offering further insight into your question.

Thanks,

AHS

@tsun

Please be informed that a reply has been verified as correct in answering the question, and has been marked as such.

Thanks,

AHS

Upvotes
Accepted
32.2k 40 11 20

Hello @tsun,

You should be able to reconnect when it's broken, just not repeatedly and unlimited number of times. When the connection is up, you should be able to issue requests. To test this capability, you can use the subscription test example from SDK, modifying it like so (just for the capability test):

    for(int i = 0; i < 10; i++) { //tight loop 
    	DacsSubscribeClient client = null;
    	try {
      		client = new DacsSubscribeClient(daemonHost, serviceName, name, position, application, usage,  reqtype);
		client.openDaemonConnection("DACS", "dacsSubscribeClient", true);
		 client.login();
      		// Wait for processing event queue dispatching.
      		client.waitForCallBackEvent(waitTime);
 		client.checkSubscribePermission(itemName, peList, enableOndemand);
 		// Again, wait for processing event queue dispatching.
		client.waitForCallBackEvent(waitTime);
      		client.logout();
	}  catch (Exception ex) {
   		// Other unexpected exception occurs.
      		System.err.print("DacsSubscribeClient failed ");
        	if (ex.getMessage() != null && ex.getMessage().trim().length() != 0) {
       		System.err.print(ex.getMessage());      	}
      System.out.println();
    	}  finally {
      		if (client != null) {
        	client.closeDaemonConnection(true);
      	}
    }

The result you should get is that you will be able to reconnect when DACS is ready, not in a tight loop, similar to mine:

Output:
[host:port] Daemon connection state is UP
[] Daemon connection opened
[] radmin logged in
[] Subscriber has been logged in
[] radmin allowed subscription access to item IBM.N
[] radmin logged out
[] Daemon connection closed
[] Daemon connection state is DOWN
[] Daemon connection closed
[] Daemon connection state is UP
[] Daemon connection opened
[] radmin logged in
[] Subscriber has been logged in
[] radmin allowed subscription access to item IBM.N
[] radmin logged out
[] Daemon connection closed
[] Daemon connection state is DOWN
[] Daemon connection closed
[] Acquire AuthorizationSystem failed
[] Daemon connection state is DOWN
[] Daemon connection closed
[] Daemon connection state is DOWN
[] Daemon connection closed
[] Daemon connection state is DOWN
[] Daemon connection closed
[] Daemon connection state is UP
[] Daemon connection opened
[] radmin logged in
[] Subscriber has been logged in
[] radmin allowed subscription access to item IBM.N
[] radmin logged out
[] Daemon connection closed

Please note, we do not recommend reconnecting repeatedly without the need, this modification can be is for the development and test phase, the way to verify the reconnect working.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
32.2k 40 11 20

Hello @tsun,

You should be able to create connection to daemon, issue request, tear it down, then repeat. There can not be unlimited number of those connections, still there should be more then one permitted by DACs to complete before they start to fail.

I am just wondering, instead, can you issue the requests without creating and destroying the connection? That would be more efficient, I modified the Java subscribe example from the toolkit to make repeated checkSubscribePermission() calls:

client.login();
   for(int i = 0; i < 1000; i++) {
      // Wait for processing event queue dispatching.
      client.waitForCallBackEvent(waitTime);
      client.checkSubscribePermission(itemName, peList, enableOndemand);
      // Again, wait for processing event queue dispatching.
      client.waitForCallBackEvent(waitTime);
   }
      client.logout();

it resulted in positive responses

...
allowed subscription access to item IBM.N
allowed subscription access to item IBM.N
allowed subscription access to item IBM.N
...

Calls do not have to be the same, just simpler to create multiples this way.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
1 1 1 1

Thanks. It's fine to keep the only connection open in our unit tests, but the real concerns is what happens if the connection is broken, and we cannot re-connect in the real time fashion for our production? Could you please finding out what we should expect in term of connection STATE check whenever we are in the need to re-connect? Seems to us CONNECTION_DOWN is always returned first during the re-creating.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.