I send data to the IoT Hub and receive it, it works, but i dont know how i can work with the received Data: here is my Code to receive data:
public void accept(PartitionReceiver receiver)
{
System.out.println("** Created receiver on partition " + partitionId);
try {
while (true) {
Iterable<EventData> receivedEvents = receiver.receive(10).get();
int batchSize = 0;
if (receivedEvents != null)
{
for(EventData receivedEvent: receivedEvents)
{
System.out.println(String.format("| Time: %s", receivedEvent.getSystemProperties().getEnqueuedTime()));
System.out.println(String.format("| Device ID: %s", receivedEvent.getProperties().get("iothub-connection-device-id")));
System.out.println(String.format("| Message Payload: %s", new String(receivedEvent.getBody(), Charset.defaultCharset())));
batchSize++;
}
}
}
}
catch (Exception e)
{
System.out.println("Failed to receive messages: " + e.getMessage());
}
}
I would like to work with the received data, here I become the data as JSON String:
System.out.println(String.format("| Message Payload: %s", new String(receivedEvent.getBody(), Charset.defaultCharset())));
The dataoutput is: product: xy, price: 2.3.
I would like take the data to :
String product= product;
double price= price;
How can I the received Payload save in the variable?
Thanks
There are two kinds of messages which include device-to-cloud and cloud-to-device.
For the first kind, device-to-cloud messages, as #DominicBetts said, you can refer to the section Receive device-to-cloud messages to know how to receive d2c messages with Event Hub-compatible endpoint. And there are two samples as references on GitHub, please see below.
Simple send/receive sample: Shows how to connect then send and receive messages to and from IoT Hub, passing the protocol of your choices as a parameter.
Simple sample handling messages received: : Shows how to connect to IoT Hub and manage messages received from IoT Hub, passing the protocol of your choices as a parameter.
For the second kind, cloud-to-device messages, you can refer to the section Receiving messages on the simulated device to know how to receive c2d messages. The sample code in the article was writen for C#, but I think it's simple for using Java instead of C#, please notice the note in the section for choosing the suitable protocol.
Related
I need to send my messages to Dead letter queue from azure topic subscription incase of any error while reading and processing the message from topic. So I tried testing pushing message directly to DLQ.
My sample code will be like
static void sendMessage()
{
// create a Service Bus Sender client for the queue
ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
.connectionString(connectionString)
.sender()
.topicName(topicName)
.buildClient();
// send one message to the topic
senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
}
static void resceiveAsync() {
ServiceBusReceiverAsyncClient receiver = new ServiceBusClientBuilder()
.connectionString(connectionString)
.receiver()
.topicName(topicName)
.subscriptionName(subName)
.buildAsyncClient();
// receive() operation continuously fetches messages until the subscription is disposed.
// The stream is infinite, and completes when the subscription or receiver is closed.
Disposable subscription = receiver.receiveMessages().subscribe(message -> {
System.out.printf("Id: %s%n", message.getMessageId());
System.out.printf("Contents: %s%n", message.getBody().toString());
}, error -> {
System.err.println("Error occurred while receiving messages: " + error);
}, () -> {
System.out.println("Finished receiving messages.");
});
// Continue application processing. When you are finished receiving messages, dispose of the subscription.
subscription.dispose();
// When you are done using the receiver, dispose of it.
receiver.close();
}
I tried getting the deadletter queue path
String dlq = EntityNameHelper.formatDeadLetterPath(topicName);
I got path of dead letter queue like = "mytopic/$deadletterqueue"
But It's not working while passing path as topic name. It throwing a Entity topic not found exception.
Any one can you please advise me on this
Reference :
How to move error message to Azure dead letter queue using Java?
https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dead-letter-queues#moving-messages-to-the-dlq
How to push the failure messages to Azure service bus Dead Letter Queue in Spring Boot Java?
https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-java-how-to-use-topics-subscriptions-legacy#receive-messages-from-a-subscription
You probably know that a message will be automatically moved to the deadletter queue if you throw exceptions during processing, and the maximum delievery count is exceeded. If you want to explicitly move the message to the DLQ, you can do so as well. A common case for this is if you know that the message can never succeed because of its contents.
You cannot send new messages directly to the DLQ, because then you would have two messages in the system. You need to call a special operation on the parent entity. Also, <topic path>/$deadletterqueue does not work, because this would be the DLQ of all subscriptions. The correct entity path is built like this:
<queue path>/$deadletterqueue
<topic path>/Subscriptions/<subscription path>/$deadletterqueue
https://github.com/Azure/azure-service-bus/blob/master/samples/Java/azure-servicebus/DeadletterQueue/src/main/java/com/microsoft/azure/servicebus/samples/deadletterqueue/DeadletterQueue.java
This sample code is for queues, but you should be able to adapt it to topics quite easily:
// register the RegisterMessageHandler callback
receiver.registerMessageHandler(
new IMessageHandler() {
// callback invoked when the message handler loop has obtained a message
public CompletableFuture<Void> onMessageAsync(IMessage message) {
// receives message is passed to callback
if (message.getLabel() != null &&
message.getContentType() != null &&
message.getLabel().contentEquals("Scientist") &&
message.getContentType().contentEquals("application/json")) {
// ...
} else {
return receiver.deadLetterAsync(message.getLockToken());
}
return receiver.completeAsync(message.getLockToken());
}
// callback invoked when the message handler has an exception to report
public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
System.out.printf(exceptionPhase + "-" + throwable.getMessage());
}
},
// 1 concurrent call, messages are auto-completed, auto-renew duration
new MessageHandlerOptions(1, false, Duration.ofMinutes(1)),
executorService);
I want to convert one of my synchronous API into asynchronous. And I believe queue are one way to do this. Like a publisher will push(synchronously) the message into queue which will be consumed by consumer API from the queue.
I was curious to know what is the right way of consuming AWS SimpleQueueService messages. Can queue call an API to deliver the message to it or the only way to do is to poll the queue. But I believe that polling will make our system busy waiting so it is best the queue deliver the message to API.
What is possible way to do this?
If you want to consume from SQS you have the following methods:
Polling using the SDK to consume messages
Using the Amazon SQS Java Messaging Library
Subscribing to an SNS Topic
Using Lambda.
If you intend to retrieve to get responses back you can also take advantage of virtual queues.
In application.yml
sqs:
region: ap-south-1
accessKeyId: arunsinghgujjar
secretAccessKey: jainpurwalearunsingh/saharanpursepauchepuna
cloud:
aws:
end-point:
uri: https://arun-learningsubway-1.amazonaws.com/9876974864/learningsubway_SQS.fifo
queue:
max-poll-time: 20
max-messages: 10
fetch-wait-on-error: 60
enabled: true
content: sqs
Write SQS client
public String sendMessage(MessageDistributionEvent messageDistributionEvent) {
SendMessageResponse sendMessage = null;
try {
Map<String, MessageAttributeValue> attributes = new HashMap<>();
String recepList = "";
for (Integer myInt : messageDistributionEvent.getRecipients()) {
recepList = recepList + "_" + myInt;
}
SendMessageRequest sendMsgRequest = SendMessageRequest.builder()
.queueUrl(url)
.messageBody(messageDistributionEvent.getChannelId() + "_" + messageDistributionEvent.getMessageId() + "" + recepList)
.messageGroupId("1")
.messageAttributes(attributes)
.build();
sendMessage = sqsClient.sendMessage(sendMsgRequest);
} catch (Exception ex) {
log.info("failed to send message :" + ex);
}
return sendMessage.sequenceNumber();
}
Read Message from Queue
ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
.queueUrl(url)
.waitTimeSeconds(maxPollTime)
.maxNumberOfMessages(maxMessages)
.messageAttributeNames("MessageLabel")
.build();
List<Message> sqsMessages = sqsClient.receiveMessage(receiveMessageRequest).messages();
Reference
https://learningsubway.com/read-write-data-into-aws-sqs-using-java/
I am getting started with vertx and was trying out point to point messaging on event bus. I have 2 services both created as separate maven projects and deployed as fat-jars
1) Read from a file and send the content as a message over an address - ContentParserService.java
2) Read the message and reply to the incoming message- PingService.java
Both these services are deployed as separate jars kind of a microservice fashion
The code is as follows: ContentParserService.java
#Override
public void start(Future<Void> startFuture) throws Exception {
super.start(startFuture);
// Reference to the eventbus running on JVM
EventBus eventBus = vertx.eventBus();
// Read file using normal java mechanism
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ClassLoader.getSystemResourceAsStream(
(config().getString("filename")))));
bufferedReader.readLine(); //read first line
String line = null;
while ((line = bufferedReader.readLine()) != null) {
String[] data = line.split(",");
// Create RealEstate Object
RealEstateTransaction realEstateData = createTransactionObject(data);
// Construct Message JSON
JsonObject messageJSON = constructMessageJson(realEstateData);
// Send message to PING address over the Event Bus
eventBus.send("PING", Json.encode(messageJSON), reply -> {
if (reply.succeeded())
System.out.println("Received Reply: " + reply.result().body());
else {
System.out.println("No reply");
}
});
}
} catch (IOException e) {
startFuture.fail(e.getMessage());
}
The code is as follows: PingService.java
#Override
public void start(Future<Void> startFuture) throws Exception {
super.start(startFuture);
System.out.println("Referencing event bus");
// Reference to the event bus running on the JVM
EventBus eventBus = vertx.eventBus();
System.out.println("Creating HttpServer");
// Create HTTP Server to handle incoming requests
HttpServer httpServer = vertx.createHttpServer();
System.out.println("Creating Router");
// Create Router for routing to appropriate endpoint
Router router = Router.router(vertx);
System.out.println("Starting to consume message sent over event bus");
// Consume the incoming message over the address PING
eventBus.consumer("PING", event -> {
System.out.println("Received message: " + event.body());
event.reply("Received at PING address");
});
System.out.println("Receiver ready and receiving messages");
When i run both the services I run on the same machine with the java -jar command for each of the service. What i observed was when i deploy the first jar of ContentParserService, it immediately starts and sends messages over the event bus, but by the time i start the pingservice jar , it is not able to receive any message sent over the event bus because my pingService is a separate fatjar and a microservice in itself. The file that i am reading is a finite lenght csv file of around 200 entries. This case would work if i bundle both the services in a single fat jar.
How should i achieve the different fat jars services able to send message to each other in my case.
This case works when both verticles in the same jar only because there's no network delay. But your usecase for EventBus is incorrect, since it doesn't persist messages, hence cannot replay them. You should start sending messages only when the other side is ready to receive them.
You need to reverse the dependency. In your ContentParserService register for some "ready" event, then start your while loop only when you get it:
vertx.eventBus().consumer("ready", (message) -> {
while ((line = bufferedReader.readLine()) != null) {
...
}
});
Now, what will happen if ContentParserService is actually slower and misses the "ready" event? Use vertx.setPeriodic() for that. So you start your PingService, and periodically tell ContentParserService that you're ready to receive some messages.
Or, as an option, just don't use EventBus at all between you services, and switch to something with persistence, like RabbitMQ or Kafka.
I am integrating Plivo SMS API with my java web application. I want to send messages through my application. I am referring to https://www.plivo.com/docs/getting-started/send-a-single-sms/ link.
Below is the code snippet:
String authId = "{my Auth_id}"; //Your Authentication ID
String authToken = "{my auth Token}"; //Your authentication code
RestAPI api = new RestAPI(authId, authToken, "v1");
LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
parameters.put("src", "+44*******"); // Sender's phone number with country code
parameters.put("dst", "+91*******"); // Receiver's phone number with country code
parameters.put("text", "Hi, text from Plivo"); // Your SMS text message
try {
// Send the message
MessageResponse msgResponse = api.sendMessage(parameters);
// Print the response
System.out.println(msgResponse);
// Print the Api ID
System.out.println("Api ID : " + msgResponse.apiId);
// Print the Response Message
System.out.println("Message : " + msgResponse.message);
if (msgResponse.serverCode == 202) {
// Print the Message UUID
System.out.println("Message UUID : " + msgResponse.messageUuids.get(0).toString());
} else {
System.out.println(msgResponse.error);
}
} catch (PlivoException e) {
System.out.println(e.getLocalizedMessage());
}
I tried to run this code using console application as well as web application.I am getting exception "com.plivo.helper.exception.PlivoException: Connection to https://api.plivo.com refused". What is wrong with my code? Am I missing anything here?
Plivo Sales Engineer here.
Please check your firewall settings to ensure that it's not blocking any traffic. Also, are you using a web proxy? If yes, make sure that your application is using this proxy to handle connections.
i am trying to use my mobile phone as GSM modem.i use SMSLib for sending and receiving SMS with this modem.
the problem is that when my phone(GSM modem) receive a sms i don't notify with SMSLib.but the code overall is good for example that notifies me when GSM modem receive a call.
my code has not any bug because i only use SMSLib example code for receiving message.
the SMSLib example code is :
public class TestSinaRec
{
public void doIt() throws Exception
{
// Define a list which will hold the read messages.
List<InboundMessage> msgList;
// Create the notification callback method for inbound & status report
// messages.
InboundNotification inboundNotification = new InboundNotification();
// Create the notification callback method for inbound voice calls.
CallNotification callNotification = new CallNotification();
//Create the notification callback method for gateway statuses.
GatewayStatusNotification statusNotification = new GatewayStatusNotification();
OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
try
{
System.out.println("Example: Read messages from a serial gsm modem.");
System.out.println(Library.getLibraryDescription());
System.out.println("Version: " + Library.getLibraryVersion());
// Create the Gateway representing the serial GSM modem.
SerialModemGateway gateway = new SerialModemGateway("modem.com4", "COM4", 115200, "Nokia", " 6303i");
// Set the modem protocol to PDU (alternative is TEXT). PDU is the default, anyway...
gateway.setProtocol(Protocols.PDU);
// Do we want the Gateway to be used for Inbound messages?
gateway.setInbound(true);
// Do we want the Gateway to be used for Outbound messages?
gateway.setOutbound(true);
// Let SMSLib know which is the SIM PIN.
gateway.setSimPin("0444");
// Set up the notification methods.
Service.getInstance().setInboundMessageNotification(inboundNotification);
Service.getInstance().setCallNotification(callNotification);
Service.getInstance().setGatewayStatusNotification(statusNotification);
Service.getInstance().setOrphanedMessageNotification(orphanedMessageNotification);
// Add the Gateway to the Service object.
Service.getInstance().addGateway(gateway);
// Similarly, you may define as many Gateway objects, representing
// various GSM modems, add them in the Service object and control all of them.
// Start! (i.e. connect to all defined Gateways)
Service.getInstance().startService();
// Printout some general information about the modem.
System.out.println();
System.out.println("Modem Information:");
System.out.println(" Manufacturer: " + gateway.getManufacturer());
System.out.println(" Model: " + gateway.getModel());
System.out.println(" Serial No: " + gateway.getSerialNo());
System.out.println(" SIM IMSI: " + gateway.getImsi());
System.out.println(" Signal Level: " + gateway.getSignalLevel() + " dBm");
System.out.println(" Battery Level: " + gateway.getBatteryLevel() + "%");
System.out.println();
// In case you work with encrypted messages, its a good time to declare your keys.
// Create a new AES Key with a known key value.
// Register it in KeyManager in order to keep it active. SMSLib will then automatically
// encrypt / decrypt all messages send to / received from this number.
//Service.getInstance().getKeyManager().registerKey("+306948494037", new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));
// Read Messages. The reading is done via the Service object and
// affects all Gateway objects defined. This can also be more directed to a specific
// Gateway - look the JavaDocs for information on the Service method calls.
msgList = new ArrayList<InboundMessage>();
Service.getInstance().readMessages(msgList, MessageClasses.ALL);
for (InboundMessage msg : msgList)
System.out.println(msg);
// Sleep now. Emulate real world situation and give a chance to the notifications
// methods to be called in the event of message or voice call reception.
System.out.println("Now Sleeping - Hit <enter> to stop service.");
System.in.read();
System.in.read();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
Service.getInstance().stopService();
}
}
public class InboundNotification implements IInboundMessageNotification
{
public void process(AGateway gateway, MessageTypes msgType, InboundMessage msg)
{
if (msgType == MessageTypes.INBOUND) System.out.println(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
else if (msgType == MessageTypes.STATUSREPORT) System.out.println(">>> New Inbound Status Report message detected from Gateway: " + gateway.getGatewayId());
System.out.println(msg);
}
}
public class CallNotification implements ICallNotification
{
public void process(AGateway gateway, String callerId)
{
System.out.println(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);
}
}
public class GatewayStatusNotification implements IGatewayStatusNotification
{
public void process(AGateway gateway, GatewayStatuses oldStatus, GatewayStatuses newStatus)
{
System.out.println(">>> Gateway Status change for " + gateway.getGatewayId() + ", OLD: " + oldStatus + " -> NEW: " + newStatus);
}
}
public class OrphanedMessageNotification implements IOrphanedMessageNotification
{
public boolean process(AGateway gateway, InboundMessage msg)
{
System.out.println(">>> Orphaned message part detected from " + gateway.getGatewayId());
System.out.println(msg);
// Since we are just testing, return FALSE and keep the orphaned message part.
return false;
}
}
public static void main(String args[])
{
TestSinaRec app = new TestSinaRec();
try
{
app.doIt();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
program output is for example :
Gateway Status change for modem.com4, OLD: STOPPED -> NEW: STARTING
Gateway Status change for modem.com4, OLD: STARTING -> NEW: STARTED
Modem Information: Manufacturer: Nokia Model: Nokia 6303i classic
Serial No: 355382041051833 SIM IMSI: ** MASKED ** Signal Level:
-57 dBm Battery Level: 91%
Now Sleeping - Hit to stop service.
New call detected from Gateway: modem.com4 : +989111007483
New call detected from Gateway: modem.com4 : +989111007483
when i searched for this issue i found this :
The correct operation of this method depends on the unsolicited modem
indications and on the correct operation of the CNMI command. If you
see that you are failing to receive messages using a callback method,
probably the modem indications have not been setup correctly.
so i changed my phone(my GSM modem) with Nokia 6303i rather than Nokia 5200 that i used first but the problem didn't solve.
so now i really don't know the problem will solve with choosing another phones ?! or i should search for a better and more reasonable solution.
thank you for any bit of help for solving this problem.
Well the only thing I can think of is that you're starting the Service and then sending the SMS to the modem. Because of this, this line won't be called: Service.getInstance().readMessages(msgList, MessageClasses.ALL);. However, you should still get the notification that a new message has arrived at the modem.
Try implementing the InboundNotification to fetch the messages when it senses any new messages on the modem. Do this by overriding the process() method.
However, it might also be due to the fact that you're actually pressing <Enter> too soon. As the comment say; you have to wait go give the notifications method a chance to be called.
Sometimes it's just something as silly as that. Let me know if any of it helped or if I completely misunderstood your problem. I'm working on a multi-modem gateway myself, so I'd be happy to help.
i had an issue with a GT-I9000 he received the inbound alert but couldn't fetch it the right sms object, i think this is a matter of the Storage Location,
i tried with another phone (Samsung GT-S5670 Android) of a friend of mine who had some messages stored on the SIM Card Memory, the smslibrary was notified and the ReadMessages Class logged all the messages.
so i think you need to find somehow to change storage location on the ReadMessages.java or find an compatible phone that can stores the sms to Sim Card instead of the phone memory.
hope this help.
The problem was with my phone.Smslib doesn't work in listening sms for a variety of phones(including smartphones,most of Nokia phones,etc.).I didn't check but probably this problem will be solved if you use a dedicated GSM modem(like huawei GSM modems)