Существует приложение с весенней загрузкой, которое подключается к службе на основе SOAP. Наше приложение имеет прослушиватель MQ, который получает сообщения из локальной очереди. После того как сообщение удалено из этой очереди, оно выполняет API-вызов к службе.
Вся связь с SOAP службой осуществляется через двухсторонний SSL.
Теперь мы столкнулся с проблемой при подключении к услуге SOAP. Отсутствует ошибка цепочки сертификатов клиента, полученная периодически на конце службы SOAP.
В нашем классе JmsConfig мы установили параллелизм на фабрике приемника на 10, как показано ниже для одновременного выполнения и параллельной обработки сообщений из очереди.
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
try {
factory.setConnectionFactory(cachingConnectionFactory(jmsConnectionFactoryX20()));
factory.setConcurrency("10");
} catch (JMSException e) {
e.printStackTrace();
}
return factory;
}
Когда мы дополнительно вызываем службу SOAP из приложения весенней загрузки после использования сообщений, в большинстве журналов службы SOAP появляется ошибка отсутствующей цепочки сертификатов клиента. При массовой загрузке 1k сообщений в очередь и при одновременном выполнении после этого около 850 сообщений завершилось с ошибкой в SOAP конце службы и только 150 прошло.
Ошибка приходит только тогда, когда параллелизм устанавливается программно, как показано через приведенный выше фрагмент кода. Если я закомментирую вызов setConcurrency, все сообщения 1k обрабатываются на SOAP конце службы без какой-либо ошибки цепочки сертификатов.
Не могли бы вы взглянуть на нашу конфигурацию и поделиться некоторыми соображениями о том, почему параллелизм вызывает эта ошибка.
ApplicationWebServiceImpl. java (вызов метода callWebService () из метода прослушивателя JMS)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.SoapMessage;
@Service
public class ApplicationWebServiceImpl implements ApplicationWebServices {
@Autowired
private WebServiceTemplate wsTemplate;
@Value("${soap.clientEndpoint}")
private String clientEndpoint;
@Value("${soap.action}")
private String soapAction;
@Override
public Object callWebService(Object request, String serviceName) throws ClientApplicationException {
return wsTemplate.marshalSendAndReceive(clientEndpoint + serviceName, request, message -> {
SoapMessage msg = (SoapMessage) message;
msg.setSoapAction(soapAction + StringUtils.capitalize(serviceName));
});
}
}
ClientApplication (весенняя загрузка основной класс)
@SpringBootApplication
@ComponentScan("com.abc.ca")
public class ClientApplication {
@Value(value = "${cert.keyStoreFileName}")
private String keyStoreFileName;
@Value(value = "${cert.trustStoreFileName}")
private String trustStoreFileName;
@Value(value = "${cert.disabledAlgorithms}")
private String disabledAlgorithms;
@PostConstruct
public void getKeyTrustStore() {
Security.setProperty("jdk.certpath.disabledAlgorithms", disabledAlgorithms);
String filePath = Thread.currentThread().getContextClassLoader().getResource(keyStoreFileName).getFile();
System.setProperty("javax.net.ssl.keyStore", filePath);
System.setProperty("javax.net.ssl.keyStorePassword", "changeme");
filePath = Thread.currentThread().getContextClassLoader().getResource(trustStoreFileName).getFile();
System.setProperty("javax.net.ssl.trustStore", filePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeme");
}
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}