I tried to run typescript code that send email using EWS, it works fine.
But when, I run the java code its throws unauthorized error,
Caused by: microsoft.exchange.webservices.data.core.exception.http.HttpErrorException: The remote server returned an error: (401) Unauthorized
microsoft.exchange.webservices.data.core.exception.service.ServiceRequestException: The request failed. The request failed. The remote server returned an error: (401) Unauthorized
I assume it because the Ts code include this line:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
So the question is how to do this line in java?
Also, do you think there is any other thing I need to add, in order to make the java code work?
Here is the java code...
#Configuration
public class MailConfig {
#Bean(name = "mailExchangeService")
public ExchangeService buildExchangeService() throws URISyntaxException {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
service.setCredentials(new WebCredentials("email", "password", "domain"));
service.setUrl(new URI("https://mail.address.something:4567/ews/exchange.asmx"));
service.setWebProxy(new WebProxy("proxy", 1234));
return service;
}
}
#service
#RequiredArgsConstructor
public class MailService {
#Resource(name = "mailExchangeService")
private final ExchangeService service;
public EmailMessage sendMail(String subscription, String subject, String body, File csvFiles) {
EmailMessage message = null;
try{
message = new EmailMessage(this.service);
message.setItemClass("IPM.Note");
message.setSubject(subject);
message.setBody(new MessageBody(bodyType.HTML, body));
message.getAttachments().addFileAttachment(csvFiles.getAbsolutePath());
message.getToRecipients().add(subscription);
message.send();
}catch (Exception e) {
log.error("Error while sending mail", e);
}
return message;
}
}
Related
service code
public void call(String number, String text) {
try {
StartOutboundVoiceContactRequest request = StartOutboundVoiceContactRequest.builder()
.instanceId(properties.getInstanceId())
.contactFlowId(properties.getContactFlowId())
.queueId(properties.getQueueId())
.destinationPhoneNumber(number)
//.attributes(Map.of("promptText", text))
.build();
System.err.println(connectClient.toString());
connectClient.startOutboundVoiceContact(request);
}catch(Exception e){
e.printStackTrace();
}
software.amazon.awssdk.services.connect.model.ConnectException: The security token included in the request is invalid. (Service: Connect, Status Code: 403, Request ID: xxxxxxxxxxxxxxxxx, Extended Request ID: null)
how to fix above error
aws config
#Bean
public ConnectClient connectClient(AWSConnectConfigurationProperties properties) {
return ConnectClient.builder()
.region(Region.US_EAST_1)
.build();
}
Followed this tutorial regarding websockets (https://www.baeldung.com/websockets-spring) and this works locally on my computer.
My issue is that calling the method directly with an endpoint (/send) does not send a message to all subscribed users, only when stompclient talks to the #MessageMapping directly.
#MessageMapping("/liveoffers")
#SendTo("/topic/messages")
public OutputMessage send(final Message message) throws Exception {
final String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
#GetMapping(value = "/send")
#ResponseStatus(HttpStatus.OK)
public void invokeSend() throws Exception {
send(new Message("from", "text"));
}
Is there anyway I can call the #MessageMapping in a similar way below but actually have it functioning?
Have you considered using SimpMessagingTemplate to send a message instead of calling a mapped method?
#Autowired
SimpMessagingTemplate template;
#GetMapping(value = "/send")
#ResponseStatus(HttpStatus.OK)
public void invokeSend() throws Exception {
template.convertAndSend("/topic/messages", new Message("from", "text"));
}
I have an Microservice and it gets an response from another. And based on the response I get I need to respond accordingly. I have no complete List of Error code I can receive, so the question is - can I generate error codes on the fly for my own response? From what I saw in spring the responses are predefined in code. I need to be flexible.
For example:
I receive a 409 I will respond with 409
I receive a 400 I will respond with 400
I receive a XXX code I will respond with XXX.
Try this code: (Sample code)
#RequestMapping(value = "/validate", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<ErrorBean> validateUser(#QueryParam("jsonInput") final String jsonInput) {
int numberHTTPDesired = 400;
ErrorBean responseBean = new ErrorBean();
responseBean.setError("ERROR");
responseBean.setMessage("Error in validation!");
return new ResponseEntity<ErrorBean>(responseBean, HttpStatus.valueOf(numberHTTPDesired));
}
I have worked on such a use case using the following concept. Try to create a generic exception across micro services. Take 2 params in the exception as error message and another one as error code. Throw the exception from the service being called and catch the same exception in the calling service in the rest template or feign client call.
public class MyException extends Exception {
private String errorCode;
public MyException() {
super();
}
public MyException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
}
--
try {
return myApiService.getUser();//call to myApiService microservice
} catch (MyException e) {
logger.error("Error: {}", e.getMessage());
throw new MyException(e.getMessage(), e.getCode());
}
I currently have a spring boot application (version - 2.1.8.RELEASE) which exposed rest webservice that provide some basic email functionality. I have added swagger component to it and can test the webservice through swagger UI interface. For example when I test the webservice through swagger UI and I don't input mandatory field such as mailfrom I got a error message that states emailfrom is missing with a status code which is what i am expecting.
But when the same scenario is carried out with a spring mvc project(client for web service - spring version 3.2.5.RELEASE) no description of the error is displayed as i was expecting to have the same behavior when testing with swagger Ui above. Please see screenshot result when carrying out integration test below the result is 500 null:
Pleas find below spring boot application rest controller below:
#RestController
#RequestMapping("/email")
public class EmailController {
private static final Logger LOG = LoggerFactory.getLogger(EmailController.class);
#Autowired
SendMailService sendMailService;
#ApiOperation(value = "This service send mail based on the information provided from EmailRequestDto", response = String.class)
#PostMapping(value = "/sendMail")
public #ResponseBody ResponseEntity<String> sendMail(#RequestBody EmailRequestDto emailRequestDto) {
LOG.debug("calling method sendMail");
sendMailService.sendEmail(emailRequestDto);
return new ResponseEntity<>("Mail has been sent successfully", HttpStatus.OK);
}
Please find below part of service class for sending e mail:
#Component
public class SendMailServiceImpl implements SendMailService {
private static final Logger LOG = LoggerFactory.getLogger(SendMailServiceImpl.class);
#Autowired
private JavaMailSender javaMailSender;
/**
* {#inheritDoc}
*/
#Override
public void sendEmail(EmailRequestDto emailRequestDto) {
LOG.debug("calling method sendMail");
if (!ObjectUtils.isEmpty(emailRequestDto)) {
MimeMessage msg = javaMailSender.createMimeMessage();
// true = multipart message
MimeMessageHelper helper;
try {
helper = new MimeMessageHelper(msg, true);
helper.setFrom(emailRequestDto.getMailFrom());
helper.setTo(emailRequestDto.getMailTo().stream().toArray(String[]::new));
helper.setSubject(emailRequestDto.getSubject());
helper.setText(emailRequestDto.getEmailContent(), true);
// helper.addAttachment("my_photo.png", new ClassPathResource("android.png"));
javaMailSender.send(msg);
} catch (MessagingException e) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Error occurred while send mail", e);
}
}
}
Please find below my integration test for calling the web service from the client project:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath*:dummy-service-test-context.xml" })
public class SendMailServiceTest {
#Test
public void testService() {
final String uri = "http://localhost:8080/email-service/email/sendMail";
EmailRequestDto emailRequestDto = new EmailRequestDto();
// emailRequestDto.setMailTo((Arrays.asList("dummy#gmail.com")));
// emailRequestDto.setEmailContent("Dear Sir");
// emailRequestDto.setMailFrom("dummy_38#hotmail.com");
// emailRequestDto.setSubject("Sending Email subject");
emailRequestDto.setMailTo(null);
emailRequestDto.setEmailContent(null);
emailRequestDto.setMailFrom(null);
emailRequestDto.setSubject(null);
HttpEntity<EmailRequestDto> request = new HttpEntity<>(emailRequestDto);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> es = restTemplate.exchange(uri, HttpMethod.POST, request,String.class);
// ResponseEntity<?> response = restTemplate.postForEntity(uri, request, ResponseEntity.class, new HashMap());
Assert.assertTrue(es.getStatusCode().equals(HttpStatus.OK));
}
}
Please find my emailDto below:
#Getter
#Setter
#ApiModel
public class EmailRequestDto implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> mailTo;
#ApiModelProperty(value = "Email address who is sending the mail", required = true)
#NonNull
private String mailFrom;
#ApiModelProperty(value = "Subject of the mail", required = true)
#NonNull
private String subject;
#ApiModelProperty(value = "The content of the mail", required = true)
#NonNull
private String emailContent;
private List<String> bcc;
#ApiModelProperty(value = "This attribute identify if the mail content should be sent as html or plain text", required = true)
#NonNull
boolean fileHtml;
Can anyone point to me what i am doing wrong and why i am getting 500 null please?
When I insert the dateFrom null purposely to force the application to fail in the spring boot tomcat log the exception is correct :
mailFrom is mandatory:
nested exception is com.fasterxml.jackson.databind.JsonMappingException: mailFrom is marked non-null but is null
But in my client integration test it is :
org.springframework.web.client.HttpClientErrorException: 400 null
i have implemented rest webservices using Jersey, and whenever some exception occur on the server side, the client gets a generic HTTP 500 Internal Server Error, with no more info of the real exception. I found that people usually catch any exception on the server side, then throws a WebApplicationException, but even this way the client keeps getting the generic HTTP 500 Internal Server Error.
This is my webservice:
#PUT
#Produces(MediaType.APPLICATION_XML)
#Consumes(MediaType.APPLICATION_XML)
#Path("/transmitir")
public WrapperTransmissaoRetorno receber(WrapperTransmissao wrapperRecepcao) {
WrapperTransmissaoRetorno retorno = new WrapperTransmissaoRetorno();
retorno.setCodigoMaster(new Random().nextInt());
retorno.setDataRetorno(new Date());
if(true){
throw new WebApplicationException("Este pau eh bem graudo");
}
return retorno;
}
This is the code that calls the client:
try {
WsTransmissaoCliente client = new WsTransmissaoCliente();
WrapperTransmissao wrapperRecepcao = new WrapperTransmissao();
Transferencia transferencia = new Transferencia();
transferencia.setCodigoTabela(23);
transferencia.setCodigoTransferencia(56);
transferencia.setDataRetorno(new Date());
transferencia.setDataTransmissao(new Date(System.currentTimeMillis()+3000000));
transferencia.setNomeTabela("CUPOM");
transferencia.setTipoOperacao(TipoOperacao.UPDATE);
wrapperRecepcao.setTransferencia(transferencia);
Jumento jumento = new Jumento();
jumento.setIdade(24);
jumento.setNome("José");
wrapperRecepcao.setObjeto(jumento);
// Cabrito cabrito = new Cabrito();
// cabrito.setAltura(56);
// cabrito.setPeso(120.0);
// wrapperRecepcao.setObjeto(cabrito);
WrapperTransmissaoRetorno retorno = client.transmitir(wrapperRecepcao);
System.out.println("Retorno do WS: "+retorno);
} catch (Exception e) {
WebApplicationException exx = (WebApplicationException) e;
exx.printStackTrace();
}
How to avoid this and get the real exception? Or at least the message?
UPDATE
Here is the object i am sending as a response:
package br.atualy.integracaocheckout.wrappers;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class WrapperTransmissaoRetorno {
private Date dataRetorno;
private Integer codigoMaster;
public Date getDataRetorno() {
return dataRetorno;
}
public void setDataRetorno(Date dataRetorno) {
this.dataRetorno = dataRetorno;
}
public Integer getCodigoMaster() {
return codigoMaster;
}
public void setCodigoMaster(Integer codigoMaster) {
this.codigoMaster = codigoMaster;
}
#Override
public String toString() {
return "WrapperRecepcaoRetorno{" + "dataRetorno=" + dataRetorno + ", codigoMaster=" + codigoMaster + '}';
}
}
UPDATE 2
And here is the client:
import br.atualy.integracaocheckout.wrappers.WrapperTransmissao;
import br.atualy.integracaocheckout.wrappers.WrapperTransmissaoRetorno;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
public class WsTransmissaoCliente {
private final WebTarget webTarget;
private final Client client;
private static final String BASE_URI = "http://localhost:8080/IntegracaoCheckout/webresources";
public WsTransmissaoCliente() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("transmissao");
}
// public String receber() throws ClientErrorException {
// WebTarget resource = webTarget;
// resource = resource.path("receber");
// return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(String.class);
// }
public WrapperTransmissaoRetorno transmitir(WrapperTransmissao requestEntity) throws ClientErrorException {
return webTarget.path("transmitir")
.request(javax.ws.rs.core.MediaType.APPLICATION_XML)
.put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_XML), WrapperTransmissaoRetorno.class);
}
public void close() {
client.close();
}
}
If using jawax.ws.rs.core.Response object.
SERVER :: In case of exception/failure set it as :
// do stuff
// here e.getMessage() can be custom failure message too
response = Response.serverError().entity(e.getMessage()).build();
// return response object
return response;
CLIENT :: On the client side check following :
if(response != null && reponse.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
String serverErrorMsg = response.readEntity(String.class);
throw new Exception(serverErrorMsg);
}
Generally it's better to declare your method as returning a Response object instead of a user-defined type, and set the data as the entity. Then if you want to indicate that an exception has happened, you can just pass that exception as the entity of the Response you are returning.
e.g.
#GET
#Path("/foo")
public Response getFoo() {
try {
// do stuff
return Response.ok(someData).build();
} catch (Exception e) {
return Response.serverError().entity(e).build();
}
}
You'll notice that this way you don't ever end up actually throwing an exception out of your method, but rather return an explicit 500 response with an exception as the entity. This way you can still throw exceptions out of your code, but they'll be handled nicely.
EDIT
I'm not sure what your client wrapper code is doing, but you can pass the expected response data type into your call with the normal REST client:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo.com/foo");
String response = target.request().get(String.class);
or you can also pull it out of the Response using the readEntity() method:
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://foo.com/foo");
Response response = target.request().get();
String entity = response.readEntity(String.class);
It sounds like what you need to do is check the return code, and then parse the entity as a either a WrapperTransmissaoRetorno or a WebApplicationException depending on what code was returned:
Response response = client.transmitir(wrapperRecepcao);
if (response.getStatus() == Response.Status.OK.getStatusCode()) { // 200
WrapperTransmissaoRetorno retorno = response.readEntity(WrapperTransmissaoRetorno.class);
// do stuff
} else if (response.getStatus() == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) { // 500
WebApplicationException e = response.readEntity(WebApplicationException.class);
// do stuff
} // etc for other response codes
Use response object in webapplication excemption. It should work.
From java docs:
WebApplicationException(String message)
Construct a new instance with a blank message and default HTTP status code of 500.
Its a blank message. I haven't tried it myself. I guess this is the problem.
https://jersey.java.net/apidocs/2.6/jersey/javax/ws/rs/WebApplicationException.html
Even after all the suggestions i could not manage to throw the exception to the client.
So what i did was to put a String property inside my returning class, so when an exception occurs on the server side, this String will contain the exception message and i can get it on the client.