I'm having a strange warning when I try to use Hazelcast-based implementation of JCache (i.e. JSR 107) as follows (original sample code):
// Explicitly retrieve the Hazelcast backed javax.cache.spi.CachingProvider
CachingProvider cachingProvider = Caching.getCachingProvider(name);
// Retrieve the javax.cache.CacheManager
CacheManager cacheManager = cachingProvider.getCacheManager("com.hazelcast.cache.impl.HazelcastCachingProvider");
Here is the logged message:
oct. 30, 2014 5:17:59 PM com.hazelcast.cache.impl.HazelcastCachingProvider
WARNING: Could not load client CachingProvider! Fallback to server one... java.lang.ClassNotFoundException: com.hazelcast.client.cache.impl.HazelcastClientCachingProvider
Why it si trying to load HazelcastClientCachingProvider will I asked for com.hazelcast.cache.impl.HazelcastCachingProvider. Am I using the wrong JCache provider?
HazelcastCachingProvider is just a delegate to automatically choose either client based or server bases CachingProvider.
For recent 3.4 SNAPSHOTS HazelcastCachingProvider also was moved to com.hazelcast.cache.HazelcastCachingProvider. For the new documentation please see the just drafted documentation version for 3.4: https://github.com/hazelcast/hazelcast/blob/master/hazelcast-documentation/src/JCache.md
You'll see it got waaaaaaay longer :)
Related
I want to send a scheduled message to the Azure Service Bus with JMS.
My code is based on org.apache.qpid.jms.message.JmsMessage. I've found one solution for the given problem, but it uses org.apache.qpid.proton.message.Message which has .getMessageAnnotations(), which allows to edit message annotations and add some properties that are correctly recognized and processed by Azure Service Bus. My message impl is missing that method.
What I've found in offical docs and implementations in node.js, to schedule a message with Azure Service Bus, you need to send header BrokerProperties/brokerProperties which has valid json.
Other headers/properties will be marked as Customer properties and ignored by Azure Service Bus.
official azure docs about JMS says that setting ScheduledEnqueueTimeUtc is not officialy supported by JMS API. But it can be achieved manually by setting property.
So when I send message to the queue, then I can post process it in lambda and set some properties:
jmsTemplate.convertAndSend(queue, payload, message -> {
var date = Date.from(ZonedDateTime.now(ZoneId.of("UTC")).plus(delay, ChronoUnit.MILLIS).toInstant());
var brokerProps = Map.of("ScheduledEnqueueTimeUtc", date.toGMTString());
message.setStringProperty(
"brokerProperties",
objectMapper.writeValueAsString(brokerProps)
);
return message;
});
And it doesn't work. The message arrives at the queue, but when I try to peek it on the Service Bus Explorer on Azure it throws error in the browser console and the operation lasts forever. I guess setting that property brokerProperties does some impact for Service Bus.
I have also tried to send a map with date as a string (with date format that is used by the Azure) like "ScheduledEnqueueTimeUtc", "Thu, 25 Mar 2021 12:54:00 GMT", but it also is recognized as an error by Service Bus (peeking lasts forever and error in the browser console is thrown).
I've tried to set string properties like x-opt-scheduled-enqueue-time or x-ms-scheduled-enqueue-time which I've found in other threads on SO, but none of them works with my example.
I saw that Microsoft gives some library for Java to communicate with Azure Service Bus, but I need to maintain independency from the Cloud provider in my code and don't include any additional libs.
Is there any example of using JMS message implementation from the package org.apache.qpid.jms.message.JmsMessage to set BrokerProperties for Azure Service Bus?
My team is currently facing the same issue.
We found that the ScheduledEnqueueTimeUtc property is set in the MessageAnnotationsMap. Unfortunately, the org.apache.qpid.jms.provider.amqp.message.AmqpJmsMessageFacade, which is used by JMS, has set the getter and setter to package private. But we found out that you can use the setTracingAnnotation(String key, Object value) Method.
Example:
public void sendDelayedMessage() {
final var now = ZonedDateTime.now();
jmsTemplate.send("test-queue", session -> {
final var tenMinutesFromNow = now.plusMinutes(10);
final var textMessage = session.createTextMessage("Hello Service Bus!");
((JmsTextMessage) textMessage).getFacade().setTracingAnnotation("x-opt-scheduled-enqueue-time", Date.from(tenMinutesFromNow.toInstant()));
return textMessage;
});
log.info("Sent at: " + now);
}
Proof:
Big Thanks to my teammate!!
Trying to use WOLA direct from a webapp in Liberty to CICS. Using same CICS region successfully with z/OS Connect V2 (zCEE). With Liberty, I have configured:
<featureManager>
<feature>servlet-3.1</feature>
<feature>jndi-1.0</feature>
<feature>jaxrs-1.1</feature>
<feature>zosLocalAdapters-1.0</feature>
</featureManager>
and
<!-- WOLA group to which others register -->
<zosLocalAdapters wolaGroup="GROUP" wolaName2="LIBRTOLA" wolaName3="WOLA3" />
<connectionFactory id="wolaCF" jndiName="eis/ola">
<properties.ola RegisterName=CICSMLAW/>
</connectionFactory>
<resourceAdapter location="/usr/lpp/IBM/zosconnect/v2r0/wlp/lib/ola.rar"/>
In the messages.log, I see good and bad items there:
CWWKB0103I: Authorized service group WOLA is available The WebSphere Optimized Local Adapter channel registered with the Liberty profile server using the following name: GROUP LIBRTOLA WOLA3
and the bad:
com.ibm.ws.app.manager.AppMessageHelper E CWWKZ0013E: It is not possible to start two applications called ola.
So the failure on registration: Requestlgth: 97
Requestparms data 1: BBOC START_SRVR RGN=CICSMLA DGN=GROUP NDN=LIBRTOLA
Requestparms data 2: SVN=WOLA3 SVC= MNC=1 MXC=10 TXN=N SEC=N REU=N
Requestparms data 3:
Processing a START SERVER request.
Starting WAS adapters Server task ...
Server transaction id will be: BBO$
Link transaction defaults to: BBO#
Service name will be:
Trace TDQ: BBOQ
Processing a REGISTER API request.
Register name: CICSMLA string len: 7
WAS Daemon: GROUP WAS Node: LIBRTOLA WAS Server: WOLA3
Min. connections: 1
Max. connections: 10
Transactional: N string len: 1
Security propagation: N string len: 1
Invoking OLA Register API for CICSMLA .
on with the Liberty profile server was not successful. The return code is 8, and the reason code 8.
And the failure in the JNDI call:
Context ctx = new InitialContext();
ConnectionFactory cf = (com.ibm.ws390.ola.jca.ConnectionFactoryImpl)ctx.lookup("java:comp/env/eis/ola");
Results in error:
[err] javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:comp/env/eis/ola
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:356) [err] at [internal classes]
[err] at javax.naming.InitialContext.lookup(InitialContext.java:428)
[err] at com.ibm.ctl.bank.impls.CTLBankWolaImpl.(CTLBankWolaImpl.java:51)
[err] at com.ibm.ctl.bank.web.OLTPBankRest.setImpl(OLTPBankRest.java:235)
Thanks
You have a lot going on here.
I'm not sure why you're starting ola.rar from the z/OS Connect v2 product, inside of a Liberty server. The zosLocalAdapters-1.0 feature already loads the ola.rar that ships with Liberty. You should remove the configuration from server.xml. That should resolve the CWWKZ0013E error.
You should see two CWWKB0103I messages in messages.log, one for WOLA (which you included) and one for CLIENT.WOLA. Please be sure you see both. It's possible you're on a very old version of Liberty that doesn't print the second CWWKB0103I message, so if this is true, please disregard that part.
I don't think you would have gotten this far without finding the WOLA configuration instructions for the Liberty server in the knowledge center, but here they are for other's benefits:
https://www.ibm.com/support/knowledgecenter/en/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/twlp_dat_enableconnector.html
OK next, I can't see your application to know whether you've got a resource-reference to a connection factory configured. I assume you do because you're doing a java:comp/env lookup. You do not need to cast to com.ibm.ws390.ola.jca.ConnectionFactoryImpl, and actually I highly recommend removing that since that is an internal class and subject to change at any time. It may be that the application class loader doesn't have access to that class, and that may be part of the problem.
Finally, you have a problem in CICS starting the link server. You are getting RC=8 RSN=8. A list of services and return/reason codes can be found here:
https://www.ibm.com/support/knowledgecenter/en/was_beta_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/rwlp_dat_olaapis.html
An 8/8 on BBOA1REG (register) indicates the register token is already in use. Basically, the RGN= name you picked is already in use. Are you sure there isn't a PLTPI transaction or something else in the CICS region that is already registered with that name? Perhaps try a different name just to see if it works, and if it does, maybe try BBOC LIST_SRVR to see what it is? It's difficult to say how it's getting started without knowing more about your system.
I hope this helps. Take care!
WARNING: JGRP000014: Discovery.timeout has been deprecated: GMS.join_timeout should be used instead
why am I getting this if it's not defined directly by me? at least I don't think it is, looks like we're using the GMS.join_timeout
Here's how this one is configured
log().info(
"Starting JChannel for Distributable Sessions config:{} with channel name of {}",
configString,
channelName
);
jChannel = new JChannel(new PlainConfigurator(configString));
jChannel.connect(channelName);
replicatedSessionIds = new ReplicatedHashMap<>( jChannel );
sessionIds = replicatedSessionIds;
if (! sessionDistributedTest )
{
replicatedSessionIds.start(TIME_OUT);
}
and the output of that log messsage
Starting JChannel for Distributable Sessions config:TCP(bind_addr=172.20.0.4;bind_port=7800;max_bundle_size=200000):TCPPING(timeout=3000;initial_hosts=dex.master[7800],dex.slave[7800];port_range=1):VERIFY_SUSPECT(timeout=1500):pbcast.NAKACK2(use_mcast_xmit=false;discard_delivered_msgs=true):pbcast.STABLE(stability_delay=1000;desired_avg_gossip=50000;max_bytes=400000):pbcast.GMS(print_local_addr=true;join_timeout=2000;view_bundling=true):pbcast.STATE_SOCK with channel name of Dex_SpringSecurity_Cluster_Dev
jgroups 3.6.13
You actually do define timeout in configString passed to the channel constructor: TCPPING.timeout.
I have 2 suggestions for you:
Switch to XML based configuration; plain-text configuration will not be supported any longer in 4.0
Use tcp.xml shipped with 3.6.13 and modify it according to you liking. Your config looks a bit dated.
while loading Map from external data source using MapLoader Hazelcast cluster(multicast discovery) gives error as
WARNING: [<IP>]:5702 [<cluster_name>] [3.8-EA] Received data format is invalid. (An old version of Hazelcast may be running here.)
com.hazelcast.nio.serialization.HazelcastSerializationException: Problem while reading DataSerializable, namespace: 0, id: 0, class: 'com.hazelcast.cluster.impl.JoinRequest', exception: com.hazelcast.cluster.impl.JoinRequest
at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.rethrowReadException(DataSerializableSerializer.java:178)
...
Caused by: java.lang.ClassNotFoundException: com.hazelcast.cluster.impl.JoinRequest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
I have tested this on hazelast 3.5.4 version .. It is working fine.
We can ignore this warning but not sure what is the impact of it. Also it floods the log.
The old and new versions of Hazelcast are not compatible in terms of multicast discovery since the internal protocol changed. That said, the new Hazelcast version cannot identify the old versions discovery packet.
Please change the multicast group according to the documentation found under: http://docs.hazelcast.org/docs/3.8-EA/manual/html-single/index.html#multicast-element
For those that may be running into this problem in an OSGi environment, you may be getting bit by a nuance of the com.hazelcast.util.ServiceLoader.findHighestReachableClassLoader() method sometimes picking the wrong class loader during Hazelcast initialization (as it won't always pick the class loader you set on the config). The following shows a way to work around that problem by taking advantage of Java's context class loader:
private HazelcastInstance createHazelcastInstance() {
// Use the following if you're only using the Hazelcast data serializers
final ClassLoader classLoader = Hazelcast.class.getClassLoader();
// Use the following if you have custom data serializers that you need
// final ClassLoader classLoader = this.getClass().getClassLoader();
final com.hazelcast.config.Config config = new com.hazelcast.config.Config();
config.setClassLoader(classLoader);
final ClassLoader previousContextClassLoader = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
return Hazelcast.newHazelcastInstance(config);
} finally {
if(previousContextClassLoader != null) {
Thread.currentThread().setContextClassLoader(previousContextClassLoader);
}
}
}
Using JClouds, up to version 1.6.x it was possible to access to the native EC2 provider API by using the following idiom:
AWSEC2Client ec2Client = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi());
Actually, I copied from the documentation page: http://jclouds.apache.org/guides/aws/
It turns out that in the latest release this method has been removed. Is there an alternative method/way to access to the provider specific features (security groups, key-pairs, etc)?
Unwrapping the API from the ComputeServiceContext
ComputeServiceContext context = ContextBuilder.newBuilder("aws-ec2")
.credentials("accessKey", "secretAccessKey")
.buildView(ComputeServiceContext.class);
ComputeService computeService = context.getComputeService();
AWSEC2Api ec2Api = context.unwrapApi(AWSEC2Api.class);
Building the API directly
AWSEC2Api ec2Api = ContextBuilder.newBuilder("aws-ec2")
.credentials("accessKey", "secretAccessKey")
.buildApi(AWSEC2Api.class);