Is there a way to set JMS to use SSL/TLS connecting to IBM MQ? - ssl

We have a Java application that uses JMS to communicate with IBM MQ. A part of their requirement is now to use TLS. Is there a way to do this? The parameters they were expecting to add are:
sslCipherSuite
hostname
port
channel
Is there any system environment property that we can set to JMS for this parameters?
the current code uses
import javax.jms.ConnectionFactory;
and we use to a config file to set system env variables.
environment.setProperty("java.naming.factory.initial", this.config.get("JMS_JndiContextFactory"));
this.setJndiExtraParameters(environment, this.config.get("JMS_JndiExtraParameters"));
while (!this.state.atLeast(State.GOT_FACTORY) && iterator.hasNext()) {
environment.setProperty("java.naming.provider.url", this.urlUsed = iterator.next());
try {
JmsClient.LOGGER.debug("Looking up connection factory");
this.factory = (ConnectionFactory)new InitialContext(environment).lookup(this.config.get("JMS_FactoryName"));
this.state = State.GOT_FACTORY;
}
im thinking if there is a way to set only another set of system properties instead of using
MQConnectionFactory
so we don't have to change something in the code?
i posted a similar question , reposted it because of lack of clarity

Related

Karate-gatling: set local addresses

I have simple karate feature file for testing an API, and I want to use this feature file for load testing. Thus I am using Gatling to execute the karate feature file: https://github.com/intuit/karate/tree/master/karate-gatling
However, when I fire up multiple users, I want to submit the requests with different ip alias that I have configured.
Using Gatling, I could use localAddress to bind to the socket
val protocol = http.localAddresses(ip)
But in Karate-Gatling, karateProtocol is used instead
val protocol = karateProtocol()
And the readme states that "Karate is responsible for making HTTP requests while Gatling is only measuring the timings and managing threads".
This means that the HTTP requests and localAddress bindings cannot be changed through Gatling, but I am wondering if there is a workaround through Karate so that different ip alias can be used for different requests.
This sounds like a feature request is needed to tell the HTTP client (Apache for e.g.) to use a local-address.
It would be great if you can help contribute and test, one way to set the localAddress would be in the code here:
RequestConfig.Builder configBuilder = RequestConfig.custom()
.setCookieSpec(LenientCookieSpec.KARATE)
.setConnectTimeout(config.getConnectTimeout())
.setSocketTimeout(config.getReadTimeout());
String localIp = "1.2.3.4";
try {
InetAddress localAddress = InetAddress.getByName(localIp);
configBuilder.setLocalAddress(localAddress);
} catch (Exception e) {
context.logger.error("failed to resolve local address: {}", localIp);
}

NServiceBus 6.2 losing messages with RabbitMQ

I'm using NSB version6.2 and RabbitMQ version 4.
I'm using RabbitMQTransport. My RabbitMQ server is in a virtual machine in Azure. when I send messages, sometimes I'm losing messages without any error.
this is my NService Bus configuration.
EndpointConfiguration config = null;
string endpointName = ConfigurationManager.AppSettings.Get("NServiceBus.EndpointName");
config = configEndPoint.IsNullOrDefault() ? new EndpointConfiguration(endpointName) : configEndPoint;
int maximumConcurrencyLevel = ConfigurationManager.AppSettings.Get("NServiceBus.TransportConfig.MaximumConcurrencyLevel").ToInt();
config.LimitMessageProcessingConcurrencyTo(maximumConcurrencyLevel);
int numberOfRetries = ConfigurationManager.AppSettings.Get("NServiceBus.TransportConfig.NumberOfRetries").ToInt();
var recoverability = config.Recoverability();
recoverability.Immediate(
customizations: immediate =>
{
immediate.NumberOfRetries(numberOfRetries);
});
DefaultFactory defaultFactory = LogManager.Use<DefaultFactory>();
defaultFactory.Directory(this.DatabusDirectory);
defaultFactory.Level(LogLevel.Error);
config.IdealinkJsonSerializer();
config.UsePersistence<InMemoryPersistence>();
config.SendFailedMessagesTo("error");
config.AuditProcessedMessagesTo("audit");
// configure transport
config.UseTransport<RabbitMQTransport>().Transactions(TransportTransactionMode.ReceiveOnly);
var endpointInstance = Endpoint.Start(endpointConfiguration).GetAwaiter().GetResult();
Configuration of your endpoint looks fine with an exception of persistence.
Persistence is used for features that are not supported by the underlying transport natively. For RabbitMQ, there is not native mechanism to send delayed messages. Until version 4.3 persistence was used to store timeouts. If you use InMemoryPersistence, none of the information will be retained after endpoint restarts. Timeouts are needed for Recoverability feature, specifically delayed retries. From version 4.3 and above, persistence is not required for timeouts, but InMemoryPersistence should still not be used. You can chose other persistences based on technology and scenario at hand.
Please note that version 4.0.0 is not under supported versions. You should update to 4.3.x or 4.4.x and verify the behavior to see if you notice a message loss or not. In case you still losing messages, I suggest providing more details such as log file and handler code. If you can't share that publicly, submit a support case.
Hope that helps.

Akka.Net Remoting Configuration + Association questions

we just upgraded Akka.Net to 1.1.3 from 1.0.7 and noticed that remoting HOCON had a few new properties such that the following works on Azure, but doesn't on private dedicated servers (say a GoDaddy box):
akka {
actor { provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" }
remote {
helios.tcp {
port = 0
hostname = 0.0.0.0
dns-use-ipv6 = false
public-hostname = localhost
enforce-ip-family = true
}
}
}
And the following works well on dedicated servers, but not on Azure:
akka {
actor {
provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
}
remote {
helios.tcp {
port = 0
hostname = 0.0.0.0
dns-use-ipv6 = false
public-hostname = localhost
enforce-ip-family = false
}
}
}
From the documentation in the change logs that I found, it appears that enforce-ip-family is a setting which when set to TRUE would allow forcing a client to use IPv6 by setting dns-use-ipv6 to true.
Is this a correct interpretation on my part? Is there some documentation regarding these settings that we could read?
Also, let's say that I wanted to use IPv6 on Azure, what would the server configuration be? Is this even something that I could control?
I also noticed something with the new version that I hadn't noticed before, overnight, I started getting these exceptions:
Tried to associate with unreachable remote address
[akka.tcp://TestActorSystem#localhost:51675]. Address is now gated for
5000 ms, all messages to this address will be delivered to dead
letters. Reason: [No connection could be made because the target
machine actively refused it.
We hadn't seen these errors before and it really doesn't look like there's a specific reason on this before the first one started. Has anyone else experienced this? Could any one shed some light on what I could do to gracefully resolve this situation? A critical piece of functionality stopped working because of this issue and we're trying to figure out how to best address it.
Please pardon my lack of expertise on Akka 1.1.3 but I think I had it all figured out until I inadvertently upgraded the nuget package and had a rude awakening :)
Thank You,
Anup

WebSphere MQ 6.0: Can't switch from non-durable to durable

When I switch from non-durable to durable topic subscriber, I am unable to look up the topic name that I could read before (using JNDI).
It gives an error in the admin console as the topic is being looked up:
An error occurred during activation of changes, please see the log for details.
ERROR: Could not activate itft-jmsmodule!ITFT-JMS-1#ItftTopic
The Messaging Kernel ITFT-JMS-1 has not yet been opened
I am using Oracle WebLogic Server Administrative Console to set up the WebSphere queue. On the console, I made these changes:
For the Persistent Stores, On the Configuration tab, Added a file store called ItftFileStore
For the Persistent Stores, On the Configuration tab, Added a directory.
For the JMS Servers, On the Configuration -> General tab, Changed the Persistent Store to ItftFileStore
For the JMS Servers, On the Configuration -> General tab -> Advanced, Checked the Store Enabled field.
For the ItftTopic, Configuration -> Override tab, Changed Delivery Mode Override to Persistent.
This is the code which I am running. There are some comments on the pertinent lines.
public void start() throws Exception {
try {
LOG.info("Starting the FC MQ message consumer / listener ...");
InitialContext initialContext = getInitialContext();
topicConnectionFactory = (TopicConnectionFactory) initialContext.lookup(jmsFactory);
topicConnection = topicConnectionFactory.createTopicConnection();
topicConnection.setClientID(clientId);
LOG.info("1"+topicConnection.getClientID());
topicSession = topicConnection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
LOG.info("2"+topicConnection.getClientID());
//topicConnection.setExceptionListener(connectionExceptionListener);
jmsTopic = (Topic) initialContext.lookup(topic); // Error being thrown here
LOG.info("3"+topicConnection.getClientID());
//topicSubscriber = topicSession.createSubscriber(jmsTopic); // Works as a non-durable subscriber
topicSession.createDurableSubscriber(jmsTopic,subscriberName);
LOG.info("4"+topicConnection.getClientID());
topicSubscriber.setMessageListener(messageListener);
topicConnection.start();
The fundamental aspect of the problem is that you are connecting WebLogic to a Websphere JMS topic, this has become clear with the last edit of your question but it is not clear whether you are using WebLogic Messaging Bridge or not. The Messaging Bridge is the proper way of configuring a foreign JMS server in WebLogic. I suggest reading this FAQ and this how-to that is specific for Websphere.

How to manually set/propagate security context information e.g. Principal for JBoss 7 (over JBoss remoting 2)

I'm using jboss remoting 2.5.4.SP3 to provide remote access to EJBs in a JBoss 7.1 server from both a web app and other JBoss instances. I'm doing it manually because of issues with remote EJB access in JBoss 7.1, specifically (but not only) the inability to access the same (interface) bean on multiple servers simultaneously. I'm using remoting2 because remoting3 has no documentation.
I have remoting working using TransporterHandle/TransporterClient using the socket transport, but in methods called via this remote connection, the server wants to lookup the principal from the ejbContext. I can't find a way to manually set the principal, or other contextual security/identity information. At the limit I'd be happy just to set the principal when the ejb method is invoked - all incoming calls are to local EJB3 beans - or even to set it specifically for the EJBContext.
I've found a lot of information regarding Spring (which I'm not using), but nothing seems to match my particular context.
And now, the correct way to do this:
On the client side I get the security context and package up the security domain and subject info for transport to the server along with the invocation. The SecurityDomain is a String and SubjectInfo is serializable:
Map m = new HashMap();
SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
if (securityContext != null) {
m.put("SUBJECT-INFO", securityContext.getSubjectInfo());
m.put("SECURITY-DOMAIN", securityContext.getSecurityDomain());
}
response = remotingClient.invoke(request, m);
The map m gets sent with the invocation over jboss remoting. On the server side, I extract the security information and set the context for the invocation like this:
SecurityContext oldContext = SecurityContextAssociation.getSecurityContext();
SubjectInfo si = (SubjectInfo) invocation.getRequestPayload().get("SUBJECT-INFO");
String domain = (String) invocation.getRequestPayload().get("SECURITY-DOMAIN");
if (si != null) {
SecurityContext sc = new JBossSecurityContext(domain);
sc.setSubjectInfo(si);
SecurityContextAssociation.setSecurityContext(sc);
}
try {
return super.invoke(invocation);
} finally {
SecurityContextAssociation.setSecurityContext(oldContext);
}
Works like a charm!
Have a look at the jboss-ejb-client.properties. There is also a quickstart example using a remote client to lookup an EJB.
I've solved my underlying problem, although not in the general way I was hoping for.
I put a servlet filter on all incoming requests, recording request.getUserPrincipal in a thread local. I can then access this in non-EE code and find the principal making the request. Then when I make call to my app server I use JBoss Remoting's ability to attach metadata to each invocation to pass the Principal over the wire. I had to copy the TransporterClient to do this because it's private constructors et al don't allow for overriding the functionality required to attach per-request metadata (as opposed to per-connection). On the server side I take the incoming Principal and set it into a thread local. Then, in subsequent code that accesses EJBContext.getCallerPrincipal I also lookup the incoming Principal from the thread local, and if that isn't null (hence we are in a remote EJB call), I use that if the caller principal is anonymous. If it's not anonymous then it must have been set in some way after the incoming call, so I ignore the incoming Principal in that case.
All in all, a much more specialised solution than I was hoping for, and it doesn't shed any light on how I can do generic context propagation in JBoss 7.1 over the wire.