on 11-06-2009 10:44 PM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
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
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
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();
}
}
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
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
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
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
86 | |
10 | |
10 | |
9 | |
6 | |
6 | |
6 | |
5 | |
4 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.