Could not convert socket to TLS Spring Mail - spring-boot

I am getting the errors:
org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
nested exception is:
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
Email sender service class:
#Service
public class EmailSenderService {
#Autowired
private JavaMailSender mailSender;
public void sendEmail(String toEmail,
String subject,
String body){
SimpleMailMessage message=new SimpleMailMessage();
message.setFrom("group18proj#gmail.com");
message.setTo(toEmail);
message.setText(body);
message.setSubject(subject);
mailSender.send(message);
System.out.println("Mail Sent Successfully...");
}
Mail Controller:
#Autowired
EmailSenderService emailSenderService;
#RequestMapping("/mail")
public String sendMail(HttpSession session, Model model){
emailSenderService.sendEmail("mrleftgamer#gmail.com","Test","This is the body of the test email");
session.setAttribute("mailMessage", "Check your email");
return "redirect:/dashboard";
}

I experienced the same problem today. My antivirus was at fault. After temporarily disabling Avast the mail sender worked as expected.

Related

Not able to configure durable subscriber in JMS with Spring Boot

I'm using Apache ActiveMQ 5.15.13 and Spring Boot 2.3.1.RELEASE. I'm trying to configure durable subscriber, but I'm not able do do. My application on runtime gives me an error as
Cause: setClientID call not supported on proxy for shared Connection. Set the 'clientId' property on the SingleConnectionFactory instead.
Below is the complete ActiveMQ setup with Spring Boot.
JMSConfiguration
public class JMSConfiguration
{
#Bean
public JmsListenerContainerFactory<?> connectionFactory(ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer)
{
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
// This provides all boot's default to this factory, including the message converter
configurer.configure(factory, connectionFactory);
// You could still override some of Boot's default if necessary.
factory.setPubSubDomain(true);
/* below config to set durable subscriber */
factory.setClientId("brokerClientId");
factory.setSubscriptionDurable(true);
// factory.setSubscriptionShared(true);
return factory;
}
#Bean
public MessageConverter jacksonJmsMessageConverter()
{
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
}
Receiver Class
public class Receiver {
private static final String MESSAGE_TOPIC = "message_topic";
private Logger logger = LoggerFactory.getLogger(Receiver.class);
private static AtomicInteger id = new AtomicInteger();
#Autowired
ConfirmationReceiver confirmationReceiver;
#JmsListener(destination = MESSAGE_TOPIC,
id = "comercial",
subscription = MESSAGE_TOPIC,
containerFactory = "connectionFactory")
public void receiveMessage(Product product, Message message)
{
logger.info(" >> Original received message: " + message);
logger.info(" >> Received product: " + product);
System.out.println("Received " + product);
confirmationReceiver.sendConfirmation(new Confirmation(id.incrementAndGet(), "User " +
product.getName() + " received."));
}
}
application.properties
spring.jms.pub-sub-domain=true
spring.jms.listener.concurrency=1
spring.jms.listener.max-concurrency=2
spring.jms.listener.acknowledge-mode=auto
spring.jms.listener.auto-startup=true
spring.jms.template.delivery-mode:persistent
spring.jms.template.priority: 100
spring.jms.template.qos-enabled: true
spring.jms.template.receive-timeout: 1000
spring.jms.template.time-to-live: 36000
When i try to run application it gives me error as below
Could not refresh JMS Connection for destination 'message_topic' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: setClientID call not supported on proxy for shared Connection. Set the 'clientId' property on the SingleConnectionFactory instead.
My application has standalone producer and consumer. I did try to Google the error but nothing helped.
Late answer. Here is what worked for me.
Use SingleConnectionFactory in place of ConnectionFactory
Set client-id to SingleConnectionFactory
Do not set client-id to factory
public JmsListenerContainerFactory<?> connectionFactory(SingleConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
// Add this
connectionFactory.setClientId("your-client-id")
// Do not do this
//factory.setClientId("brokerClientId");

Getting I/O error while executing JUnit test case for Spring Controller

I am executing a test case to call spring controller (GET method). However, It throws below I/O error.
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8039": Connect to localhost:8039 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect; nested exception is org.apache.http.conn.HttpHostConnectException: Connect to localhost:8039 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:636)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
Below is the test case class that i am executing which throws the above error.
public class GetRuleSetsTests extends PreferencesAdminClientTestApplicationTests<GetRuleSetsResponse>{
#Test
public void testSuccess() throws Exception
{
final String mockedResponseJson = rawJsonFromFile("com/cnanational/preferences/client/rule-sets/getRuleSetsResponse.json");
MockRestServiceServer mockServer = mockServer();
mockServer.expect(requestTo(dummyUri()))
.andExpect(method(HttpMethod.GET))
.andExpect(queryParam("ruleSetDescription", "TestRuleDescription"))
.andRespond(withSuccess(
mockedResponseJson,
MediaType.APPLICATION_JSON));
ServiceClientResponse<GetRuleSetsResponse> response = executeDummyRequest();
mockServer.verify();
assertThat(response.isSuccessful(), equalTo(true));
GetRuleSetsResponse programResponse = response.getParsedResponseObject();
assertThat(programResponse.getRuleSets().size(), equalTo(2));
}
#Override
public URI dummyUri() {
return UriComponentsBuilder.fromUri(baseUri())
.path(this.endpointProperties.getRuleSets())
.build()
.toUri();
}
}
What am i missing? Any inputs appreciated.
If you have configured your test environment properly to run MockRestServiceServer
(by that, I mean #RunWith(SpringRunner.class) and #RestClientTest(ClassUnderTestThatCallsTheMockServer.class)), make sure that you are not instantiating your mock server with = new MockServer(), instead just use an instance that is #Autowired from the spring context (because that instance is configured out of the box).
I see that you have a lot of inheritance and overridden methods in your tests, calling things with this.returnSomething..., so make sure that you are not instantiating things outside of the spring context.
Here is a simple example of a mock server to get some posts:
#RunWith(SpringRunner.class)
#RestClientTest(PostClient.class)
public class PostClientMockTest {
// class under test
#Autowired
private PostClient postClient;
// autowired mock server from the spring context
#Autowired
private MockRestServiceServer mockRestServiceServer;
#Test
public void readPosts() throws Exception {
String mockJsonResponse = "My response";
mockRestServiceServer.expect(requestTo("https://myurl.com/posts?userId=1"))
.andRespond(withSuccess(mockJsonResponse, MediaType.APPLICATION_JSON_UTF8));
List<Post> posts = postClient.readPosts(1);
assertEquals(9, posts.size());
mockRestServiceServer.verify();
}
}
Hope this helps

Error/exception handling in spring boot application

I am trying to develop an application with spring boot. I am stuck on managing exception/error for the application. So far I have service layer and controller and I have created service class specific exceptions. for.eg. AnimalService exception class is AnimalServiceException. Services throw respective ABCServiceException. I am stuck on how to handle exceptions/errors in the controller if there are exceptions there? Specifically for ill-formatted input to api method call. I am reading inputs in Controller. Should I include that in service?
All the service exceptions are returning HTTP code as 500 internal application errors. I want to capture those exceptions somehow but donno how.
What qualifies as error vs exception in spring boot?
I'd suggest you to take a look at #ControllerAdvice of Spring MVC (https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc)
We can create customized exception:
#ResponseStatus(HttpStatus.NOT_FOUND)
public class StudentNotFoundException extends RuntimeException {}
Exception handler in Spring:
#ControllerAdvice
#RestController
public class CustomizedResponseEntityExceptionHandler extends
ResponseEntityExceptionHandler {
#ExceptionHandler(StudentNotFoundException.class)
public final ResponseEntity<ErrorDetails>
handleUserNotFoundException(StudentNotFoundException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(),
request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}

assign name in spring jms topic

I am using spring JMS to connect to WSO2MB server. Everything is working fine, but all listeners are assigned the same id. To make it unique, I provided clientId but it is not working. I am not finding any other field where I can provide the name.
I even provided id on the JMS listener but no success.
#Bean
#ConditionalOnProperty(name="my.listener.active", matchIfMissing = true)
public JmsListenerContainerFactory jmsListenerContainerFactory(#Qualifier("listenerConnectionFactory") ConnectionFactory connectionFactory) throws URLSyntaxException {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setClientId("listener"+listenerTopic);
if (Boolean.valueOf(listenerTopic)) {
factory.setSubscriptionDurable(true);
factory.setPubSubDomain(true);
}
return factory;
}
#JmsListener(destination = "${default-queue-name-to-listen}", id = "${default-queue-name-to-listen}")
public void receiveMessage(final Message<T> message) throws JMSException {
}
each connection need to have a unique clientID
void org.apache.activemq.ActiveMQConnectionFactory.setClientID(String
clientID)
Sets the JMS clientID to use for the created connection.
Note that this can only be used by one connection at once so generally
its a better idea to set the clientID on a Connection
your solution is to use org.springframework.jms.connection.SingleConnectionFactory
subscription name made the connection name unique and resolved my problem
#JmsListener(
destination = "${default-queue-name-to-listen}",
subscription = "${default-queue-name-to-listen}"
)
public void receiveMessage(Message<T> message) throws JMSException {}

Spring WS and HTTPS?

I use Spring WS to send a request to web service (DentalXChange).
private static final String MESSAGE = <xml request/>
private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
public void customSendAndReceive() {
StreamSource source = new StreamSource(new StringReader(MESSAGE));
StreamResult result = new StreamResult(System.out);
webServiceTemplate.sendSourceAndReceiveToResult("https://prelive2.dentalxchange.com/dws/DwsService",
source, result);
}
And here is error
Exception in thread "main" org.springframework.ws.client.WebServiceIOException: I/O error: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext); nested exception is java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
How to solve it. Thanks

Resources