org.springframework.boot.webservices.client.HttpWebServiceMessageSenderBuilder Maven / Gradle / Ivy
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.webservices.client;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.function.Supplier;
import org.springframework.boot.web.client.ClientHttpRequestFactorySupplier;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.ws.transport.http.ClientHttpRequestMessageSender;
/**
* {@link WebServiceMessageSender} builder that can detect a suitable HTTP library based
* on the classpath.
*
* @author Stephane Nicoll
* @since 2.1.0
*/
public class HttpWebServiceMessageSenderBuilder {
private Duration connectTimeout;
private Duration readTimeout;
private Supplier requestFactorySupplier;
/**
* Set the connection timeout.
* @param connectTimeout the connection timeout
* @return a new builder instance
*/
public HttpWebServiceMessageSenderBuilder setConnectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
/**
* Set the read timeout.
* @param readTimeout the read timeout
* @return a new builder instance
*/
public HttpWebServiceMessageSenderBuilder setReadTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
return this;
}
/**
* Set the {@code Supplier} of {@link ClientHttpRequestFactory} that should be called
* to create the HTTP-based {@link WebServiceMessageSender}.
* @param requestFactorySupplier the supplier for the request factory
* @return a new builder instance
*/
public HttpWebServiceMessageSenderBuilder requestFactory(
Supplier requestFactorySupplier) {
Assert.notNull(requestFactorySupplier,
"RequestFactory Supplier must not be null");
this.requestFactorySupplier = requestFactorySupplier;
return this;
}
public WebServiceMessageSender build() {
ClientHttpRequestFactory requestFactory = (this.requestFactorySupplier != null)
? this.requestFactorySupplier.get()
: new ClientHttpRequestFactorySupplier().get();
if (this.connectTimeout != null) {
new TimeoutRequestFactoryCustomizer(this.connectTimeout, "setConnectTimeout")
.customize(requestFactory);
}
if (this.readTimeout != null) {
new TimeoutRequestFactoryCustomizer(this.readTimeout, "setReadTimeout")
.customize(requestFactory);
}
return new ClientHttpRequestMessageSender(requestFactory);
}
/**
* {@link ClientHttpRequestFactory} customizer to call a "set timeout" method.
*/
private static class TimeoutRequestFactoryCustomizer {
private final Duration timeout;
private final String methodName;
TimeoutRequestFactoryCustomizer(Duration timeout, String methodName) {
this.timeout = timeout;
this.methodName = methodName;
}
public void customize(ClientHttpRequestFactory factory) {
ReflectionUtils.invokeMethod(findMethod(factory), factory,
Math.toIntExact(this.timeout.toMillis()));
}
private Method findMethod(ClientHttpRequestFactory factory) {
Method method = ReflectionUtils.findMethod(factory.getClass(),
this.methodName, int.class);
if (method != null) {
return method;
}
throw new IllegalStateException("Request factory " + factory.getClass()
+ " does not have a " + this.methodName + "(int) method");
}
}
}