cancel
Showing results for 
Search instead for 
Did you mean: 

Retrieve user sessions from all nodes / force_remote

Former Member
0 Kudos

Hello,

I am trying to retrieve all user sessions from all nodes in a J2EE portal environment. The code below works great. However, it only returns the users from the node I am currently attached to.

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl"); 
env.put(Context.PROVIDER_URL, serverIP + ":" + serverPort + "#" + serverId);
env.put("force_remote", "true");

InitialContext context = new InitialContext(env);
Object obj = context.lookup( "remotesecurity" );
RemoteSecurity remoteSecurity = (RemoteSecurity) PortableRemoteObject.narrow(obj, RemoteSecurity.class);

RemoteSecuritySessions sessions = remoteSecurity.getSecuritySessions();
SecuritySession securitySession[] = sessions.listSecuritySessions();

So I included this statement to attach to remote servers per [SAP instructions|http://help.sap.com/saphelp_nw04/helpdata/en/8d/41ee1b22797c4b9d9b7ad67aa7333f/content.htm]. But that generates the error you see below.

env.put("force_remote", "true");

#1.#C6CD2000E002007600000BC8001ED034000477BB4B57FFF1#1257546213490#com.sap.engine.core.cluster.impl6.JoinPortListener#
#com.sap.engine.core.cluster.impl6.JoinPortListener.run()#Guest#0##n/a#
#af6c4ad0cb2211de9d23c6cd2000e002#SAPEngine_Application_Thread[impl:3]_24#
#0#0#Error##Plain###java.io.IOException: Invalid connection identification byte: 118.
        at com.sap.engine.core.cluster.impl6.JoinPortListener$SocketProcessor.run(JoinPortListener.java:191)
        at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)
        at java.security.AccessController.doPrivileged(AccessController.java:219)
        at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:104)
        at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:176)
#com.sap.engine.services.jndi.persistent.exceptions.NamingException: Exception while trying to get InitialContext.  
Root exception is com.sap.engine.interfaces.cross.DestinationException: cannot establish connection with any of the available instances 
Nested exceptions are: com.sap.engine.services.rmi_p4.exception.P4BaseIOException: Cannot open connection on host:  and port:

Does anyone know how to resolve this problem?

Thanks in advance,

John

Accepted Solutions (0)

Answers (4)

Answers (4)

Former Member
0 Kudos

I am specifying in the PROVIDER_URL the server IP address, server Port and node ID. But I'm always getting data from the current node. Even when I hard-code the cluster ID from another node I always get the data from the current node. And if I put in a bogus server node Id I STILL get data from the current node. It seems as if the code is ignoring the forced remote server node id.

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl"); 
env.put(Context.PROVIDER_URL, "xx.xx.xx.xxx:50004#4879352");
env.put("force_remote", "true");

InitialContext context = new InitialContext(env);
Object obj = context.lookup( "remotesecurity" );
RemoteSecurity remoteSecurity = (RemoteSecurity) PortableRemoteObject.narrow(obj, RemoteSecurity.class);

RemoteSecuritySessions sessions = remoteSecurity.getSecuritySessions();
SecuritySession securitySession[] = sessions.listSecuritySessions(); // list of sessions on given server in a cluster

Any ideas why this would be happening?

Thanks,

John

siarhei_pisarenka3
Active Contributor
0 Kudos

John

Maybe the WebDynpro forum is not a good place for such questions... Try Netweaver Security or other forums.

BR, Siarhei

Former Member
0 Kudos

I think you are mistaken. This forum is "Java Programming". There is a specific forum named "Web Dynpro Java" for Dynpro specific type of programming. I checked the "Security" forum but that is specifically related to UME and role management and not programming related at all. I've seen other programming questions posted similar to my problem in this forum so I think I'm in the right place.

Thanks,

John

Former Member
0 Kudos

Hi John,

Have you tried providing user and pwd for SECURITY_PRINCIPALS & SECURITY_CREDENTIALS env vars ? SAPHelp says this :

"The port specified in the provider URL is the P4 port of the dispatcher. Although the client is an application, if it wants to use the naming system of a different Java instance it has to specify security credentials and principles."

Maybe "Guest" (default value) does not have rights to access remote naming features, so the code sticks to current cluster node ?

Hope this helps

Chris

Former Member
0 Kudos

Hi Christophe,

I've tried adding credentials as well and I get the same results. I've used my personal credentials and the Administrator's credentials. I've tried with no credentials as well which seems to use the credentials of the logged in user. When I supply the credentials it creates a new session on the current node each time it passes through the for-loop.

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl"); 
//env.put(Context.INITIAL_CONTEXT_FACTORY, "com.inqmy.services.jndi.RemoteInitialContextFactoryImpl"); 
env.put(Context.PROVIDER_URL, providerURL); //server_ip:port#server_id_in_a_cluster
env.put(Context.SECURITY_PRINCIPAL, "Administrator");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put("force_remote", "true");

I've also tried using com.inqmy.services.jndi.RemoteInitialContextFactoryImpl, which is another method recommended by SAP but I can't locate the jar files containing the class.

I'm going to post the entire program in here in case someone can locate a bug in my code or would like to run it in their own environment to see what results they get. I'm going to post in a 2nd post because the renderer for these forums apparently can't handle the length OR squiggles for start/stop blocks. It'll look messy but hopefully you can copy/paste it.

-John

Former Member
0 Kudos

Here's the source code

public void doContent(IPortalComponentRequest request, IPortalComponentResponse response)
{
  IClusterInformation clusterInfo = (IClusterInformation)PortalRuntime.getRuntimeResources().getService("com.sap.portal.runtime.system.clusterinformation.clusterinformation");
  int clusterElements[] = clusterInfo.getIDClusterElements();
  try
  {
    for (int i=0;i<clusterElements.length;i++)
    {
      String serverIP = clusterInfo.getServerIP(clusterElements<i>);
      int serverPort = clusterInfo.getServerPort(clusterElements<i>);
      int serverId = clusterElements<i>;
      serverPort = 50004;  // hard-code the port to p4
      String providerURL = serverIP + ":" + serverPort + "#" + serverId;
      response.getWriter().write(providerURL + "<br>");

      if (!clusterInfo.isDispatcher(clusterElements<i>))
      {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl"); 
        //env.put(Context.INITIAL_CONTEXT_FACTORY, "com.inqmy.services.jndi.RemoteInitialContextFactoryImpl"); 
        env.put(Context.PROVIDER_URL, providerURL); //server_ip:port#server_id_in_a_cluster
        //env.put(Context.SECURITY_PRINCIPAL, "Administrator");
        //env.put(Context.SECURITY_CREDENTIALS, "password");
        env.put("force_remote", "true");

        InitialContext context = new InitialContext(env);
        Object obj = context.lookup( "remotesecurity" );
        RemoteSecurity remoteSecurity = (RemoteSecurity) PortableRemoteObject.narrow(obj, RemoteSecurity.class);
        
        response.getWriter().write("getActiveSessionsCount=" + remoteSecurity.getActiveSessionsCount() + "");
        response.getWriter().write("getLoggedUsersCount=" + remoteSecurity.getLoggedUsersCount() + "");
        response.getWriter().write("getLoggedUsersCount=" + remoteSecurity.getActiveSessionsCount(serverIP + ":" + serverPort + "#" + serverId) + "");

        RemoteSecuritySessions sessions = remoteSecurity.getSecuritySessions();
        SecuritySession securitySession[] = sessions.listSecuritySessions(); // list of sessions on given server in a cluster
      /*
</tr>");
        for (int x=0; x < securitySession.length; x++)
        {
          SecuritySession s = securitySession[x];
          response.getWriter().write(s.getPrincipal());
        }
        response.getWriter().write("# of sessions=" + securitySession.length + "");
        response.write("");
      */

        securitySession = null;
        sessions = null;
        remoteSecurity = null;
        obj = null;
        context = null;
        env = null;
      }
      response.getWriter().write("");
    }    
  }
  catch (Exception e1)
  {
    // TODO Auto-generated catch block
    e1.printStackTrace();
  }
}

Former Member
0 Kudos

Wow - that worked like a lead balloon. I have source available if anyone wants it.

-John

christiansche
Active Participant
0 Kudos

Hhi John,

it works for me, when I use the following Code:


IClusterInformation clusterInfo = (IClusterInformation) PortalRuntime.getRuntimeResources().getService(IClusterInformation.KEY);

int clusterElements[] = clusterInfo.getIDClusterElements();

for (int j = 0; j < clusterElements.length; j++) {
  int port = clusterInfo.getServerPort(clusterElements[j]);

  if (port > 0) {
    String nodeID = "" + clusterElements[j];
    //usind hostname instead of ip address
    String host = System.getProperty("j2ee.dbhost");
    //Setting the port to xxx04
    String providerURL = host + ":" + (port + "").substring(0, 3) + "04#" + nodeID;

    Context ctx = null;
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl");
    env.put(Context.PROVIDER_URL, providerURL);
    env.put("force_remote", "true");
    ctx = new InitialContext(env);

    com.sap.engine.services.security.remote.RemoteSecurity security = (RemoteSecurity_Stub) ctx.lookup("remotesecurity");

    RemoteSecuritySessions rss = security.getSecuritySessions();

    response.write("Sessions: " + rss.listSecuritySessions().length);
    }
  }

Maybe there is a difference to your code.

Best Regards,

Christian

Former Member
0 Kudos

Hi Christian,

Thanks for the response. That's very similar to the code I have. Except I'm using RemoteSecurity instead of RemoteSecurity_Stub in the class cast. When I used RemoteSecurity in the class cast I only get sessions from the current node. When I added RemoteSecurity_Stub, I get a compile time exception.

Kind	Status	Priority	Description	Resource	In Folder	Location
Error			This compilation unit indirectly references the missing type com.sap.engine.services.rmi_p4.StubImpl (typically some required class file is referencing a type outside the classpath)

Do you know which JAR file contains the class com.sap.engine.services.rmi_p4.StubImpl?

Thanks,

John

Former Member
0 Kudos

I found it the class in p4.jar. I added the library to the project, compiled and deployed. Same result - I only get security sessions from the current node.

providerURL=hostname:50004#4879352
Sessions: 84
providerURL=hostname:50004#4879351
Sessions: 84
providerURL=hostname:50004#4879350
Sessions: 84

I'm running the following software component versions. Are you running something different? Perhaps we've got a bugged kernel implementation?

sap.com/SAP-JEECOR 7.01 SP3 (1000.7.01.3.0.20081208163400) 20090614073324

sap.com/SAP-JEE 7.01 SP3 (1000.7.01.3.0.20081208163400) 20090614073032

Kernel Version: 7.01 PatchLevel 51212

-John

christiansche
Active Participant
0 Kudos

Hi John,

i didn't watch the thread, so ma reply is a little late. We are on

sap.com/SAP-JEECOR 7.01 SP4 (1000.7.01.4.0.20090417015900) 20090721171323

sap.com/SAP-JEE 7.01 SP4 (1000.7.01.4.0.20090417015900) 20090721171123

Kernel Version: 7.01 PatchLevel 58805.

It seems strange to me, that it doesn't work for you. I'm sorry, I don't have any other clue.

best Regards,

Christian

Former Member
0 Kudos

I agree. The P4 port for this instance is 50004. When I hard code the port to 50004 and use "force_remote = true" the errors go away but I'm still getting the users from the current node and not all nodes, even though I'm looping through each node.

Any other ideas?

Thanks,

John

Former Member
0 Kudos

Sorry - should have include how I was getting the serverIP, serverPort and serverId.


IClusterInformation clusterInfo = (IClusterInformation)PortalRuntime.getRuntimeResources().getService("com.sap.portal.runtime.system.clusterinformation.clusterinformation");
int clusterElements[] = clusterInfo.getIDClusterElements();

for (int i=0;i<clusterElements.length;i++)
{
  String serverIP = clusterInfo.getServerIP(clusterElements<i>);
  int serverPort = clusterInfo.getServerPort(clusterElements<i>);
  int serverId = clusterElements<i>;
  ...
}

Does look correct? The data I'm getting back for 3 nodes is below.

ServerName=Server 2 0_48793
getServerPort=50030
getServerIP=xx.xx.xx.xxx

ServerName=Server 1 0_48793
getServerPort=50025
getServerIP=xx.xx.xx.xxx

ServerName=Server 0 0_48793
getServerPort=50020
getServerIP=xx.xx.xx.xxx

Thanks,

John

siarhei_pisarenka3
Active Contributor
0 Kudos

John

P4 port shall end with 4 (like 50004). I do not know exactly which ports your API returns, but very likely it's HTTP ports, not P4.

BR, Siarhei

siarhei_pisarenka3
Active Contributor
0 Kudos

Hi John

Maybe the Context.PROVIDER_URL is not correctly provided. I cannot see this from your message, but keep in mind that P4 port shall be provided (like 50004).

BR, Siarhei