WebSphere wsadmin script to create custom properties for JMS provider - websphere

I have created a custom JMS provider in WebSphere 8. Now I want to add custom properties to this JMS provider, but the usual procedure does not work.
I created the JMS provider with the following commands (Jython):
server = AdminConfig.getid('/Cell:cell/Node:node0/Server:appserver/')
jms_provider = AdminConfig.create('JMSProvider', server, '[[name "ActiveMQ"] [externalInitialContextFactory "org.apache.activemq.jndi.ActiveMQWASInitialContextFactory"] [externalProviderURL "tcp://10.1.1.1:61616"]]')
Usually, I would get a custom property set in order to popultate it, but I just get "None":
wsadmin> print(AdminConfig.showAttribute(jms_provider, 'propertySet'))
(None)
Creating a new one does not work either:
wsadmin> AdminConfig.create('J2EEResourceProperty', jms_provider, [])
WASX7015E: Exception running command: "AdminConfig.create('J2EEResourceProperty', jms_provider, [])"; exception information:
com.ibm.ws.scripting.ScriptingException: WASX7129E: Cannot create objects of type "J2EEResourceProperty" in parents of type "JMSProvider"
How can I create the initial property set for a JMS provider?

Solution was to create a J2EEResourcePropertySet instead of a J2EEResourceProperty:
props = AdminConfig.create('J2EEResourcePropertySet', jms_provider, [])
AdminConfig.create('J2EEResourceProperty', props, '[[name "java.naming.queue.Queue1"] [value "Queue1"]]')

Related

Accessing JNDI Datasource using Container Managed Authentication Alias in Websphere (Spring + Ibatis/Mybatis)

I am using WebSphere 8.5.5.18.
As of now I'm using Component-Managed Authentication Alias for my DataSource. But I want to use Container-Managed instead. When I just change the Security settings in Data Sources → Security settings I am getting error in logs. It is unable to fetch records.
Exception Stacktrace:
Check the SQL Statement (preparation failed).
--- Cause: java.sql.SQLException: [jcc][t4][10205][11234][3.72.54] Null userid is not supported. ERRORCODE=-4461, SQLSTATE=42815 DSRA0010E: SQL State = 42815, Error Code = -4,461
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:271)
Basically the database is not being accessed properly when settings are changed from Component-Managed Authentication to Container-Managed Authentication alias.
When I run with Component-Managed Authentication, its working fine.
Does changing security setting to Container Managed Authentication alias, require some other/additional setting/changes? Or do I need to change my underlying Spring ibatis code to make it work?
Any help on configuring/implementing Container-Managed Authentication Alias in websphere would be appreciated.
Container-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source with a resource reference that specifies the resource authentication as container or leaves resource authentication unspecified, in which case it defaults to container.
Component-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source without a resource reference, or uses a resource reference that specifies the resource authentication as application.
Here are some examples of resource references that use container authentication:
// resource injection can be used on a web component (servlet) or ejb component
#Resource(name = "java:comp/env/jdbc/ds1ref", lookup = "jdbc/ds1", authenticationType = Resource.AuthenticationType.CONTAINER)
DataSource ds1;
#Resource(name = "java:comp/env/jdbc/ds2ref", lookup = "jdbc/ds2")
DataSource ds2;
...
// code that looks up one of the above resource references
DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1ref");
Here is an example of a resource reference defined within a web.xml deployment descriptor:
<resource-ref>
<res-ref-name>java:comp/env/jdbc/ds3ref</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<lookup-name>jdbc/ds3</lookup-name>
</resource-ref>
If third party code, such as Spring, is looking up a data source on your behalf and you would like it to use container authentication, you will need to define a resource reference with container managed authentication, such as shown above in the examples, and supply its resource reference name to the third party software in place of however you are doing so currently. If you are unsure where this is done, it might help to search for occurrences of the configured JNDI name of the WebSphere data source within the application.

Solace NIFI JMSConnectionFactoryProvider

I am trying to connect to Solace Queues on a VPN different then default using Appache NIFI ConsumeJMS Processor. When I try to enable the JMSConnectionFactoryProvider I get the following error:
JMSConnectionFactoryProvider Failed to invoke #OnEnabled method due to
java.lang.IllegalStateException: java.lang.IllegalStateException:
Failed to load and/or instantiate class
'com.solacesystems.jms.SolConnectionFactory'
The NIFI JMSConnectionFactoryProvider provides a generic service to create vendor specific javax.jms.ConnectionFactory implementations. ConnectionFactory can be served once this service is configured successfully.
Why is NIFI Unable to find the class within the Solace JMS API Jar files?
----- Update --------
Solace JMS API 10.1.0 now contains an zero argument default constructor, and integration with NiFi is now possible.
Here is an example configuration:
Controller:
The MQ ConnectionFactory Implementation is set to com.solacesystems.jms.SolConnectionFactoryImpl.
ConsumeJMS Processor:
Username field can also take the form of "myUsername#myMessageVPN".
----- Original -------
The problem here is that Apache NiFi is not using a portable method of creating a ConnectionFactory. It is trying to create a ConnectionFactory by calling an zero argument default constructor, but there's no guarantee that one exists.
// From https://github.com/apache/nifi/blob/master/nifi-nar-bundles/nifi-jms-bundle/nifi-jms-cf-service/src/main/java/org/apache/nifi/jms/cf/JMSConnectionFactoryProvider.java
private void createConnectionFactoryInstance(ConfigurationContext context) {
String connectionFactoryImplName = context.getProperty(CONNECTION_FACTORY_IMPL).evaluateAttributeExpressions().getValue();
this.connectionFactory = Utils.newDefaultInstance(connectionFactoryImplName);
}
Note that there's an entry over at NiFi's JIRA https://issues.apache.org/jira/browse/NIFI-2701 to "Add JNDI Factory support for JMS ConnectionFactory service". (The initial description of that entry is a bit confusing, but the comments are clearer.)
At this point, Solace only supports the creation of the ConnectionFactory through the standard JNDI lookup - javax.naming.InitialContext.lookup() and through Solace's proprietary method - SolJmsUtility.createConnectionFactory().
Solace will investigate whether it is feasible to implement a zero argument default constructor for the ConnectionFactory.
A JNDI connection provider is developed and published at http://dev.solace.com/integration-guides/nifi/. For people that are interested in this provider, it is worthwhile finding out.

Connecting to a JMS Queue using a file system based Initial Context

Using Websphere MQ Explorer, I have created a new file system based initial contextfor JMS. Using the new initial context, I have created a JMS queue to connect to an existing queue (currently accessed using a non java based framework).
Within the application code, I can succesfully connect to the context, as follows:
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
properties.put(Context.PROVIDER_URL, "file:C://folder-name//");
try {
val ctx = new InitialContext(properties)
Next, I create a QueueConnectionFactory:
val qcf = (ctx.lookup("com.ibm.mq.jms.MQQueueFactory")).asInstanceOf[QueueConnectionFactory]
However, this throws the following exception:
javax.naming.NameNotFoundException: com.ibm.mq.jms.MQQueueFactory
at com.sun.jndi.fscontext.RefFSContext.getObjectFromBindings(RefFSContext.java:400)
at com.sun.jndi.fscontext.RefFSContext.lookupObject(RefFSContext.java:327)
at com.sun.jndi.fscontext.RefFSContext.lookup(RefFSContext.java:146)
at com.sun.jndi.fscontext.FSContext.lookup(FSContext.java:127)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
I used com.ibm.mq.jms.MQQueueFactory as the connection factory name, because in the .bindings file, there is the following line:
MY.QUEUE/FactoryName=com.ibm.mq.jms.MQQueueFactory
But that throws an exception.
Where would the correct connection factory name be defined?
Thanks
Problem solved - under the file based context (under JMS Administered Objects), a Connection Factory must be defined.

How to test WSO2 Message Broker with JMeter

I'm having some issues getting JMeter to work against the WSO2 Message Broker using the JMS Publisher. I had JMeter working against ActiveMQ but I'm still new with the tool.
I copied the client libraries over to jmeter wso2mb-2.0.1\client-lib to apache-jmeter-2.9\lib
andes-client-0.13.wso2v4.jar
geronimo-jms_1.1_spec-1.1.0.wso2v1.jar
Settings:
Context Factory : org.wso2.andes.jndi.PropertiesFileInitialContextFactory
Provider Url : amqp://admin:admin#clientID/carbon?brokerlist='tcp://localhost:5672'
Connection Factory : qpidConnectionfactory
...also tried several other values
Destination: dynamicQueues/test
The error I'm getting is on the Connection Factory field.
I've tried several different values all of which generate a naming error like there is a setting missing.
When I leave it blank I get:
javax.naming.NamingException: Expected javax.jms.ConnectionFactory, found org.wso2.andes.jndi.ReadOnlyContext
Does anyone know what I'm missing here?
Suspect it's something simple.
I found the problem.
In short the qpid context factory org.wso2.andes.jndi.PropertiesFileInitialContextFactory does not use fields the same way as the activeMQ context factory org.apache.activemq.jndi.ActiveMQInitialContextFactory.
While ActiveMQ allows you to not use a separate properties file with Jmeter, Qpid does not.
Jmeter JMS Publisher:
Context Factory : org.wso2.andes.jndi.PropertiesFileInitialContextFactory
Provider Url : nameOfYouFile.properties
Connection Factory : qpidConnectionfactory
Destination : <QueuePropertyName>
nameOfYouFile.properties:
connectionfactory.qpidConnectionfactory = amqp://admin:admin#clientID/carbon?brokerlist='tcp://localhost:5672'
queue.JMeterQueue = JMeterQueue
Reference:
Qpid Wiki

Unit-Of-Order in WLI JMSControl

One of our clientes is intented to use the Unit-Of-Order Weblogic Server Feature (UOO).
Everything is OK using UOO in pure java code for sending JMS Messages with custom UOO Names, as well as propagating the UOO Name in Aqualogic Service Bus from the Proxy Service to a Business Service (both using JMS as the transfer protocol).
However, using UOO in Weblogic Integration along with WLI JMSControl, does no work properly.
Consider this code:
#com.bea.control.JMSControl.Properties(value = {
#com.bea.control.JMSControl.PropertyValue(name = "JMS_BEA_UnitOfOrder", value = "MyUOONameFromWLI"),
#com.bea.control.JMSControl.PropertyValue(name = "MyCustomProperty", value = "MyCustomValue") })
public void sendTextMessage(String payload);
It sends the property MyCustomProperty to the JMS consumer, but the property JMS_BEA_UnitOfOrder - related to UOO Name - is ignored. The default User-generated UOO name is used instead.
So, how to customize my UOO Name using Weblogic JMSControl?
I've found that it has no support!

Resources