NumberFormatException in connecting Azure Service Bus using Managed Identity - java

I am trying to connect to Azure Service Bus from my webjob using Managed Identities. But unfortunately, I am getting the following error
com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: For input string: "10/10/2020 6:50:38 AM +00:00"
I have enabled Identity and assigned Contributor role for connecting to Service bus. Also, in the code, I have used ClientSettings to create a connection with Service bus.
ClientFactory.createMessageReceiverFromEntityPathAsync(namespace, queueName,new ClientSettings(TokenProvider.createManagedServiceIdentityTokenProvider()), ReceiveMode.RECEIVEANDDELETE).get();
Any idea how to resolve this exception, as it is thrown from built-in class ManagedServiceIdentityTokenProvider. Any help would be really helpful.
Thanks in advance.
EDIT -
I updated the service bus package to 3.2.0. Now I can't see NumberFormatException but I am getting java.lang.RuntimeException: java.net.SocketException: Permission denied: connect even though I have provided the 'Owner' role to the webjob.

If you want to connect Azure Service bus with Azure Managed Identity, we need to assign some special role(Azure Service Bus Data Owner, Azure Service Bus Data Sender and Azure Service Bus Data Receiver ) to the MSI. For more details, please refer to here.
For example
Assing role to the MSI
Code
public static void main( String[] args )
{
IMessageReceiver receiver = null;
try {
receiver= ClientFactory.createMessageReceiverFromEntityPathAsync("bowman1012",
"myqueue",
new ClientSettings(TokenProvider.createManagedIdentityTokenProvider()),
ReceiveMode.PEEKLOCK).get();
IMessage message = receiver.receiveAsync().get();
String content = new String(message.getBody(), UTF_8);
System.out.println(content);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally {
Boolean f= receiver.closeAsync().complete(null);
System.out.println(f);
}
}

Related

Kucoin Java SDK error KC-API-KEY not exists

Following their guide in usage here I couldn't get started.
The code:
KucoinClientBuilder builder = new KucoinClientBuilder()
.withApiKeyVersion(2)
.withBaseUrl("https://openapi-sandbox.kucoin.com")
.withApiKey("MyKey", "MySecret", "MyPass");
KucoinRestClient kucoinRestClient = builder.buildRestClient();
KucoinPrivateWSClient kucoinPrivateWSClient;
try {
kucoinPrivateWSClient = builder.buildPrivateWSClient();
KucoinPublicWSClient kucoinPublicWSClient = builder.buildPublicWSClient();
} catch (IOException e) {
e.printStackTrace();
}
builder.buildPrivateWSClient() throws an exception with this message:
KucoinApiException{code='400003', message='KC-API-KEY not exists'}
I copied the Api Key and Secret and pass from the api page
What am I missing here? Why the KC-API-KEY does not exist?
The "sandbox" account is different than the original account.
Its domain is different and you need to register in the sandbox version of the website here

Getting Persistence Already in Use error from MQTT

I am getting the following exception from the mqtt broker when I am trying to create a new MqttClient. The error is here ---
Caused by: Persistence already in use (32200)
at org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence.open(MqttDefaultFilePersistence.java:108) [mqtt-client-0.4.0.jar:]
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:273) [mqtt-client-0.4.0.jar:]
at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:222) [mqtt-client-0.4.0.jar:]
at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:134) [mqtt-client-0.4.0.jar:]
at com.ericsson.asdp.virtualassist.notification.messaging.MQTTHandler.createClient(MQTTHandler.java:61) [classes:]
at com.ericsson.asdp.virtualassist.notification.messaging.MQTTMessagingService.receieve(MQTTMessagingService.java:52) [classes:]
... 44 more
Here is the code for my java class receive() method from where I am trying to connect to mqtt ---
MqttClient subClient = null;
try {
subClient = mqttHandler.createClient(userId, brokerURL);
MQTTNotificationSubscriber notificationSub = new MQTTNotificationSubscriber(mqttHandler);
notificationSub.setUserId(userId);
subClient.setCallback(notificationSub);
mqttHandler.subscribe(subClient, userId);
// do something here
} catch (Exception e) {
logger.error("Error in receive " + e.getMessage());
throw new VirtualAssistServicesException(e.getMessage(), e);
} finally {
try {
mqttHandler.disconnect(subClient);
} catch (MqttException e) {
throw new VirtualAssistServicesException(e.getMessage(), e);
}
}
And here is the MQTTHandler class createClient() method ---
MqttClient subClient = null;
try {
subClient = new MqttClient(brokerURL, clientId);
} catch (MqttException e) {
}
When I create the client for a userId first time it works. From second time onwards it fails with the above exception. I am using clean-session=false here.
If anyone has any idea please let me know. Thanks.
Looks like both clients are trying to use the same file for persistence.
Javadocs for MqttDefaultFilePersistence.open() says
Initialise the persistent store. If a persistent store exists for this client ID then open it, otherwise create a new one. If the persistent store is already open then just return. An application may use the same client ID to connect to many different servers, so the client ID in conjunction with the connection will uniquely identify the persistence store required.
Throws: MqttPersistenceException - if there was a problem opening the
persistent store.
I suppose the file is already open, you must use a different clientId in your code for each one of your Mqtt clients.
This is because in both client you are using same persistence name.
client = new MqttClient("tcp://192.168.1.100:1883", "One");
In the next thread you are using the same:
client1 = new MqttClient("tcp://192.168.1.100:1883", "One");
The persistence name should be different for each connection you want to make. You have to make change like this in client1:
client = new MqttClient("tcp://192.168.1.100:1883", "Two");

What can be the best approach to handle java.net.UnknownHostException for AWS users?

My application sends message to Amazon Simple Notification Service (SNS) topic but sometime (6/10) I get java.net.UnknownHostException:sqs.ap-southeast-1.amazonaws.com. The reason of exception is described in the amazon web services discussion forums, please look: https://forums.aws.amazon.com/thread.jspa?messageID=499290&#499290.
My problem is similar to what described in forums of amazon but my rate of publishing messages to topic is very dynamic. It can be 1 message/second or 1 message/minute or no message in an hour. I am looking for a cleaner, better and safe approach, which guaranties sending of message to SNS topic.
Description of problem in detail:
Topic_Arn= arn of SNS topic where application wants to publish message
msg = Message to send in topic
// Just a sample example which publish message to Amazon SNS topic
class SimpleNotificationService {
AmazonSNSClient mSnsClient = null;
static {
createSnsClient()
}
private void static createSnsClient() {
Region region = Region.getRegion(Regions.AP_SOUTHEAST_1);
AWSCredentials credentials = new
BasicAWSCredentials(AwsPropertyLoader.getInstance().getAccessKey(),
AwsPropertyLoader.getInstance().getSecretKey());
mSqsClient = new AmazonSQSClient(credentials);
mSqsClient.setRegion(region);
}
public void static publishMessage(String Topic_Arn, String msg) {
PublishRequest req = new PublishRequest(Topic_Arn, msg);
mSnsClient.publish(req);
}
}
class which calls SimpleNotificationService
class MessagingManager {
public void sendMessage(String message) {
String topic_arn = "arn:of:amazon:sns:topic";
SimpleNotificationService.publishMessage(topic_arn, message);
}
}
Please note that this is a sample code, not my actual code. Here can be class design issue but please ignore those if they are not related to problem.
My thought process says to have try-catch block inside sendMessage, so when we catch UnknownHostException then again retry but I am not sure how to write this in safer, cleaner and better way.
So MessagingManager class will look something like this:
class MessagingManager {
public void sendMessage(String message) {
String topic_arn = "arn:of:amazon:sns:topic";
try {
SimpleNotificationService.publishMessage(topic_arn, message);
} catch (UnknownHostException uhe) {
// I need to catch AmazonClientException as aws throws
//AmazonClientException when sees UnknownHostException.
// I am mentioning UnknownHostException for non-aws user to understand
// my problem in better way.
sendMessage(message); // Isn't unsafe? - may falls into infinite loop
}
}
}
I am open for answers like this: java.net.UnknownHostException: Invalid hostname for server: local but my concern is to dependent on solution at application code-level and less dependent on changes to machine. As my server application is going to run in many boxes (developer boxes, testing boxes or production boxes). If changes in machine host-files or etc is only guaranted solution then I prefer that to include with code level changes.
Each AWS SDK implements automatic retry logic. The AWS SDK for Java automatically retries requests, and you can configure the retry settings using the ClientConfiguration class.
Below is the sample example to create SNS client. It retries for 25 times if encounters UnKnownHostException. It uses default BackOff and retry strategy. If you want to have your own then you need to implement these two interfaces: http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/retry/RetryPolicy.html
private void static createSnsClient() {
Region region = Region.getRegion(Regions.AP_SOUTHEAST_1);
AWSCredentials credentials = new
BasicAWSCredentials(AwsPropertyLoader.getInstance().getAccessKey(),
AwsPropertyLoader.getInstance().getSecretKey());
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setMaxErrorRetry(25);
clientConfiguration.setRetryPolicy(new RetryPolicy(null, null, 25, true));
mSnsClient = new AmazonSNSClient(credentials, clientConfiguration);
mSnsClient.setRegion(region);
}
Have you considering looking into the JVM TTL for the DNS Cache?
http://docs.aws.amazon.com/AWSSdkDocsJava/latest//DeveloperGuide/java-dg-jvm-ttl.html

data cache for odata4j

I am implementing a RESTlet service via odata4j on Android.
When running the application there is a constant flow of data, which needs to be sent to a odata server.
The following method get's the new data:
private void freshData(Data data) {
try {
dataTransmitter.sendData(data, this.ptId);
} catch (Exception ex) {
//
}
The following method sends the data to the server:
ODataJerseyConsumer c = ODataJerseyConsumer.create(serviceUrl);
public void sendData(Data data, int ptId) throws Exception {
OEntity newData = c.createEntity(entitySet)
.properties(OProperties.int32("ptID", ptID),
OProperties.double_("data", data.getDouble())))
.execute;
So far no problem. But what if the mobile connection is cut off or lags?
1) Is there way to get the status from execute() (positive send, or no mobile connection for instance).
2) If the send has failed, or is still in progress I somehow need to store the new data to send it, when the old data is out. Is there a feature in odata4j (0.8-SNAPSHOT) available I haven't found, or do I need to do this with a queue for example?
Thank you for the help!

org.smslib port in use exception

I am trying to create web application to send sms by gsm modem in JSP first I put destination mobile number and sms text in url and get by request.getparameter and first message sent with no problem but when send a message again by referenshing the same page i get this exception:
org.smslib.GatewayException: Comm library exception: java.lang.RuntimeException: gnu.io.PortInUseException: org.smslib
at org.smslib.modem.SerialModemDriver.connectPort(SerialModemDriver.java:102)
at org.smslib.modem.AModemDriver.connect(AModemDriver.java:114)
at org.smslib.modem.ModemGateway.startGateway(ModemGateway.java:189)
at org.smslib.Service$1Starter.run(Service.java:276)
I tried to stop gateway and stop service but no hope
My code:
public boolean sendMessage(String strMobileNo,String strSMSText)
{
try
{
OutboundMessage outboundMessage=new OutboundMessage();
SMS message=new SMS();
SerialModemGateway gateway = new SerialModemGateway("modem.com1", "COM12", 9600, "Huawie", "EF200");
gateway.setInbound(true);
gateway.setOutbound(true);
gateway.setSimPin("0000");
gateway.setSmscNumber("+9647701144010");
Service.getInstance().setOutboundMessageNotification(message);
Service.getInstance().addGateway(gateway);
Service.getInstance().startService();
outboundMessage.setText(strSMSText);
outboundMessage.setRecipient(strMobileNo);
outboundMessage.setEncoding(Message.MessageEncodings.ENCUCS2);
//outboundMessage.setDeliveryDelay(5000);
Service.getInstance().sendMessage(outboundMessage);
System.out.println(outboundMessage);
gateway.stopGateway();
Service.getInstance().stopService();
Thread.sleep(10000);
return true;
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
}
The problem in your code is every time a request is made a new SerialModemGateway is created, which should not be done.
Try to have SerialModemGateway gateway = new SerialModemGateway("modem.com1", "COM12", 9600, "Huawie", "EF200"); statement only called once your application run, instead of every time a request is made.
try out this Service.getInstance().stopService() in last of your code its working and you can also terminate your program before running it again
I solved this problem with
Service.getInstance().removeGateway(gateway);

Categories

Resources