ILYA
ILYA

Reputation: 1

Correct way to make a non-blocking delay in Spring WS (SOAP)

I have a SOAP controller (Java 11, spring-ws 3.1.3), and I need to implement non-blocking delay before responding.

SOAP Controller:

@Endpoint
public class SoapController {

    @PayloadRoot(namespace = "http://mysoapsite.ru/2020/webservice/SingleFormatService", localPart = "AuthData")
    @ResponsePayload
    public SoapResponse responseABC(@RequestPayload AuthData authData, MessageContext messageContext) {
        SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext.getRequest();
        String responseMessage = null;

        try {          

                    String inn = SoapUtility.parseTag(soapRequest.getEnvelope(), "empInn");
                    Map<String, String> params = new HashMap<>();
                    params.put("Inn", inn);
                    params.put("LocalDate", LocalDate.now().toString());
                    StringSubstitutor substitutor = new StringSubstitutor(params);
                    responseMessage = ReadFromFile.readXmlToString("ANSWER");
                    responseMessage = substitutor.replace(responseMessage);  
            }

        } catch (IOException | TransformerException | SAXException e) {
            throw new RuntimeException(e);
        }


        return SoapUtility.convertStringToSoapEnvelope(responseMessage);
    }
}

I have created a class that implements SoapEndpointInterceptor, then I used a blocking delay with TimeUnit.MILLISECONDS.sleep(), which has a significant impact on performance.

Is there a better way to implement non-blocking delay (without Thread.sleep()) ?

Thread.sleep() in implemented class:

public class SoapPrefixAndDelayInterceptor implements SoapEndpointInterceptor {
    private final Long responseDelay=429L;

    private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
    private static final String PREFERRED_PREFIX = "soap";


    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) {
        SaajSoapMessage soapMessage = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapMessage, responseDelay);
        return true;
    }

    private void alterSoapEnvelope(SaajSoapMessage soapResponse, Long delay) {
        try {
            SOAPMessage soapMessage = soapResponse.getSaajMessage();
            SOAPPart soapPart = soapMessage.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPHeader header = soapMessage.getSOAPHeader();
            SOAPBody body = soapMessage.getSOAPBody();
            SOAPFault fault = body.getFault();
            if (header != null) {
                header.detachNode();
            }
            envelope.removeNamespaceDeclaration(envelope.getPrefix());
            envelope.addNamespaceDeclaration(PREFERRED_PREFIX, SOAP_ENV_NAMESPACE);
            envelope.setPrefix(PREFERRED_PREFIX);
            header.setPrefix(PREFERRED_PREFIX);
            body.setPrefix(PREFERRED_PREFIX);
            if (fault != null) {
                fault.setPrefix(PREFERRED_PREFIX);
            }
            TimeUnit.MILLISECONDS.sleep(delay); // <=== WRONG WAY TO MAKE DELAY
        } catch (SOAPException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Upvotes: 0

Views: 64

Answers (0)

Related Questions