Migration to EWS API for sending emails - attributes

I have the following code to send a email through EWS API,
ExchangeService service = new ExchangeService();
service.setUrl(new URI(**MyExchangeURL**));
ExchangeCredentials credentials = new WebCredentials(**UserName**, **Password**);
service.setCredentials(credentials);
EmailMessage message = new EmailMessage(service);
message.setSubject("EWS Test Mail");
message.setBody(MessageBody.getMessageBodyFromText("This is a test mail from EWS"));
message.getToRecipients().add("Test#gmail.com");
message.send();
With the above code, I facing a null pointer exception when message.send() is called.
Log:
Exception in thread "main" microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. null
at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:74)
at microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:158)
at microsoft.exchange.webservices.data.core.ExchangeService.internalCreateItems(ExchangeService.java:598)
at microsoft.exchange.webservices.data.core.ExchangeService.createItem(ExchangeService.java:657)
at microsoft.exchange.webservices.data.core.service.item.Item.internalCreate(Item.java:245)
at microsoft.exchange.webservices.data.core.service.item.EmailMessage.internalSend(EmailMessage.java:147)
at microsoft.exchange.webservices.data.core.service.item.EmailMessage.send(EmailMessage.java:258)
at EWS.main(EWS.java:28)
Caused by: java.lang.NullPointerException
at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.readResponse(ServiceRequestBase.java:369)
at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:63)
... 7 more
When debugged further there is a mismatch in the attribute name.
In request, the attribute is contentType is setted in request. But while reading the response, we are getting Null as code used have Content-type. There is a mismatch in the attribute name being set and read.
Is anyone else facing this issue or any workaround?

Related

Servicestack JsonClient - Object reference not set to an instance of an object

We have a basic servicestack frontend that sends using the jsonclient to backend services and works for the past few years.
I am trying to investigate why we are receiving the below exception on any frontend JSON Client.get requests,
System.NullReferenceException
Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Collections.Specialized.NameObjectCollectionBase.BaseGetAllKeys()
at System.Collections.Specialized.NameValueCollection.get_AllKeys()
at ServiceStack.PclExportClient.AddHeader(WebRequest webReq, NameValueCollection headers)
at ServiceStack.ServiceClientBase.PrepareWebRequest(String httpMethod, String requestUri, Object request, Action`1 sendRequestAction)
at ServiceStack.ServiceClientBase.SendRequest(String httpMethod, String requestUri, Object request)
at ServiceStack.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
at ABC.api.InitializationService.Any(InitializationRequest request) in C:\.....\api\InitializationService.cs:line 27
It's strange, and i'm trying to reproduce this issue by hitting the breakpoint, and nulling / modifying the headers, but can't reproduce or figure out what this issue is.
To me, doesn't the exception imply the header base keys are null, and it can't be retrieved - but how does that occur ?
Using ServiceStack 5.80
ASP.NET MVC
.Net Framework 4.6.1
EDIT:
Calling line of code that produces this issue is
var deviceResult = client.Get(new DRequest{ U = r.D });

Revenuecat Webhook Issue

I have implemented webhook for revenuecat in .net core C#. But for some reason I am getting 400 badrequest with empty response. I am mostly sure that I am not getting the json response in webook through revenuecat for any of the event occurring.
I have also added endpoint on revenue cat webhook with authentication. I have tried several time and as I have not way to test this on local machine. I need help from revenue cat team to provide some reference doc with sample implementation just to get proper json response. Below is the code snippet that I am using to get json response from the webhook endpoint added in revenuecat.
var webHookSecret = _configuration[Constants.RevenueCatWebHookSecret]; var headerAuthorization = HttpContext.Request.Headers["Authorization"].ToString(); #region Check authorization if (webHookSecret == headerAuthorization) { json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync(); } else { _logger.Information($"Un-Authorized token access in revenuecat webhook. Returning BadRequest response."); throw new APIException(HttpStatusCode.Unauthorized, new APIError(_configuration, "InternalServerError")); }

What's the best way to handle reconnection with MqttPahoMessageHandler as token has now expired?

I have used the following example as a basis for my own code to publish to a MQTT server: https://github.com/spring-projects/spring-integration-samples/blob/master/basic/mqtt/src/main/java/org/springframework/integration/samples/mqtt/Application.java
I have a particular use case where the password is a token in particular a keycloak token which will expire. If for whatever reason the spring application loses connection with the MQTT server and tries to reconnect the token will have expired and an MqttSecurityException: Not authorized to connect exception will be thrown. I tried extending the method connectionLost in MqttPahoMessageHandler but as the MqttPahoClientFactory & IMqttAsyncClient are private final there is not much I can do. Wondering if there is any other approach I've not thought of or is the library just not meant to be used like this???
Thanks for any replies.
We get the MqttConnectOptions from the client factory each time we try to connect so you should be able to just update the password there.
If that doesn't work for some reason, open a new feature request.
EDIT
Regarding your comment, what's wrong with this?
#Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
MqttConnectOptions options = new MqttConnectOptions();
options.setServerURIs(new String[] { "tcp://localhost:1883" });
options.setUserName("guest");
options.setPassword("guest".toCharArray());
factory.setConnectionOptions(options);
return factory;
}
#Bean
public ApplicationRunner runner(MqttPahoClientFactory mqttClientFactory, MqttPahoMessageHandler handler) {
return args -> {
Thread.sleep(30_000);
System.out.println("Changing password");
mqttClientFactory.getConnectionOptions().setPassword("foo".toCharArray());
handler.stop();
handler.start();
};
}
foo
2020-03-10 17:42:33.560 INFO 95638 --- [iSampleConsumer] siSample
: foo sent to MQTT, received from MQTT
Changing password
foo
2020-03-10 17:43:08.705 ERROR 95638 --- [ask-scheduler-3] o.s.integration.handler.LoggingHandler
: org.springframework.messaging.MessageHandlingException: error occurred in message handler [bean 'mqttOutbound' for component 'mqttOutFlow.org.springframework.integration.config.ConsumerEndpointFactoryBean#1'; defined in: 'com.example.demo.So60610337Application'; from source: 'org.springframework.core.type.StandardMethodMetadata#79da8dc5']; nested exception is org.springframework.messaging.MessagingException: Failed to connect; nested exception is Bad user name or password (4), failedMessage=GenericMessage [payload=foo sent to MQTT, headers={id=4eab5b52-726f-7ea3-252d-77c4d0401cc8, timestamp=1583876588662}]
...
Caused by: Bad user name or password (4)

Why am I getting javax.xml.bind.UnmarshalException when calling a soap web service

I am trying consume a SOAP web Service and I have written my SOAP client using Spring-ws. This also included a message signing. However when I am trying to trigger a request I am getting the exception. From the server standpoint, the server is sending a successful response but I am not able to unmarshall it.
I followed quite a few suggestion including one from this
UnmarshallingFailureException, unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault")
Following the above link however removed the exception but in turn I am getting a null response object and I could not trace out where the response went missing.
This is my Config class methods:
public WebServiceTemplate accountsInquiryWebServiceTemplate() throws Exception {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
Jaxb2Marshaller accountsInquiryMarshaller = accountsInquiryMarshaller();
webServiceTemplate.setMarshaller(accountsInquiryMarshaller);
webServiceTemplate.setUnmarshaller(accountsInquiryMarshaller);
ClientInterceptor[] clientInterceptors = new ClientInterceptor[1];
clientInterceptors[0] = wsClientSecurityInterceptor();
webServiceTemplate.setInterceptors(clientInterceptors);
webServiceTemplate.setCheckConnectionForFault(true);
webServiceTemplate.setDefaultUri(serviceURL);
return webServiceTemplate;
}
private Jaxb2Marshaller accountsInquiryMarshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPaths(new String[]{
"com.accounting.integrationservice"
});
return jaxb2Marshaller;
}
private Wss4jSecurityInterceptor wsClientSecurityInterceptor() throws Exception {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("Signature");
wss4jSecurityInterceptor.setSecurementUsername(username);
wss4jSecurityInterceptor.setSecurementPassword(password);
wss4jSecurityInterceptor.setSecurementSignatureCrypto(clientCrypto());
wss4jSecurityInterceptor.setValidationActions("Signature");
return wss4jSecurityInterceptor;
}
private Crypto clientCrypto() throws Exception {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setKeyStoreLocation(resourceLoader.getResource("classpath:accountsInquiry/keystore/" + keyStoreLocation));
cryptoFactoryBean.setKeyStorePassword(keyStorePassword);
cryptoFactoryBean.afterPropertiesSet();
return cryptoFactoryBean.getObject();
}
The client calls as below:
Response response = accountsWebServiceTemplate.marshalSendAndReceive(request);
The exception stack that I am getting is as below : Its similar to the referred link above, so not putting the entire exception stack
org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleResponse(AbstractWsSecurityInterceptor.java:247)
- Could not validate request: No WS-Security header found
org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Fault"). Expected elements are http://www.qualityaccounts.com/IntegrationService/schemas/ProductInfo/v1}
at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:911)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:784)
at org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62)
at org.springframework.ws.client.core.WebServiceTemplate$3.extractData(WebServiceTemplate.java:413)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:619)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
Ok So, I was trying to use "Signature" to validate the Security Header of the response even though there was no header. But thing is if I didn't specify the ValidationAction it was throwing NullPointerException so it was expecting at least one ValidationAction.
To counter all this I told the Spring security not to validate the response by this piece of code.
wss4jSecurityInterceptor.setValidateResponse(false);
Thanks to this article
Spring Security - Wss4jSecurityInterceptor - Nullpointer

RabbitMQ, EasyNetQ With NodeJS?

I'm trying to understand what's reasonable for integrating these technologies. How would I go about integrating NodeJS (currently using amqplib, but that could be changed) across RabbitMQ to EasyNetQ?
I have it sort of working, except EasyNetQ is expecting an object (I think) and Node/amqplib can only send strings.
C# code:
Bus.Subscribe<BusManifestHolla>(HollaID,
msg => {
Console.WriteLine("Received Manifest Holla ID {0}", msg.ManifestID.ToString());
Console.WriteLine("Responding with Manifest Yo ID {0}", YoID_1);
Bus.Publish(new BusManifestYo { ManifestID = msg.ManifestID, ServiceName = YoID_1 });
}
);
NodeJS code:
var b = new Buffer(JSON.stringify(new dto.BusManifestHolla(uuid.v4())));
ch.publish(Play.exchangeName, '#', b);
The result:
DEBUG: HandleBasicDeliver on consumer: a60b7760-e22f-4685-9f65-039bef19f58c, deliveryTag: 1
DEBUG: Recieved
RoutingKey: '#'
CorrelationId: ''
ConsumerTag: 'a60b7760-e22f-4685-9f65-039bef19f58c'
DeliveryTag: 1
Redelivered: False
ERROR: Exception thrown by subscription callback.
Exchange: 'RabbitMon.BusManifestHolla:RabbitMon'
Routing Key: '#'
Redelivered: 'False'
Message:
{"Guid":"a6cf174d-9b77-4558-bbda-efe9d8451dff"}
BasicProperties:
ContentType=NULL, ContentEncoding=NULL, Headers=[], DeliveryMode=0, Priority=0, CorrelationId=NULL, ReplyTo=NULL, Expiration=NULL, MessageId=NULL, Timestamp=0, Type=NULL, UserId=NULL, AppId=NULL, ClusterId=
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
at EasyNetQ.TypeNameSerializer.DeSerialize(String typeName)
at EasyNetQ.RabbitAdvancedBus.<>c__DisplayClass16.<Consume>b__15(Byte[] body, MessageProperties properties, MessageReceivedInfo messageRecievedInfo)
at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandler(ConsumerExecutionContext context)
Is there not a way to send an object across the bus? How do you integrate these two?
It's failing on the TypeNameSerializer.DeSerialize call. In your node code you'll need to populate BasicProperties.Type with the type that EasyNetQ should expect at the other end. This needs to be a fully qualified name including the assembly name. Just look at the name that EasyNetQ has given to your BusManifestHolla queue minus the HollaID value (and underscore).
Admittedly that error message isn't very helpful. It probably could be improved.

Resources