I'm trying to browse messages in a topic using TopicBrowser. To call the correct createBrowser method that will return a TopicBrowser object, I need to cast my topicSession variable to AQjmsSession.
private InitialContext initialContext;
private TopicConnection topicConnection;
private TopicSession topicSession;
private Topic topic;
private TopicConnectionFactory topicFactory;
private TextMessage message;
private void initTopic(Context context, String topicName) throws NamingException, JMSException {
System.out.println("initializing the queue...");
topicFactory = (TopicConnectionFactory) context.lookup(JMS_FACTORY);
topicConnection = topicFactory.createTopicConnection();
//queueConnection.setExceptionListener(this);
topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
System.out.println("session created, lookup queue: " + topicName);
topic = (Topic)context.lookup(topicName);
System.out.println("done...");
}
private void readTopicMessage() throws JMSException {
int counter = 0;
System.out.println("Starting the subscriber");
TopicBrowser topicBrowser = ((AQjmsSession) topicSession).createBrowser(topic, SUBSCRIBER);
Enumeration msgs = topicBrowser.getEnumeration();
//topicConnection.start();
System.out.println("Topic started\n");
if (!msgs.hasMoreElements()) {
System.out.println("No messages in topic");
} else {
while (msgs.hasMoreElements()) {
System.out.println(">>> message count: " + ++counter);
Message message = (Message) msgs.nextElement();
System.out.println("MessageID: " + message.getJMSMessageID() + "\tPriority: " + message.getJMSPriority() + "\tDeliveryMode: " + message.getJMSDeliveryMode());
System.out.println("Timestamp: " + message.getJMSTimestamp() + "\tJMSDestination: " + message.getJMSDestination() + "\tReplyTo: " + message.getJMSReplyTo());
if (message instanceof TextMessage)
System.out.println("Data: " + ((TextMessage) message).getText());
System.out.println("\n");
if (counter >= 5) break;
}
}
System.out.println("stopping the topic");
topicConnection.stop();
}
Attempting to make this cast gives me this error:
java.lang.ClassCastException: weblogic.jms.client.WLSessionImpl cannot be cast to oracle.jms.AQjmsSession
You can't cast it to that type because the client that your application is using isn't from the provider you think it is. According to the exception the TopicSession is of a type provided by the WebLogic JMS client so that cast is doomed to failure. You should look at your JNDI configuration and see if it is configured the way you seem to think it is configured.
Your JNDI Properties is telling the code where to create the ConnectionFactory from and that is getting you WebLogic client bits, you seem to want Oracle AQ bits so the ConnectionFactory that's looked up in the JNDI step needs to be an Oracle one.
Related
I have a function for consuming Kafka. I consume multiple topics in the same function. But I don't know which topic is consumed
#KafkaListener(topics = {"topic1","topic2"})
public void kafkaConsume(String message) {
//Print the kafka topic that is being consumed
return;
}
How do I print the kafka topic?
You can add #Headers parameter to get all the extra information you want within the message.
For example:
#KafkaListener(topics = "topicName")
public void listenWithHeaders(
#Payload String message,
#Header(KafkaHeaders.TOPIC) String topic) {
System.out.println("Received Message: " + message" + "from: " + topic);
}
You can get all this information in KafkaHeaders https://docs.spring.io/spring-kafka/api/org/springframework/kafka/support/KafkaHeaders.html
Or alternatively, you can consume a ConsumerRecord<K, V> which has most of the information as well
#KafkaListener(topics = "topicName")
public void listenConsumerRecord(ConsumerRecord<String, String> record) {
System.out.println("Received Message: " + record.value() + "from: " + record.topic());
}
In some old project, I need to replace AMQ with SQS. The problem I have is when I'm receiving the message some "Message" attributes like (getJMSType()) are null for example:
inside the onMessage method I have:
#Override
public void onMessage(Message message) {
LOG.info(CLASS_NAME, new Date() + " Message received... ");
Converter.EVENT_TYPE eventType = null;
String serviceType = null;
try {
if (message instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) message;
String onMessageRequestXML = txtMsg.getText();
serviceType = txtMsg.getJMSType(); <----------------- THESE ONE
if (serviceType == null) {
LOG.warning(CLASS_NAME, "JMS message type is null!");
return;
}
eventType = converter.getEventType(onMessageRequestXML);
LOG.info(CLASS_NAME, "Message received is of EventType: " + eventType + " ServiceType : " + serviceType);
if (serviceType.equalsIgnoreCase(ServiceConstants.MW_METER_MGMT_HOUSEHOLD_UPDATE_REQUEST_JMS_TYPE)) {
In my "message sender" code I set the message content and also the value for JMSType
example:
connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(session.createQueue("nonprod-mbo-sqs-api-hybridcollection-dev-mwcfgsend"));
String mes = "TEST...";
TextMessage message = session.createTextMessage(mes);
message.setJMSType("MW_METER_MGMT_HOUSEHOLD_UPDATE_REQUEST_JMS_TYPE");
message.setJMSMessageID(""+System.currentTimeMillis());
producer.send(message);
In my project, I'm using amazon-sqs-java-messaging-lib version 1.0.8.
Have also tried to use SQSTextMessage instead of TextMessage but the result is the same.
Any Idea why the values are not included when I receive the message?
I am working on receiving pending messages in Azure Service Bus queue.
I have created a queue (SampleQueue) in Azure ServiceBus and I am able to send the message successfully in that queue via POSTMAN using a SAS token which I generate with my Java program.
I am also getting a 201 created status after hitting my service bus queue api url(below image).
I want to receive the message pending in my Service bus queue. I went through some links about receiving message (https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-java-how-to-use-queues), but this does not contain information about how I can receive and view those messages.
My Java code that receives the message from Service bus queue looks like below[I am a novice in Java]:-
public class Test2 {
public static void main(String[] args) throws ServiceException {
String namespace = "SampleNamespace";
String sharedKeyName = "RootManageSharedAccessKey";
String sharedSecretKey = "t+U5ERMAnIyxgEUDUouGOKn6ADM/CuLWzEJZtauwVsc=";
String queueName = "QueueName";
// Azure Service Bus Service
com.microsoft.windowsazure.Configuration config = ServiceBusConfiguration.configureWithSASAuthentication(namespace, sharedKeyName, sharedSecretKey, ".servicebus.windows.net");
ServiceBusContract service = ServiceBusService.create(config);
// Receive and Delete Messages
ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.RECEIVE_AND_DELETE);
while (true) {
ReceiveQueueMessageResult resultQM = service.receiveQueueMessage(queueName , opts);
BrokeredMessage message = resultQM.getValue();
if (message != null && message.getMessageId() != null) {
System.out.println("Body: " + message.toString());
System.out.println("MessageID: " + message.getMessageId());
} else {
System.out.println("No more messages.");
break;
}
}
}
}
But when I run this code, I get the below error:-
Exception in thread "main" java.lang.NoClassDefFoundError: javax/ws/rs/WebApplicationException
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructors(Class.java:1651)
at com.microsoft.windowsazure.core.DefaultBuilder.findInjectConstructor(DefaultBuilder.java:67)
at com.microsoft.windowsazure.core.DefaultBuilder.add(DefaultBuilder.java:94)
at com.microsoft.windowsazure.services.servicebus.Exports.register(Exports.java:34)
at com.microsoft.windowsazure.core.DefaultBuilder.create(DefaultBuilder.java:46)
at com.microsoft.windowsazure.Configuration.<init>(Configuration.java:80)
at com.microsoft.windowsazure.Configuration.load(Configuration.java:100)
at com.microsoft.windowsazure.Configuration.getInstance(Configuration.java:90)
at com.microsoft.windowsazure.services.servicebus.ServiceBusConfiguration.configureWithSASAuthentication(ServiceBusConfiguration.java:252)
at com.rocky.servicebus.queue.Test2.main(Test2.java:24)
Caused by: java.lang.ClassNotFoundException: javax.ws.rs.WebApplicationException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Can anyone please help in rectifying what I am doing wrong?
Would be greatful for any help.
Thanks,
Rudra
Based on the tutorial for receiving message, you need to create a queue client, and register a message handler for it.
A) Get connection string.
B) A code sample for sending and receiving messages
public static void registerReceiver(QueueClient queueClient, ExecutorService executorService) throws Exception {
queueClient.registerMessageHandler(
new IMessageHandler() {
public CompletableFuture<Void> onMessageAsync(IMessage message) {
if (message.getLabel() != null &&
message.getContentType() != null &&
message.getLabel().contentEquals("TestMessage") &&
message.getContentType().contentEquals("text/plain")) {
System.out.printf(
"\nMessage received: \n -->MessageId = %s\n -->ContentType = %s\n -->Content = %s\n",
message.getMessageId(),
message.getContentType(),
new String(message.getBody())
);
return queueClient.completeAsync(message.getLockToken());
}
return queueClient.abandonAsync(message.getLockToken());
}
public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
System.out.printf(exceptionPhase + "-" + throwable.getMessage());
}
},
new MessageHandlerOptions(1, false, Duration.ofSeconds(10)),
executorService
);
}
public static void sendMessages(QueueClient client) throws ServiceBusException, InterruptedException {
for (int i = 0; i < 100; i++) {
String messageId = Integer.toString(i);
Message message = new Message("This is message " + i);
message.setContentType("text/plain");
message.setLabel("TestMessage");
message.setMessageId(messageId);
message.setTimeToLive(Duration.ofMinutes(10));
client.send(message);
System.out.printf("Message sent: Id = %s \n", message.getMessageId());
}
}
public static void main(String[] args) throws Exception {
String connectionString = "your_connection_string, Endpoint=sb://j*9.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=V*=";
String queueName = "your_queue_name, testQueue";
QueueClient client = new QueueClient(new ConnectionStringBuilder(connectionString, queueName), ReceiveMode.PEEKLOCK);
sendMessages(client);
client.close();
QueueClient receiveClient = new QueueClient(new ConnectionStringBuilder(connectionString, queueName), ReceiveMode.PEEKLOCK);
ExecutorService executorService = Executors.newSingleThreadExecutor();
registerReceiver(receiveClient, executorService);
Thread.sleep(60 * 1000); // Wait for 60 seconds to receive all the messages.
receiveClient.close();
executorService.shutdown();
}
Result:
100 messages will be sent.
Message sent: Id = 0
Message sent: Id = 1
Message sent: Id = 2
Message sent: Id = 3
*
*
*
Message sent: Id = 99
And then will start to receive messages.
Message received:
-->MessageId = 0
-->ContentType = text/plain
-->Content = This is message 0
Message received:
-->MessageId = 1
-->ContentType = text/plain
-->Content = This is message 1
Message received:
-->MessageId = 2
-->ContentType = text/plain
-->Content = This is message 2
*
*
*
Message received:
-->MessageId = 99
-->ContentType = text/plain
-->Content = This is message 99
For all the wanderers, below is the working Java code to fetch pending messages from Azure SB Queue:-
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
import com.microsoft.windowsazure.services.servicebus.ServiceBusConfiguration;
import com.microsoft.windowsazure.services.servicebus.ServiceBusContract;
import com.microsoft.windowsazure.services.servicebus.ServiceBusService;
import com.microsoft.windowsazure.services.servicebus.models.BrokeredMessage;
import com.microsoft.windowsazure.services.servicebus.models.ReceiveMessageOptions;
import com.microsoft.windowsazure.services.servicebus.models.ReceiveMode;
import com.microsoft.windowsazure.services.servicebus.models.ReceiveQueueMessageResult;
public class Test1 {
//static StringWriter writer = new StringWriter();
public static void main(String...s) throws Exception{
com.microsoft.windowsazure.Configuration config = ServiceBusConfiguration.configureWithSASAuthentication("Your_NameSpace", "RootManageSharedAccessKey", "Mkf1H3g9qg0LrNEP1QbZ/EJKSARmJZQdOI6ek6obalI=", ".servicebus.windows.net");
ServiceBusContract service = ServiceBusService.create(config);
ReceiveMessageOptions opts = ReceiveMessageOptions.DEFAULT;
opts.setReceiveMode(ReceiveMode.PEEK_LOCK);
while(true)
{
ReceiveQueueMessageResult resultQM = service.receiveQueueMessage("Queue_Name", opts);
BrokeredMessage message = resultQM.getValue();
if (message != null && message.getMessageId() != null)
{
try
{
// IOUtils.copy(message.getBody(), writer, encoding);
Scanner s1 = new Scanner(message.getBody()).useDelimiter("\\A");
String result = s1.hasNext() ? s1.next() : "";
//above will convert InputStream in String
System.out.println("Body: " + message.toString());
System.out.println("MainBody : " + result );
System.out.println("MessageID: " + message.getMessageId());
System.out.println("Custom Property: " +
message.getProperty("TestProperty"));
// Remove message from queue
System.out.println("Deleting this message.");
service.deleteMessage(message);
}
catch (Exception ex)
{
// Indicate a problem, unlock message in queue
System.out.println("Inner exception encountered!");
service.unlockMessage(message);
}
}
else
{
System.out.println("Finishing up - no more messages.");
break;
// Added to handle no more messages in the queue.
// Could instead wait for more messages to be added.
}
}
}
}
Make sure to get required Maven Dependencies for "BrokeredMessage".
Thanks,
Rudra
I want to send a message from Amazon Simple Notification Service (SNS) using Play framework, and I read that I have to use WS for REST APIs. However, I am confused on how to do this. Can anyone help me work this out?
First of all, you need to add SNS SDK to your project by adding the following line into your build.sbt:
libraryDependencies += "com.amazonaws" % "aws-java-sdk-sns" % "1.11.271"
then use your service by injecting it with your controller, your service should be something like:
#Singleton
public final class AmazonSNSService {
// logging always a good thing to do
private final Logger.ALogger logger = Logger.of(this.getClass());
// this is what you have to use
private final com.amazonaws.services.sns.AmazonSNS snsClient;
private final String AMAZON_ARN;
#Inject
public AmazonSNSService(Configuration configuration) { // or Config if play 2.6 and later
// I set the aws config in application.conf and I read them here
final String AWS_ACCESS_KEY = configuration.getString("aws_access_key");
final String AWS_SECRET_KEY = configuration.getString("aws_secrect_key");
snsClient = AmazonSNSClient.builder()
.withRegion(Regions.US_EAST_1)
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY)))
.build();
AMAZON_ARN = configuration.getString("amazon_arn_config_key");
}
}
then you can use snsClient with methods you do want, for creating a topic:
public void createTopic(String topicName) {
String topicARN = AMAZON_ARN + ":" + topicName;
if (doesTopicExists(topicARN)) {
logger.debug("TopicArn - already Exists" + topicARN);
} else {
//create a new SNS topic
CreateTopicRequest createTopicRequest = new CreateTopicRequest(topicName);
CreateTopicResult createTopicResult = snsClient.createTopic(createTopicRequest);
//get request id for CreateTopicRequest from SNS metadata
ResponseMetadata topicResponse = snsClient.getCachedResponseMetadata(createTopicRequest);
logger.debug("CreateTopicArn - " + createTopicResult.getTopicArn());
}
}
And another example to subscribe to the topic:
public String subscribeToTopic(String topicName, String deviceEndpointARN) {
String topicARN = AMAZON_ARN + ":" + topicName;
//if topic does not exists create topic then subscribe
if (!doesTopicExists(topicARN)) {
createTopic(topicName);
}
return subscribeToTopic(topicARN, deviceEndpointARN);
}
Want push to the topic?:
public void publishToTopic(String message, String topicName) {
String topicARN = AMAZON_ARN + ":" + topicName;
//if topic does not exists create topic then publish to topic
// or throw an exception, maybe it does not make sense to push to the topic that have no subscribers at all.
if (!doesTopicExists(topicARN)) {
createTopic(topicName);
}
//publish to an SNS topic
PublishRequest publishRequest = new PublishRequest(topicARN, message);
publishRequest.setMessageStructure("json");
PublishResult publishResult = snsClient.publish(publishRequest);
//print MessageId of message published to SNS topic
logger.debug("Push Notification sent to TOPIC [" + topicARN + "] MessageId - [" + publishResult.getMessageId() + "] Message Body: " + message);
}
And this is how I check if the topic exists or not:
private boolean doesTopicExists(String topicARN) {
String nextToken = null;
do {
ListTopicsRequest request = new ListTopicsRequest();
request.setNextToken(nextToken);
ListTopicsResult listTopicsResult = snsClient.listTopics();
List<Topic> topics = listTopicsResult.getTopics();
for (Topic topic : topics) {
if (topic.getTopicArn().equals(topicARN)) {
return true;
}
}
nextToken = request.getNextToken();
} while (nextToken != null);
return false;
}
For more, check java doc of them and search for examples,
Have fun!
I have my Hyperledger Fabric V1.0 network up and running by following the steps Building Your First Network.
And now I am able to create channel, install/instantiate/invoke/query chaincode etc.
Now I am trying to create some assets and query the same using Java SDK Client.
I have created the following methods to invoke and query the chaincode from my java application.
void createChannel() throws InvalidArgumentException, TransactionException, IOException, ProposalException{
Properties ordererProperties = getOrdererProperties("orderer.example.com");
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
Orderer orderer = client.newOrderer("orderer.example.com", "grpcs://192.168.99.100:7050",ordererProperties);
Properties peerProperties = getPeerProperties("peer0.org1.example.com"); //test properties for peer.. if any.
if (peerProperties == null) {
peerProperties = new Properties();
}
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer = client.newPeer("peer0.org1.example.com", "grpcs://192.168.99.100:7051",peerProperties);
channel = client.newChannel("testchannel");
channel.addOrderer(orderer);
channel.addPeer(peer);
channel.initialize();
}
void creteTransactionalProposal(){
proposalRequest = client.newTransactionProposalRequest();
final ChaincodeID chaincodeID = ChaincodeID.newBuilder()
.setName("asset_test")
.setVersion("1.0")
.setPath("github.com/myuser/myfabricrepo/asset_chain")
.build();
proposalRequest.setChaincodeID(chaincodeID);
proposalRequest.setFcn("set");
proposalRequest.setProposalWaitTime(TimeUnit.SECONDS.toMillis(1));
proposalRequest.setArgs(new String[]{"a1", "a1_val"});
}
void sendProposal() throws ProposalException, InvalidArgumentException, InterruptedException, ExecutionException{
final Collection<ProposalResponse> responses = channel.sendTransactionProposal(proposalRequest);
CompletableFuture<BlockEvent.TransactionEvent> txFuture = channel.sendTransaction(responses, client.getUserContext());
BlockEvent.TransactionEvent event = txFuture.get();//waiting indefinitely
System.out.println(event.toString());
//query();
}
void query() throws InvalidArgumentException, ProposalException{
final ChaincodeID chaincodeID = ChaincodeID.newBuilder()
.setName(""asset_test"")
.setVersion("1.0")
.setPath("github.com/myuser/myfabricrepo/asset_chain")
.build();
QueryByChaincodeRequest queryByChaincodeRequest = client.newQueryProposalRequest();
queryByChaincodeRequest.setArgs(new String[] {"a1"});
queryByChaincodeRequest.setFcn("get");
queryByChaincodeRequest.setChaincodeID(chaincodeID);
Map<String, byte[]> tm2 = new HashMap<>();
tm2.put("HyperLedgerFabric", "QueryByChaincodeRequest:JavaSDK".getBytes(UTF_8));
tm2.put("method", "QueryByChaincodeRequest".getBytes(UTF_8));
queryByChaincodeRequest.setTransientMap(tm2);
Collection<ProposalResponse> queryProposals = channel.queryByChaincode(queryByChaincodeRequest, channel.getPeers());
for (ProposalResponse proposalResponse : queryProposals) {
if (!proposalResponse.isVerified()
|| proposalResponse.getStatus() != ProposalResponse.Status.SUCCESS) {
System.out.println("Failed query proposal from peer " + proposalResponse.getPeer().getName() + " status: "
+ proposalResponse.getStatus() + ". Messages: " + proposalResponse.getMessage()
+ ". Was verified : " + proposalResponse.isVerified());
} else {
String payload = proposalResponse.getProposalResponse().getResponse().getPayload()
.toStringUtf8();
System.out.printf("\nQuery payload of b from peer %s returned %s", proposalResponse.getPeer().getName(),
payload);
//assertEquals(payload, expect);
}
}
}
I am able to create Asset by calling
t.creteTransactionalProposal();
t.sendProposal();
But the line BlockEvent.TransactionEvent event = txFuture.get(); makes the application in an indefinite waiting state even after the completion of the transaction commit to ledger. Why it is behaving like this?
Once I to force exit and run the query() method it is listing the asset.
I ran into a similar issue to this, and many of the answers around the net are missing a key part of the code - assigning the EventHub to the channel. I added this before initializing the channel (which in this case would be in the createChannel mehtod), and my transactions were then processed successfully:
channel.addEventHub(client.newEventHub("eventhub0", "grpc://localhost:7053"));