T3 client with custom SSLSocketFactory - java

I have my T3 client code like this:
private InitialContext initContext() {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, context.providerURL);
for (Map.Entry<String, String> entry : getEnvironmentProperties().entrySet()) {
p.put(entry.getKey(), entry.getValue());
}
InitialContext res = null;
try {
res = new InitialContext(p);
} catch (NamingException e) {
e.printStackTrace();
}
return res;
}
My t3 client deployed on Tomcat (uses wlthint3client-12.1.3.jar) and trying to lookup remote bean of external system which deployed on Weblogic.
However when I trying to perform new InitialContext(p) I receive SSLHandshake exception, because it gets standart SSLSocketFactory with standart SSLConext and standart java trust store.
My question - is there any way to give to InitialContext some property which will override SSLSocketFacory. My aim is to populate my cutom trust store to this t3 client.
Changing standart trust store like this
System.setProperty("javax.net.ssl.trustStore", "pathToTrustStore");
works fine, however in case if my t3 client is used to communicate with 2 different external systems, it might be a problem in doing so.
Is there some property that I can populate?
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
**p.put("CUSTOM SSL SOCKET FACTORY, "MY CLASS");**

Problem was solved by adding few parameters on application side
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStore=path/truststore.jks"
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=changeIT"

Related

MQ - Get Multi Instance MQ Manager Connection List

In a Java client app we are connecting to a multi-instance MQ Manager as follows:
java.net.URL ccdt = new URL("file:./config/qmgrs/MQMGR/AMQCLCHL.TAB");
MQQueueManager mqQueueManager = new MQQueueManager("*MQMGR", ccdt);
We can then for example enquire about the current depth of a queue as follows:
int openOptions = CMQC.MQOO_INQUIRE;
MQQueue mqQueue = mqQueueManager.accessQueue("A.QUEUE.NAME", openOptions);
System.out.println("queue depth:" + mqQueue.getCurrentDepth());
Question is, using the same MQQueueManager object, how can we get the list of multi-instance MQ Managers' addresses and ports. Or any other info about the manager itself...
We can see there is the following sort of thing available:
String nameList = mqQueueManager.getAttributeString(MQConstants.MQCA_NAMELIST_NAME, MQConstants.MQ_NAMELIST_NAME_LENGTH);
But when we call the above command, we get:
com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2067'.
We are not sure if this is because the client code is not configured correctly or, if it is because the connection that we are using does not have sufficient permissions to get information about the manager?
You will have to use MQ PCF classes to query queue manager attributes. There is sample PCF_WalkThroughQueueManagerAttributes.java shipped with MQ that displays all attributes of queue manager. Here is small sample that lists local queues of a queue manager.
private void runPCFTest() {
try {
PCFAgent agent = new PCFAgent(connect());
PCFParameter[] parameters = { new MQCFST (MQConstants.MQCA_Q_NAME, "*"),
new MQCFIN (MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL)};
MQMessage[] responses = agent.send(CMQCFC.MQCMD_INQUIRE_Q_NAMES, parameters);
MQCFH cfh = new MQCFH(responses[0]);
for (int i = 0; i < cfh.getParameterCount(); i++) {
System.out.println (PCFParameter.nextParameter (responses [0]));
}
}catch(Exception ex) {
System.out.println(ex);
}
}
#SuppressWarnings({ "unchecked", "rawtypes" })
private MQQueueManager connect() throws MQException {
Hashtable props = new Hashtable();
props.put(MQConstants.HOST_NAME_PROPERTY, "localhost");
props.put(MQConstants.PORT_PROPERTY, 1414);
props.put(MQConstants.CHANNEL_PROPERTY, "MFT_CHN");
props.put(MQConstants.USER_ID_PROPERTY, "user1");
props.put(MQConstants.PASSWORD_PROPERTY, "passw0rd");
props.put(MQConstants.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
return new MQQueueManager("MQM", props);
}
But why do you want to query connection information, host, port etc?
If I understand your question correctly, you want to know all of the hostnames (or IP addresses) and Port numbers of the servers where the MI queue manager may reside. Correct?
This information is in your CCDT file. When you (or MQAdmin) created your CCDT entry for the CLNTCONN (client-side channel), you would have issued a like:
DEFINE CHANNEL(TEST.CHL) CHLTYPE(CLNTCONN) TRPTYPE(TCP) CONNAME('ipaddr1(1414), ipaddr2(1414)') QMNAME(QM1)
Hence, the CONNAME parameter has the information and that is what the MQ client library uses to connect to the remote queue manager. First it will try 'ipaddr1(1414)' and if it fails then it will try 'ipaddr2(1414)'.

how to create a new user jazn-data.xml programmatically?

I'm using JDeveloper 11g.
I want to create a new user programmatically in 'jazn-data.xml'. Is this possible and how can I do it?
public void createWeblogicUser() {
try {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "welcome1");
env.put(Context.PROVIDER_URL, "t3://127.0.0.1:7101");
InitialContext ctx = new InitialContext(env);
MBeanServer wls = (MBeanServer) ctx.lookup("java:comp/env/jmx/runtime");
wls.invoke(new ObjectName(" Security:Name=myrealmDefaultAuthenticator")
, "createUser"
, new Object[] {"wls_user5555", "password123","User created programmatically."}
, new String[] {"java.lang.String", "java.lang.String","java.lang.String"}
);
ctx.close();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
Yes, is possible.
Technically speaking, you do not create users in jazn-data.xml, this is just a file used at development time. At runtime, you create users in weblogic.
Please find below a link:
Creating WebLogic users programmatically from a standalone Java client

Connecting WAS to JRules USING ejb

I am trying to call RES server (v 7.1) from EAR deployed on WAS (8.5) instance. I was able to invoke rule server from standalone program and its working without any problems.
However my main problem is to invoke EJB deployed on RES server remotely from another EAR deployed on some other WAS instance. In this case we are not able to look-up the EJB remotely.
As per below thread we should bypass the EJB3 IlrSessionFactory API and should use Java EJB API to look up rule sessions directly.
http://www-01.ibm.com/support/docview.wss?uid=swg21586621
Recommendation from IBM is to use standard java api for ejb lookup or to upgrade to Rule Server 7.5 (latest 8.x).
Code snippet
// Initialization
Map<String, Object> outputParms = null;
IlrStatelessSession session=null;
IlrSessionResponse response=null;
// IlrSessionFactory factory = getFactory();
try {
sessionFactory = JRulesInvoker.getFactory();
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
env.put(Context.PROVIDER_URL,"corbaloc:iiop:localhost:28004");
Context ctx = new InitialContext(env);
Object lookupResult = ctx.lookup("ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote");
PortableRemoteObject aPortableRemoteObject = new PortableRemoteObject();
session = (IlrStatelessSession) aPortableRemoteObject.narrow(lookupResult, IlrStatelessSession.class);
IlrPath path = new IlrPath(ruleApp, ruleSet);
IlrSessionRequest request = sessionFactory.createRequest();
request.setRulesetPath(path);
request.setInputParameters(inputParms);
request.getTraceFilter().setInfoTotalRulesFired(true);
request.getTraceFilter().setInfoExecutionEvents(true);
request.setTraceEnabled(true);
// session = sessionFactory.createStatelessSession();
System.out.println("created session " + IlrJNDIConstants.STATELESS_SESSION_EJB3_NAME);
response = session.execute(request);
System.out.println(response.getRulesetExecutionTrace().getTotalRulesFired() + " rule(s) fired.");
System.out.println("Execution output=" + response.getRulesetExecutionOutput());
// Return the result(s)
outputParms = response.getOutputParameters();
if (logger.isEnabledFor(Level.DEBUG)) {
if (response.getRulesetExecutionOutput() != null) {
logger.debug("RuleSet execution output: \n" + response.getRulesetExecutionOutput());
}
}
}catch (IlrSessionCreationException cx) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(cx.getMessage(), cx);
}
} catch (IlrSessionException e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getMessage(), e);
}
} catch (NamingException e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getMessage(), e);
}
}
Error
Context: idewas/nodes/ide/servers/server1, name: ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote: First component in name ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote not found.
javax.naming.NameNotFoundException: Context: idewas/nodes/ide/servers/server1, name: ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote: First component in name ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]
at com.ibm.ws.naming.jndicos.CNContextImpl.mapNotFoundException(CNContextImpl.java:4563)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1821)
at com.ibm.ws.naming.jndicos.CNContextImpl.doLookup(CNContextImpl.java:1776)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookupExt(CNContextImpl.java:1433)
at com.ibm.ws.naming.jndicos.CNContextImpl.lookup(CNContextImpl.java:615)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:165)
at com.ibm.ws.naming.util.WsnInitCtx.lookup(WsnInitCtx.java:179)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:436)
Check in the SystemOut.log of the RES server what are the binding names for EJBs as it looks like there is no ilog.rules.res.session.impl.ejb3.IlrStatelessSessionRemote there. Also if you have two servers on the same host under the same name e.g. server1 you may have interoberability issues and need to set JVM property com.ibm.websphere.orb.uniqueServerName to true. For more details check the following page Application access problems

JNDI .Net implemantation

I've a java code which uses JNDI to acess a Directory and get user/password to login inside a samba.
What I need is a way to covnert it to .Net code. However I read this MSDN article and couldn't understand. I've tried to use DirectorySearcher class in many different ways.
There's a small piece of java code:
try {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env.put(Context.PROVIDER_URL, jndiServerURL);
ic = new InitialContext(env);
fileSystemProxy = (T3FileSystemProxy) ic.lookup("Credential");
}
catch (Exception e) {
e.printStackTrace();
}
Does somebody know how to implement it?
Unfortunately I couldn't implement JNDI because it's an interface for Java. I've had to get the UNC path and to authenticate using network credential.
using (new UNCPathAccess(Path.GetDirectoryName(pathPdf), username, string.Empty, password))
{
Email.Send(subject, body, email, attachments);
}

Remote object call inside remote JVM

I'm working with weblogic Server. I was wondering if after binding an object in the JNDI context it would be possible to make remote call on this object (executing it inside the remote JVM).
In my local JVM:
Context ctx = null;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL,"t3://remoteServer:7001/);
env.put(Context.SECURITY_PRINCIPAL,"");
env.put(Context.SECURITY_CREDENTIALS,"");
try {
ctx = new InitialContext(env);
MyObjectImpl obj1 = new MyObjectImpl();
ctx.bind("jndi_name", obj1);
//Now my object can be retrieve from the JNDI context under "jndi_name"
MyObjectImpl obj2 = (MyObjectImpl)ctx.lookup("jndi_name"); //lookup of object
System.out.println(obj2.method(1,2)); //call
}catch (Exception e) {
// a failure occurred
}
But the call is done locally in the client JVM and not the remote JVM.
Is there any way to counter this problem?
Regards,
Make sure you have a remote interface(using annotation #Remote) for jndi lookup.
You can see this example: http://middlewaremagic.com/weblogic/?p=5532 (search for the class “CalculatorBean.java”).

Categories