Monitoring IBM MQ with java - java

How do I discover the Queue depth, and other metrics about queues, from IBM MQ using java with standard IBM MQ libraries?

Try out the below sample code snippet for fetching the queue depth.
String mqQMgr = "";
String mqQueue = "";
MQEnvironment.hostname = "";
MQEnvironment.port = "";
MQEnvironment.channel = "";
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
MQQueueManager qMgr = new MQQueueManager(mqQMgr);
MQQueue destQueue = qMgr.accessQueue(mqQueue, openOptions);
int depth = destQueue.getCurrentDepth();
destQueue.close();
qMgr.disconnect();
A full code version (Change your parameters accordingly, like Bindings or client mode, options etc ) :
import com.ibm.mq.*;
public class QueueManager {
private final String host;
private final int port;
private final String channel;
private final String manager;
private final MQQueueManager qmgr;
public QueueManager(String host, int port, String channel, String manager) throws MQException {
this.host = host;
this.port = port;
this.channel = channel;
this.manager = manager;
this.qmgr = createQueueManager();
}
private MQQueueManager createQueueManager() throws MQException {
MQEnvironment.channel = channel;
MQEnvironment.port = port;
MQEnvironment.hostname = host;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
return new MQQueueManager(manager);
}
// This method will return the Queue Depth
public int queueDepth(String queueName) {
int depth = -1;
int openOptions = MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING;
MQQueue queue = null;
try {
queue = qmgr.accessQueue(queueName, openOptions);
depth = queue.getCurrentDepth();
}
catch (MQException e)
{
System.out.println("CC=" +e.completionCode + " : RC=" + e.reasonCode);
}
finally {
try {
if (queue != null)
queue.close();
}
catch (MQException e) {
System.out.println("CC=" +e.completionCode + " : RC=" + e.reasonCode);
}
}
return depth;
}
........ Other Methods .......
}

Related

Cannot connect to remote MDB on wildfly - Name not found

I have an issue with connecting to wildfly remote queue.
My MDB on wildfly instance is:
#MessageDriven(name = "HelloWorldQueueMDB", activationConfig = {
#ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/HELLOWORLDMDBQueue"),
#ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
#ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
public class HelloWorldQueueMDB implements MessageListener {
private static final Logger LOGGER = Logger.getLogger(HelloWorldQueueMDB.class.toString());
/**
* #see MessageListener#onMessage(Message)
*/
public void onMessage(Message rcvMessage) {
TextMessage msg = null;
try {
if (rcvMessage instanceof TextMessage) {
msg = (TextMessage) rcvMessage;
LOGGER.info("Received Message from queue: " + msg.getText());
} else {
LOGGER.warning("Message of wrong type: " + rcvMessage.getClass().getName());
}
} catch (JMSException e) {
throw new RuntimeException(e);
}
}
}
and the standalone client is:
public class HelloWorldJMSClient {
private static final Logger log = Logger.getLogger(HelloWorldJMSClient.class.getName());
// Set up all the default values
private static final String DEFAULT_MESSAGE = "Hello, World!";
private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
private static final String DEFAULT_DESTINATION = "queue/HELLOWORLDMDBQueue";
private static final String DEFAULT_MESSAGE_COUNT = "1";
private static final String DEFAULT_USERNAME = "quickstartUser";
private static final String DEFAULT_PASSWORD = "quickstartPwd1!";
private static final String INITIAL_CONTEXT_FACTORY = "org.wildfly.naming.client.WildFlyInitialContextFactory";
private static final String PROVIDER_URL = "http-remoting://127.0.0.1:8080";
public static void main(String[] args) {
Context namingContext = null;
try {
String userName = System.getProperty("username", DEFAULT_USERNAME);
String password = System.getProperty("password", DEFAULT_PASSWORD);
// Set up the namingContext for the JNDI lookup
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
env.put(Context.SECURITY_PRINCIPAL, userName);
env.put(Context.SECURITY_CREDENTIALS, password);
namingContext = new InitialContext(env);
// Perform the JNDI lookups
String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);
log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\"");
ConnectionFactory connectionFactory = (ConnectionFactory) namingContext.lookup(connectionFactoryString);
log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI");
String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);
log.info("Attempting to acquire destination \"" + destinationString + "\"");
Destination destination = (Destination) namingContext.lookup(destinationString);
log.info("Found destination \"" + destinationString + "\" in JNDI");
int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT));
String content = System.getProperty("message.content", DEFAULT_MESSAGE);
try (JMSContext context = connectionFactory.createContext(userName, password)) {
log.info("Sending " + count + " messages with content: " + content);
// Send the specified number of messages
for (int i = 0; i < count; i++) {
context.createProducer().send(destination, content);
}
// Create the JMS consumer
JMSConsumer consumer = context.createConsumer(destination);
// Then receive the same number of messages that were sent
for (int i = 0; i < count; i++) {
String text = consumer.receiveBody(String.class, 5000);
log.info("Received message with content " + text);
}
}
} catch (NamingException e) {
log.severe(e.getMessage());
} finally {
if (namingContext != null) {
try {
namingContext.close();
} catch (NamingException e) {
log.severe(e.getMessage());
}
}
}
}
}
And the error output is:
pro 10, 2020 1:49:20 PM org.jboss.as.quickstarts.jms.HelloWorldJMSClient main
INFO: Found connection factory "jms/RemoteConnectionFactory" in JNDI
pro 10, 2020 1:49:20 PM org.jboss.as.quickstarts.jms.HelloWorldJMSClient main
INFO: Attempting to acquire destination "queue/HELLOWORLDMDBQueue"
pro 10, 2020 1:49:20 PM org.jboss.as.quickstarts.jms.HelloWorldJMSClient main
SEVERE: queue -- service jboss.naming.context.java.jboss.exported.queue
I'm using wildfly 21 and I don't know what I'm doing wrong.
In the wildfly management console I can see the MDB:
URI
java:/queue/HELLOWORLDMDBQueue
Class Name
org.apache.activemq.artemis.jms.client.ActiveMQQueue
Value
ActiveMQQueue[jms.queue.HelloWorldMDBQueue]
Update:
Executed:
jms-queue add --queue-address=HelloWorldQueueMDB --entries=queue/HelloWorldQueueMDB,java:jboss/exported/jms/queue/HelloWorldQueueMDB
on wildfly side I got:
15:05:27,427 ERROR [org.apache.activemq.artemis.core.client] (default I/O-53) AMQ214013: Failed to decode packet: java.lang.NoClassDefFoundError: java/security/acl/Group
Update:
java/security/acl/Group was removed from java14, so using an older version of java works.
So you are trying to access a Queue remotely and not an MDB. Your queue should be exposed externally using the jboss/exported namespace.
java:jboss/exported/queue/HELLOWORLDMDBQueue would work and make the queue available.
You can take a look at WildFly HelloworlJms quickstart or HelloworldMdb for such an example

Hyperledger Fabric Java SDK Event Hub Exception when trying to initialize channel

I'm trying to use the Hyperledger Fabric Java SDK to invoke chaincode transactions but I'm getting the following error in channel.initialize():
Exception in thread "main" org.hyperledger.fabric.sdk.exception.TransactionException: org.hyperledger.fabric.sdk.exception.EventHubException: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:1158)
at HLFJavaClient.getChannel(HLFJavaClient.java:231)
at HLFJavaClient.main(HLFJavaClient.java:84)
Caused by: org.hyperledger.fabric.sdk.exception.EventHubException: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:322)
at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:200)
at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:1127)
... 2 more
Caused by: org.hyperledger.fabric.sdk.exception.CryptoException: Could not sign the message using private key
at org.hyperledger.fabric.sdk.security.CryptoPrimitives.ecdsaSignToBytes(CryptoPrimitives.java:747)
at org.hyperledger.fabric.sdk.security.CryptoPrimitives.sign(CryptoPrimitives.java:757)
at org.hyperledger.fabric.sdk.identity.X509SigningIdentity.sign(X509SigningIdentity.java:23)
at org.hyperledger.fabric.sdk.transaction.TransactionContext.sign(TransactionContext.java:180)
at org.hyperledger.fabric.sdk.transaction.TransactionContext.signByteString(TransactionContext.java:184)
at org.hyperledger.fabric.sdk.EventHub.blockListen(EventHub.java:389)
at org.hyperledger.fabric.sdk.EventHub.connect(EventHub.java:320)
... 4 more
Caused by: java.security.InvalidKeyException: cannot identify EC private key: java.lang.NullPointerException
at org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil.generatePrivateKeyParameter(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.SignatureSpi.engineInitSign(Unknown Source)
at java.security.Signature$Delegate.engineInitSign(Signature.java:1177)
at java.security.Signature.initSign(Signature.java:530)
at org.hyperledger.fabric.sdk.security.CryptoPrimitives.ecdsaSignToBytes(CryptoPrimitives.java:729)
... 10 more
My network is running with 4 peers (peer0.org1.mydomain.com, peer0.org2..., peer0.org3... and peer0.org4...) and one orderer (orderer.mydomain.com).
Java SDK Client code:
public class HLFJavaClient {
public static final String HLF_USER_NAME = "User1#org1.mydomain.com";
public static final String HLF_CLIENT_ORG = "Org1";
public static final String HLF_CLIENT_MSPID = "Org1MSP";
public static final String HLF_CLIENT_CRT_PATH = "../crypto-config/peerOrganizations/org1.mydomain.com/users/User1#org1.mydomain.com/msp/signcerts/User1#org1.mydomain.com-cert.pem";
public static final String HLF_CLIENT_KEY_PATH = "../crypto-config/peerOrganizations/org1.mydomain.com/users/User1#org1.mydomain.com/msp/keystore/User1#org1.mydomain.com-priv.pem";
public static final String HLF_CHANNEL_NAME = "mychannel";
public static final String HLF_CHAINCODE_NAME = "pkicc";
private static final Logger log = Logger.getLogger(HLFJavaClient.class);
public static void main(String[] args) throws Exception {
AppUser appUser = getUser(HLF_CLIENT_CRT_PATH, HLF_CLIENT_KEY_PATH, HLF_USER_NAME);
HFClient client = getHfClient();
client.setUserContext(appUser);
Channel channel = getChannel(client);
addProperty(client, new String[] {"1","w"});
}
static void addProperty(HFClient client, String[] property) throws ProposalException, InvalidArgumentException {
Channel channel = client.getChannel(HLF_CHANNEL_NAME);
TransactionProposalRequest tpr = client.newTransactionProposalRequest();
ChaincodeID CCId = ChaincodeID.newBuilder().setName(HLF_CHAINCODE_NAME).build();
tpr.setChaincodeID(CCId);
tpr.setFcn("createWallet");
tpr.setArgs(property);
Collection<ProposalResponse> res = channel.sendTransactionProposal(tpr);
for (ProposalResponse pres : res) {
String stringResponse = "Response from endorser is: " + pres.getChaincodeActionResponseStatus();
log.info(stringResponse);
System.out.println(stringResponse);
}
channel.sendTransaction(res);
System.out.println("Transaction sent.");
}
static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {
Channel channel = client.newChannel(HLF_CHANNEL_NAME);
class PeerOrgPort {
public String org;
public int port;
public PeerOrgPort(String org, int port) {
this.org = org;
this.port = port;
}
}
PeerOrgPort[] peers = new PeerOrgPort[] {
new PeerOrgPort("1", 7051),
new PeerOrgPort("2", 8051),
new PeerOrgPort("3", 9051),
new PeerOrgPort("4", 10051),
};
for (int i = 0; i < peers.length; i++) {
File tlsCrt = Paths.get("../crypto-config/peerOrganizations/org" + peers[i].org + ".mydomain.com/tlsca", "tlsca.org" + peers[i].org + ".mydomain.com-cert.pem").toFile();
if (!tlsCrt.exists())
throw new RuntimeException("Missing TLS cert files");
Properties secPeerProperties = new Properties();
secPeerProperties.setProperty("hostnameOverride", "peer0.org" + peers[i].org + ".mydomain.com");
secPeerProperties.setProperty("sslProvider", "openSSL");
secPeerProperties.setProperty("negotiationType", "TLS");
secPeerProperties.setProperty("pemFile", tlsCrt.getAbsolutePath());
Peer peer = client.newPeer("peer0.org" + peers[i].org + ".mydomain.com", "grpcs://localhost:" + peers[i].port, secPeerProperties);
channel.addPeer(peer);
if (peers[i].org.equals("1")) {
EventHub eventHub = client.newEventHub("eventhub01", "grpcs://localhost:7053", secPeerProperties);
channel.addEventHub(eventHub);
}
}
File tlsOrdCrt = Paths.get("../crypto-config/ordererOrganizations/mydomain.com/tlsca", "tlsca.mydomain.com-cert.pem").toFile();
if (!tlsOrdCrt.exists())
throw new RuntimeException("Missing TLS cert files");
Properties secOrdererProperties = new Properties();
secOrdererProperties.setProperty("hostnameOverride", "orderer.mydomain.com");
secOrdererProperties.setProperty("sslProvider", "openSSL");
secOrdererProperties.setProperty("negotiationType", "TLS");
secOrdererProperties.setProperty("pemFile", tlsOrdCrt.getAbsolutePath());
Orderer orderer = client.newOrderer("orderer.mydomain.com", "grpcs://localhost:7050", secOrdererProperties);
channel.addOrderer(orderer);
channel.initialize();
return channel;
}
static HFClient getHfClient() throws Exception {
CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
HFClient client = HFClient.createNewInstance();
client.setCryptoSuite(cryptoSuite);
return client;
}
static AppUser getUser(String certPath, String keyPath, String userId) throws Exception {
AppUser appUser = null;//tryDeserialize(userId);
if (appUser == null) {
appUser = new AppUser(userId, HLF_CLIENT_ORG, HLF_CLIENT_MSPID, certPath, keyPath);
}
return appUser;
}
AppUser:
public class AppUser implements User, Serializable {
private static final long serializationId = 1L;
private static final long serialVersionUID = -6287264119837208213L;
private String name;
private Set<String> roles;
private String account;
private String affiliation;
private Enrollment enrollment;
private String mspId;
public AppUser() {
// no-arg constructor
}
public AppUser(String name, String affiliation, String mspId, String certPath, String keyPath) {
this.name = name;
this.affiliation = affiliation;
this.enrollment = getEnrollmentFromCertPath(certPath, keyPath);
this.mspId = mspId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getRoles() {
return roles;
}
public void setRoles(Set<String> roles) {
this.roles = roles;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public Enrollment getEnrollment() {
return enrollment;
}
public void setEnrollment(Enrollment enrollment) {
this.enrollment = enrollment;
}
public String getMspId() {
return mspId;
}
public void setMspId(String mspId) {
this.mspId = mspId;
}
#Override
public String toString() {
return "AppUser{" +
"name='" + name + '\'' +
"\n, roles=" + roles +
"\n, account='" + account + '\'' +
"\n, affiliation='" + affiliation + '\'' +
"\n, enrollment=" + enrollment +
"\n, mspId='" + mspId + '\'' +
'}';
}
private Enrollment getEnrollmentFromCertPath(final String certPath, final String keyPath) {
return new Enrollment() {
public PrivateKey getKey() {
try {
return loadPrivateKey(Paths.get(keyPath));
} catch (Exception e) {
return null;
}
}
public String getCert() {
try {
return new String(Files.readAllBytes(Paths.get(certPath)));
} catch (Exception e) {
return "";
}
}
};
}
private static PrivateKey loadPrivateKey(Path fileName) throws IOException, GeneralSecurityException {
PrivateKey key = null;
InputStream is = null;
BufferedReader br = null;
try {
is = new FileInputStream(fileName.toString());
br = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
boolean inKey = false;
for (String line = br.readLine(); line != null; line = br.readLine()) {
if (!inKey) {
if (line.startsWith("-----BEGIN ") && line.endsWith(" PRIVATE KEY-----")) {
inKey = true;
}
continue;
} else {
if (line.startsWith("-----END ") && line.endsWith(" PRIVATE KEY-----")) {
inKey = false;
break;
}
builder.append(line);
}
}
byte[] encoded = DatatypeConverter.parseBase64Binary(builder.toString());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("ECDSA", "BC");
key = kf.generatePrivate(keySpec);
} finally {
br.close();
is.close();
}
return key;
}
}
What am I doing wrong?
Thank you

MQTT client terminates without subscribing

I have set-up MQTT subscription as shown here:
package com.mqttW.demo;
import java.text.SimpleDateFormat;
import java.util.*;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.json.*;
public class WSync implements MqttCallback {
private String BROKER_URL = "";
private String PROTOCOL = "tcp://";
private String PORT = "1883";
private String TOPIC_ROOT_UNCNF = "/P/uncnf/";
private String TOPIC_ROOT_CNF = "/P/cnf/";
private DbOperations dbo = new DbOperations();
public void setBrokerUrl() {
this.BROKER_URL = PROTOCOL + System.getenv("BROKER_DNS") + ":" + PORT;
}
public String getBrokerUrl() {
return this.BROKER_URL;
}
public void publishPayload(String wName, String txnType, String payload) {
String clientId = wName + "-PUB";
String broker = this.getBrokerUrl();
String topic = TOPIC_ROOT_UNCNF + txnType + "/" + wName;
try {
MqttClient w = new MqttClient(broker, clientId);
w.connect();
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(2);
w.publish(topic, message);
w.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
public void processTxns(String wName) {
this.setBrokerUrl();
String broker = this.getBrokerUrl();
String clientId = wName + "-SUB";
String topic = TOPIC_ROOT_CNF + wName + "/CR";
MemoryPersistence persistence = new MemoryPersistence();
try {
MqttConnectOptions c = new MqttConnectOptions();
c.setCleanSession(false);
MqttClient w = new MqttClient(broker, clientId, persistence);
w.connect(c);
w.setCallback(this);
w.subscribe(topic, 2);
System.out.println(w.getServerURI() + " " + w.getClientId() + " " + w.isConnected());
} catch (MqttException e) {
e.printStackTrace();
}
}
#Override
public void connectionLost(Throwable arg0) {
System.out.println("Connection lost at : " + new SimpleDateFormat("yyyy-MM-dd.HH:mm:ss").format(new java.util.Date()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
// TODO Auto-generated method stub
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String s = new String(message.getPayload());
System.out.println(s);
}
}
The class with this method does implement MqttCallback. The System.out.println shows the broker URL, client ID and connected status (true) correctly.
So, what I am not getting is, why does the code terminate? Why is the subscription not set-up to listen for messages?

Pcap4j packet capture on loopback doesn't differentiate between Incoming and Outgoing packets

I am writing a simple packet capture & processing engine for my project using pacp4j. Below is the code that I am using to capture packets but when I use it to capture ONLY incoming packets on loopback address it gives me both outgoing and incoming packets.
How can I differentiate between incoming and outgoing packets on loopback address?
public class PacketListner {
int packet_count = 0;
private static final String READ_TIMEOUT_KEY
= PacketListner.class.getName() + ".readTimeout";
private static final int READ_TIMEOUT
= Integer.getInteger(READ_TIMEOUT_KEY, 10); // [ms]
private static final String SNAPLEN_KEY
= PacketListner.class.getName() + ".snaplen";
private static final int SNAPLEN
= Integer.getInteger(SNAPLEN_KEY, 65536); // [bytes]
private static final String TIMESTAMP_PRECISION_NANO_KEY
= PacketListner.class.getName() + ".timestampPrecision.nano";
private static final boolean TIMESTAMP_PRECISION_NANO
= Boolean.getBoolean(TIMESTAMP_PRECISION_NANO_KEY);
public int sniff() throws PcapNativeException, NotOpenException {
PcapNetworkInterface nif = null;
try {
nif = new NifSelector().selectNetworkInterface();
} catch (IOException e) {
e.printStackTrace();
}
if (nif == null) {
return -1;
}
System.out.println(nif.getName() + "(" + nif.getDescription() + ")");
PcapHandle.Builder phb
= new PcapHandle.Builder(nif.getName())
.snaplen(SNAPLEN)
.direction(PcapHandle.PcapDirection.IN)
.promiscuousMode(PcapNetworkInterface.PromiscuousMode.PROMISCUOUS)
.timeoutMillis(READ_TIMEOUT);
if (TIMESTAMP_PRECISION_NANO) {
phb.timestampPrecision(PcapHandle.TimestampPrecision.NANO);
}
PcapHandle handle = phb.build();
while (true) {
Packet packet = handle.getNextPacket();
if (packet != null) {
if (packet.contains(IpV4Packet.class) &&
(packet.contains(TcpPacket.class) || packet.contains(UdpPacket.class))) {
IpV4Packet pkt = packet.get(IpV4Packet.class);
if (packet.contains (TcpPacket.class)) {
TcpPacket tcpPkt = packet.get(TcpPacket.class);
System.out.println(pkt.getHeader().getSrcAddr() + ":" + tcpPkt.getHeader().getDstPort());
}
else {
UDpPacket udpPkt = packet.get(UDpPacket.class);
System.out.println(pkt.getHeader().getSrcAddr() + ":" + udpPkt.getHeader().getDstPort());
}
}
packet_count++;
}
}
}
}

JSch with Executor

I am having issues running multiple SSH jobs (using JSch) with ExecutorService.
When running a single job, they execute as expected. However, when I attempt to run multiple jobs, only the first job executes fully. I have changed the thread pool to use only 1 thread, thinking that somehow its a port issue but it still doesn't work correctly. Any help will be appreciated.
ExecutorService ex = Executors.newFixedThreadPool(4);
Set<Future<Task>> set = new HashSet<Future<Task>>();
for (int i = 0; i < tasks.size(); i++) {
Task task = tasks.get(i);
creds.setHostName(task.getFirewall().getAddress());
System.out.println("Task(" + i + ")=" + task);
Callable<Task> worker = new SSH.SSHWorker(creds, task, i);
ex.submit(worker);
}
Here is the SSH
public class SSH {
LoginCredentials creds;
//ChannelExec channelExec;
ChannelExec channelExec;
BufferedReader consoleOutput;
Session session;
InputStream is;
UI ui;
String output = "";
// String command;
public boolean debug = false;
public SSH(LoginCredentials creds, String command) throws JSchException, IOException {
// System.out.println("NEW SSH");
this.creds = creds;
consoleOutput = new BufferedReader(new InputStreamReader(System.in));
ui = new UI();
this.connect();
Channel channel = session.openChannel("exec");
this.sendCommand(channel, command);
}
public String getOutput() {
return output;
}
public class UI extends MyUserInfo {
String message;
#Override
public void showMessage(String message) {
this.message = message;
super.showMessage(message); //To change body of generated methods, choose Tools | Templates.
}
#Override
public String getMessage() {
return this.message;
}
}
private void sendCommand(Channel channel, String command) throws IOException, JSchException {
this.channelExec = (ChannelExec) channel;
this.channelExec.setCommand(command);
//channel.setInputStream(null);
channel.setOutputStream(System.out);
this.is = channel.getInputStream();
channel.connect();
byte[] buffer = new byte[1024];
while (channel.getExitStatus() == -1) {
//System.out.println("Here 1.1");
while (is.available() > 0) {
//System.out.println("Here 1.2");
int i = is.read(buffer, 0, 1024);
//System.out.println("i= " + i);
if (i < 0) {
System.out.println("breaking");
break;
}
String string = new String(buffer, 0, i);
output = output.concat(string);
//System.out.println("output= "+output);
if (string.contains("Command authorization failed")) {
channel.disconnect();
break;
}
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
}
is.close();
channel.disconnect();
this.session.disconnect();
}
private void connect() throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(creds.getUser(), creds.getHostName(), 22);
session.setTimeout(0);
session.setPassword(creds.getPassword());
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setUserInfo(ui);
session.connect();
System.out.println("Connected in SSH");
}
public static class SSHWorker implements Callable {
private LoginCredentials lc;
private Task t;
private int thread;
public SSHWorker(LoginCredentials creds, Task task, int thread) {
this.t = task;
lc = creds;
this.thread = thread;
System.out.println("Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
}
#Override
public Task call() throws JSchException, IOException {
System.out.println("Doing Call For: Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
String enablepassword1 = (String) lc.getEnablePassword().get(0);
SSH ssh = new SSH(lc, t.getSSHCommand(enablepassword1));
this.t.setTaskResult(ssh.getOutput());
return t;
}
}
}
The output is Here (IP addresses have been changed)
In your loop that creates the tasks, you use only one instance of LoginCredentials. So all tasks share the instance. In the loop, you overwrite the hostname in each iteration. So in the end the LoginCredentials refers to the hostname of the last task. So all tasks connect to that host.
Just to do not pass the hostname via LoginCredentials and use task.getFirewall().getAddress() directly when creating the JSch session:
SSH ssh = new SSH(lc, t.getSSHCommand(enablepassword1), task.getFirewall().getAddress());
...
public SSH(LoginCredentials creds, String command, String hostname)
{
...
this.connect(hostname);
}
...
private void connect(String hostname) throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(creds.getUser(), hostname, 22);
...
}

Categories

Resources