IBM MQ fail with reason '2278' ('MQRC_CLIENT_CONN_ERROR') - java

I have been trying with no luck to get a java app to connect to IBM MQ v8 via CCDT file. I can connect fine when connecting using properties (hostname, port, etc) but with CCDT I consistently get WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2278' ('MQRC_CLIENT_CONN_ERROR').
I am using a vanilla install of MQ Developer 8.0 (version required, can't change) and the Jars from the installation. All I did was install MQ, then setup a QueueManager 'QM1', then create a queue 'Q1'.
My code:
package mqtest;
import com.ibm.mq.jms.*;
import java.io.File;
import java.net.URL;
public class Main {
public static void main(String[] args) {
try {
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
File file = new File("C:/ProgramData/IBM/MQ/qmgrs/QM1/#ipcc/AMQCLCHL.TAB");
URL clientChannelTableUrl = file.toURI().toURL();
cf.setQueueManager("QM1");
cf.setCCDTURL(clientChannelTableUrl);
MQQueueConnection mqQueueConnection = (MQQueueConnection) cf.createConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
}
dis qmgr
AMQ8408: Display Queue Manager details.
QMNAME(QM1) ACCTCONO(DISABLED)
ACCTINT(1800) ACCTMQI(OFF)
ACCTQ(OFF) ACTIVREC(MSG)
ACTVCONO(DISABLED) ACTVTRC(OFF)
ALTDATE(2018-05-23) ALTTIME(10.21.26)
AUTHOREV(DISABLED) CCSID(437)
CERTLABL(ibmwebspheremqqm1) CERTVPOL(ANY)
CHAD(DISABLED) CHADEV(DISABLED)
CHADEXIT( ) CHLEV(DISABLED)
CHLAUTH(ENABLED) CLWLDATA( )
CLWLEXIT( ) CLWLLEN(100)
CLWLMRUC(999999999) CLWLUSEQ(LOCAL)
CMDEV(DISABLED) CMDLEVEL(800)
COMMANDQ(SYSTEM.ADMIN.COMMAND.QUEUE) CONFIGEV(DISABLED)
CONNAUTH(SYSTEM.DEFAULT.AUTHINFO.IDPWOS)
CRDATE(2018-05-23) CRTIME(10.21.26)
CUSTOM( ) DEADQ( )
DEFCLXQ(SCTQ) DEFXMITQ( )
DESCR( ) DISTL(YES)
INHIBTEV(DISABLED) IPADDRV(IPV4)
LOCALEV(DISABLED) LOGGEREV(DISABLED)
MARKINT(5000) MAXHANDS(256)
MAXMSGL(4194304) MAXPROPL(NOLIMIT)
MAXPRTY(9) MAXUMSGS(10000)
MONACLS(QMGR) MONCHL(OFF)
MONQ(OFF) PARENT( )
PERFMEV(DISABLED) PLATFORM(WINDOWSNT)
PSMODE(ENABLED) PSCLUS(ENABLED)
PSNPMSG(DISCARD) PSNPRES(NORMAL)
PSRTYCNT(5) PSSYNCPT(IFPER)
QMID(QM1_2018-05-23_10.21.26) REMOTEEV(DISABLED)
REPOS( ) REPOSNL( )
REVDNS(ENABLED) ROUTEREC(MSG)
SCHINIT(QMGR) SCMDSERV(QMGR)
SPLCAP(ENABLED) SSLCRLNL( )
SSLCRYP( ) SSLEV(DISABLED)
SSLFIPS(NO)
SSLKEYR(C:\ProgramData\IBM\MQ\qmgrs\QM1\ssl\key)
SSLRKEYC(0) STATACLS(QMGR)
STATCHL(OFF) STATINT(1800)
The error log in C:\ProgramData\IBM\MQ\qmgrs\QM1\errors has no relevant (that I can see at least) data in it.
As far as I can tell from various SO, IBM, Google searches this should work. As far as I can tell it has something to do with Channel definition or settings, but I just don't know what.
And, honestly, I think I have spent enough brain cells on this that I am most likely overlooking something important but can't see the small simple detail I am overlooking. Any help as appreciated.

MQ Version: 9.0.0.4
Step 1: only one jar required: com.ibm.mq.allclient-9.0.4.0.jar
Step 2:
Do not set any variable in MQEnvironment
Step 3:
java.net.URL chanTab1 = new URL("file:///C:/MGR.TAB");
MQQueueManager _queueManager = new MQQueueManager("*", chanTab1);
int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
MQQueue queue = _queueManager.accessQueue( "QNAME", openOptions,null,null, null );
MQMessage sendmsg = new MQMessage();
* will allow you to connect all the QManager available in the .TAB file.
Step 4:
Install certificate in your jre C:\Program Files\Java\jdk1.7\jre\bin by command
keytool -import -alias example -keystore ..\lib\security\cacerts -file C:\test.cer
default password is changeit. Mostly nobody change this. :-)
or
if you deployed your code on websphere application server then no need to install certificate in server JRE. Insted install certificate on Websphere server
SSL certificate and key management > Key stores and certificates > NodeDefaultKeyStore > Signer certificates > Retrieve from port

Related

Is there any way to connect to perform operation on AWS neptune giving gremlin code in .java file

I tried Connecting the AWS Neptune with this Java code and got the error , NoHostAvailable Exception
approach 1:
public static void main(String[] args) throws Exception {
Cluster.Builder builder = Cluster.build();
builder.addContactPoint("endpoint");
builder.port(8182);
builder.enableSsl(true);
builder.keyStore("pem-file");
Cluster cluster = builder.create();
GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster));
System.out.println(g.V().limit(10).toList());
cluster.close();
}}
approach 2:
Cluster cluster = Cluster.build("endpoint").
enableSsl(true).keyStore("pem").
handshakeInterceptor( r -> {
NeptuneNettyHttpSigV4Signer sigV4Signer = null;
try {
sigV4Signer = new NeptuneNettyHttpSigV4Signer("us-east-2", new
DefaultAWSCredentialsProviderChain());
} catch (NeptuneSigV4SignerException e) {
e.printStackTrace();
}
try {
sigV4Signer.signRequest(r);
} catch (NeptuneSigV4SignerException e) {
e.printStackTrace();
}
return r;
}).create();
Client client=Cluster.open("src\\conf\\remote-objects.yaml").connect();
client.submit("g.V().limit(10).toList()").all().get();
what ever I do, I am getting this error:
Sep 02, 2021 3:18:34 PM io.netty.channel.ChannelInitializer exceptionCaught
WARNING: Failed to initialize a channel. Closing:
java.lang.RuntimeException: java.lang.NullPointerException
org.apache.tinkerpop.gremlin.driver.Channelizer$AbstractChannelizer.initChannel(Channelizer.java:117)
Caused by: org.apache.tinkerpop.gremlin.driver.exception.NoHostAvailableException: All hosts
are considered unavailable due to previous exceptions. Check the error log to find the actual
reason.
I need the code or the document to connect my Gremlin code in .java file to AWS neptune. I am struggling and tried various number of ways,
1.created EC2 instance and did installed maven and apache still got error and code is running in Server(EC2), i want code to present in IntelliJ
it would be more helpful, if I get the Exact Code any way. what should be added in remote-objects.yaml.
if we require Pem-file to access Amazon Neptune, please help with the creation of it.
Assuming SSL is enabled but IAM is not, in terms of Java code, this is all you need to create the connection.
Cluster.Builder builder = Cluster.build();
builder.addContactPoint("localhost");
builder.port(8182);
builder.enableSsl(true);
builder.serializer(Serializers.GRAPHBINARY_V1D0);
cluster = builder.create();
drc = DriverRemoteConnection.using(cluster);
g = traversal().withRemote(drc);
You may need to add an entry to your /etc/hosts file to get the SSL certs to resolve correctly such as:
127.0.0.1 localhost my-neptune-cluster.us-east-1.neptune.amazonaws.com
If you find that using localhost with SSL enabled does not work then use the actual Neptune cluster DNS name and make the edit to your /etc/hosts file.
The last thing you will need to do is create access to the Neptune VPC from your local machine. One way is using an SSH tunnel as explained in this post

Connecting to an MQ with Jmeter

I've been assigned the task of using Apache Jmeter to connect to an MQ. Unfortunately, I'm not the admin of the MQ, and all my attempts to get more information about it have gotten me nowhere. What I have now is a queue name (call it q), a queue manager (its name, anyway; call it v), a host (w), a port (x), a channel (y), a user (z), and a test message I'm supposed to send across. The object of the game is straightforward: send the test message from Apache Jmeter to the MQ (after which I'll ask the admins whether the message went through or not). In other words, I need help figuring out what to do with Jmeter.
The MQ is version 8.0.0.4. I already have Jmeter installed, so I don't need advice on that (unless there's some special way it should have been installed for this task).
The links provided in this question's answer didn't get me very far. They seemed largely unrelated to what I was trying to do (and also imprecise in their instructions).
Download 8.0.0.4-WS-MQ-Install-Java-All file
Run it like java -jar 8.0.0.4-WS-MQ-Install-Java-All.jar and accept the license agreement
Add all .jars from wmq/JavaSE/ folder to JMeter Classpath
Restart JMeter to pick the .jars up
Add JSR223 Sampler to your Test Plan and put the following code into "Script" area:
import com.ibm.msg.client.jms.JmsFactoryFactory
import com.ibm.msg.client.wmq.WMQConstants
import javax.jms.Session
// 1
def hostName = "127.0.0.1"
def hostPort = 1414
def channelName = "DEV.APP.SVRCONN"
def queueManagerName = "QM1"
def queueName = "DEV.QUEUE.1"
// 2
def ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER)
def cf = ff.createConnectionFactory()
// 3
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, hostName)
cf.setIntProperty(WMQConstants.WMQ_PORT, hostPort)
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channelName)
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT)
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManagerName)
// 4
def conn = cf.createConnection("app", "")
def sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
// 5
def destination = sess.createQueue(queueName)
conn.start()
See IBM MQ testing with JMeter - Learn How article for more information if needed.

JUnit test with Embedded tomcat server , how to specify automatic ports for both http and https connectors?

Description
I have made a JUnit test that focus on trying to test a call to a SOAP web service.
I am using an embedded tomcat server for my test in order to run my test with a mock server.
I am also using both http and https connectors.
I need to use automatic ports for both these connectors because the test is running on a Jenkins server and i can't just use port 443 or 8443 as they are already taken.
I understand that using the port 0 as standard port will result in tomcat using automatic port allocation but I can't manage to use it with both connectors.
Expected behavior
I'd like to use automatic port allocation also for my custom ssl connector.
Is it possible to do so in some way ?
Sample code
Here is the code for my tomcat instance :
#Before
public void setup() throws Throwable {
File tomcatWorkingDir = new File(mWorkingDir);
//Empty the target/tomcat-working-dir directory if it exist
//Create the directory otherwise
if(tomcatWorkingDir.exists() && tomcatWorkingDir.isDirectory()){
LOGGER.info("cleaning tomcat-working-dir directory");
FileUtils.cleanDirectory(new File(mWorkingDir));
} else {
LOGGER.info("create tomcat-working-dir directory");
tomcatWorkingDir.mkdir();
}
LOGGER.info("disabling ssl certification validation");
//Disable JVM ssl sockets connection
disableJVMCertificate();
//Add server certificate
createServerCertificate();
//Custom SSL Connector
Connector SSLConnector = getSSLConnector();
mTomcat = new Tomcat();
//Standard http startup port
mTomcat.setPort(0);
//Set up base directory
//Otherwise, tomcat would use the current directory
mTomcat.setBaseDir(mWorkingDir);
LOGGER.info("setting the ssl connector in TOMCAT");
Service service = mTomcat.getService();
service.addConnector(SSLConnector);
//Redirect current port
Connector defaultConnector = mTomcat.getConnector();
defaultConnector.setRedirectPort(SERVER_HTTPS_PORT);
//Configure the way WAR are managed by the engine
mTomcat.getHost().setAutoDeploy(true);
mTomcat.getHost().setDeployOnStartup(true);
//Add mock server into our webApp
String servletName = "/server";
File webApp = new File(mWorkingDir,"../../../ws-mock-server/src/main/webapp");
mTomcat.addWebapp(mTomcat.getHost(), servletName, webApp.getAbsolutePath());
//start tomcat
LOGGER.info("starting TOMCAT");
mTomcat.start();
}
and here for my custom ssl connector.
private static Connector getSSLConnector(){
Connector connector = new Connector();
connector.setPort(SERVER_HTTPS_PORT);
connector.setSecure(true);
//Http protocol Http11AprProtocol
connector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
//Maximum threads allowedd on this instance of tomcat
connector.setAttribute("maxThreads","200");
connector.setAttribute("SSLEnabled", true);
//No client Authentification is required in order to connect
connector.setAttribute("clientAuth", false);
//SSL TLSv1 protocol
connector.setAttribute("sslProtocol","TLS");
//Ciphers configuration describing how server will encrypt his messages
//A common cipher suite need to exist between server and client in an ssl
//communication in order for the handshake to succeed
connector.setAttribute("ciphers","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
LOGGER.info("setting keystore file");
//Here an absolute file path is needed in order to properly set up the keystore attribute
connector.setAttribute("keystoreFile",new File(".").getAbsolutePath().replace("\\", "/")+"/"+mWorkingDir+"/server.jks");
LOGGER.info("setting keystore pass");
connector.setAttribute("keystorePass","changeit");
return connector;
}
I have two solutions for this problem:
Select SSL port manually
The ServerSocket(0) constructor automatically selects a free port. The Tomcat uses this method also.
try (ServerSocket testSocket = new ServerSocket(0)) {
int randomFreePort = testSocket.getLocalPort();
sslConnector.setPort(randomFreePort);
defaultConnector.setRedirectPort( randomFreePort);
} // At this point the testSocket.close() called
tomcat.start();
I know, there is a probability, that an another process allocates the same port between the testSocket.close() and tomcat.start(), but you can detect this situation, with LifecycleState.FAILED.equals(sslConnector.getState()) test.
Use lifecycle listeners
Tomcat connectors are lifecycle aware, so you will be notified on 'before_init' and 'after_init' events. Tomcat initializes the connectors in the order as you added them to the Service.
Add the ssl connector.
Add an http connector. (That will be the 'default' connector. Don't call the mTomcat.getConnector() because it gets the first or creates a new connector. )
When the ssl connector initialization complete, you can get the chosen port with getLocalPort() call.
Before the http connector initialization, call the setRedirectPort
Full example:
Tomcat mTomcat = new Tomcat();
Connector sslConnector = getSSLConnector();
mTomcat.getService().addConnector(sslConnector);
Connector defaultConnector = new Connector();
defaultConnector.setPort(0);
mTomcat.getService().addConnector(defaultConnector);
// Do the rest of the Tomcat setup
AtomicInteger sslPort = new AtomicInteger();
sslConnector.addLifecycleListener(event->{
if( "after_init".equals(event.getType()) )
sslPort.set(sslConnector.getLocalPort());
});
defaultConnector.addLifecycleListener(event->{
if( "before_init".equals(event.getType()) )
defaultConnector.setRedirectPort(sslPort.get());
});
mTomcat.start();
I haven't tried it but from the code it looks like
You can setRedirectPort after server was started
You can use Connector.getLocalPort to get actual port
So I think you could try to add something like
mTomcat.start(); // <-- your existing code
defaultConnector.setRedirectPort(SSLConnector.getLocalPort())

Java JDBC unable to connect to a Oracle database with SSL

I have configured a Oracle 11g database server to work with SSL using a wallet and self signed certificate.
Tested it with local client (sqlplus) and it works without any issues.
Now I'm trying to connect the database using Java JDBC.
Currently I'm getting an error:
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to
find valid certification path to requested target
Here is my code:
public static void main(String[] args)
{
Connection connection = null;
String url = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=VDB)))";
Properties props = new Properties();
props.setProperty("user", "dbuser");
props.setProperty("password", "dbpass");
props.setProperty("oracle.net.ssl_cipher_suites","(SSL_RSA_WITH_3DES_EDE_CBC_SHA)");
/* Load the database driver */
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(url,props);
if (connection != null) {
System.out.println("You made it, take control your database now!");
} else {
System.out.println("Failed to make connection!");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
I did some more research, and found that if the wallet is configured as 'auto_login', I can try the following:
Connection connection = null;
String url = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=VDB)))";
Properties props = new Properties();
props.setProperty("user", "dbuser");
props.setProperty("password", "dbpass");
props.setProperty("javax.net.ssl.trustStore", "C:\\oracle\\wallet\\cwallet.sso");
props.setProperty("javax.net.ssl.trustStoreType","SSO");
/* Load the database driver */
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(url,props);
if (connection != null) {
System.out.println("You made it, take control your database now!");
} else {
System.out.println("Failed to make connection!");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
In this case, I'm getting:
java.security.NoSuchAlgorithmException: SSO KeyStore not available
I've added 3 Jars: oraclepki.jar, osdt_cert.jar, osdt_core.jar
Attempted to run the last version of the code, getting exception:
java.lang.ClassNotFoundException: com.phaos.crypto.AuthenticationException
Perhaps I should specify the wallet location? as I did in the tnsnames.ora file? or specify the certificate CN?
Please advise, thanks.
Using services or resources that requires certificates within your application, require that you somehow trust the certificate issuer or certificate itself. In this case, I guess you will have to trust the certificate itself as it is self-signed and not issued by a well-known CA (already trusted by the trust-store bundled with the JRE you're using).
In order to do this, export the certificate that you use together with your database and locate a file called "cacerts". The file exists within your jdk-installation folder. Example:
/path/to/jdk/jre/lib/security/cacerts
The easiest thing to do, is just to import the certificate to this file (you can use some commands to do this, or if you're lazy like me - download KSE and click the Import-button: http://keystore-explorer.org/). You may also specify your own trust-store using properties mentioned here:
https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html
If you choose to use a custom trust-store, you have more control regarding the cacerts - as if you're choosing to update to a newer jdk installation, that installation will use the cacerts issued with the jdk :-).
Anyway. Hope it helped a bit.
The JVM tries to establish a chain of trust of the server's certificate towards any known trusted CAs. You can either obtain a certificate from a CA which is trusted by your Java's default TrustStore or you can provide your own CA certificate (the one you used to sign the self-signed certificate) to your JVM by generating your own TrustStore. You would then pass the TrustStore e.g. using the command line argument -Djavax.net.ssl.trustStore= when starting your application.
Keep in mind that passing a custom TrustStore requires you to either add all CAs which are contained in your JRE's default TrustStore or you live with the fact that no chains of trust can be established to any certificates not issued by your own CA.
A third option is adding your own CA certificate to your system's global TrustStore which leads to any Java application accepting certificates from your CA. This is a shortcut but might not be in your best interest if you require a strict separation of CAs.
I think below link may be helpful to you.
http://docs.oracle.com/cd/B19306_01/java.102/b14355/sslthin.htm#BABHFBJD
Found the solution, as I'm using SSO need to specify both keystore and truststore.
Connection connection = null;
String url = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=192.168.200.191)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=NNVSDB)))";
Properties props = new Properties();
props.setProperty("user", "dbuser");
props.setProperty("password", "dbpass");
//Single sign on
props.setProperty("javax.net.ssl.trustStore", "C:\\oracle\\wallet\\cwallet.sso");
props.setProperty("javax.net.ssl.trustStoreType","SSO");
props.setProperty("javax.net.ssl.keyStore","C:\\oracle\\wallet\\cwallet.sso");
props.setProperty("javax.net.ssl.keyStoreType","SSO");
props.setProperty("oracle.net.authentication_services","(TCPS)");
/* Load the database driver */
try
{
Security.addProvider(new oracle.security.pki.OraclePKIProvider());
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
connection = DriverManager.getConnection(url,props);
if (connection != null) {
System.out.println("You made it, take control your database now!");
} else {
System.out.println("Failed to make connection!");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}

SSL Error while publishing extract to tableau server

Getting the following error while publishing an extract into Tableau server.
com.tableausoftware.TableauException: Problem with the SSL CA cert (path? access rights?)
at com.tableausoftware.server.ServerConnection.connect(Unknown Source)
at com.tableau.sample.PublishOrder.main(PublishOrder.java:31)
CURL_ERROR - Problem with the SSL CA cert (path? access rights?)
com.tableausoftware.TableauException: Problem with the SSL CA cert (path? access rights?)
at com.tableausoftware.server.ServerConnection.connect(Unknown Source)
at com.tableau.sample.PublishOrder.main(PublishOrder.java:31)
I am using online Tableau server and its version is 10.0
Here is my java code. This is same as the sample provided in Tableau documentation
import com.tableausoftware.TableauException;
import com.tableausoftware.common.*;
import com.tableausoftware.server.*;
public class PublishOrder {
public static void main( String[] args ) {
try {
// Initialize Tableau Server API
ServerAPI.initialize();
// Create the server connection object
ServerConnection serverConnection = new ServerConnection();
// Connect to the server
serverConnection.connect("https://xxx.online.tableau.com", "xxx#example.com", "xxx", "xxx");
// Publish order-java.tde to the server under the default project with name Order-java
serverConnection.publishExtract("order-java.tde", "default", "Order-java-ubuntu", false);
// Disconnect from the server
serverConnection.disconnect();
// Destroy the server connection object
serverConnection.close();
// Clean up Tableau Server API
ServerAPI.cleanup();
}
catch (TableauException e) {
e.printStackTrace();
}
}
}
I am running this java code from ubuntu 12.04.
Please help me to resolve this issue
The error indicates that the CA certificates are not available on your system. Check if the file /usr/local/share/ca-certificates exists. You may also need to update these certificates using update-ca-certificates.

Categories