Drop RPC-style remoting

Closes gh-27422
This commit is contained in:
Juergen Hoeller
2021-09-17 08:59:58 +02:00
parent 3c8724ba3d
commit 5822f1bf85
79 changed files with 0 additions and 11653 deletions

View File

@@ -1,163 +0,0 @@
/*
* Copyright 2002-2019 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.remoting.caucho;
import java.io.IOException;
import java.net.InetSocketAddress;
import com.caucho.hessian.client.HessianProxyFactory;
import com.sun.net.httpserver.HttpServer;
import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.util.SocketUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* @author Juergen Hoeller
* @author Sam Brannen
* @since 16.05.2003
*/
public class CauchoRemotingTests {
@Test
public void hessianProxyFactoryBeanWithClassInsteadOfInterface() throws Exception {
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
assertThatIllegalArgumentException().isThrownBy(() ->
factory.setServiceInterface(TestBean.class));
}
@Test
public void hessianProxyFactoryBeanWithAccessError() throws Exception {
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
factory.setServiceInterface(ITestBean.class);
factory.setServiceUrl("http://localhosta/testbean");
factory.afterPropertiesSet();
assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
boolean condition = factory.getObject() instanceof ITestBean;
assertThat(condition).isTrue();
ITestBean bean = (ITestBean) factory.getObject();
assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
bean.setName("test"));
}
@Test
public void hessianProxyFactoryBeanWithAuthenticationAndAccessError() throws Exception {
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
factory.setServiceInterface(ITestBean.class);
factory.setServiceUrl("http://localhosta/testbean");
factory.setUsername("test");
factory.setPassword("bean");
factory.setOverloadEnabled(true);
factory.afterPropertiesSet();
assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
boolean condition = factory.getObject() instanceof ITestBean;
assertThat(condition).isTrue();
ITestBean bean = (ITestBean) factory.getObject();
assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
bean.setName("test"));
}
@Test
public void hessianProxyFactoryBeanWithCustomProxyFactory() throws Exception {
TestHessianProxyFactory proxyFactory = new TestHessianProxyFactory();
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
factory.setServiceInterface(ITestBean.class);
factory.setServiceUrl("http://localhosta/testbean");
factory.setProxyFactory(proxyFactory);
factory.setUsername("test");
factory.setPassword("bean");
factory.setOverloadEnabled(true);
factory.afterPropertiesSet();
assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
boolean condition = factory.getObject() instanceof ITestBean;
assertThat(condition).isTrue();
ITestBean bean = (ITestBean) factory.getObject();
assertThat(proxyFactory.user).isEqualTo("test");
assertThat(proxyFactory.password).isEqualTo("bean");
assertThat(proxyFactory.overloadEnabled).isTrue();
assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
bean.setName("test"));
}
@Test
@SuppressWarnings("deprecation")
public void simpleHessianServiceExporter() throws IOException {
final int port = SocketUtils.findAvailableTcpPort();
TestBean tb = new TestBean("tb");
SimpleHessianServiceExporter exporter = new SimpleHessianServiceExporter();
exporter.setService(tb);
exporter.setServiceInterface(ITestBean.class);
exporter.setDebug(true);
exporter.prepare();
HttpServer server = HttpServer.create(new InetSocketAddress(port), -1);
server.createContext("/hessian", exporter);
server.start();
try {
HessianClientInterceptor client = new HessianClientInterceptor();
client.setServiceUrl("http://localhost:" + port + "/hessian");
client.setServiceInterface(ITestBean.class);
//client.setHessian2(true);
client.prepare();
ITestBean proxy = ProxyFactory.getProxy(ITestBean.class, client);
assertThat(proxy.getName()).isEqualTo("tb");
proxy.setName("test");
assertThat(proxy.getName()).isEqualTo("test");
}
finally {
server.stop(Integer.MAX_VALUE);
}
}
private static class TestHessianProxyFactory extends HessianProxyFactory {
private String user;
private String password;
private boolean overloadEnabled;
@Override
public void setUser(String user) {
this.user = user;
}
@Override
public void setPassword(String password) {
this.password = password;
}
@Override
public void setOverloadEnabled(boolean overloadEnabled) {
this.overloadEnabled = overloadEnabled;
}
}
}

View File

@@ -1,169 +0,0 @@
/*
* Copyright 2002-2019 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.remoting.httpinvoker;
import java.io.IOException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.Configurable;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.withSettings;
/**
* @author Stephane Nicoll
*/
public class HttpComponentsHttpInvokerRequestExecutorTests {
@Test
public void customizeConnectionTimeout() throws IOException {
HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
executor.setConnectTimeout(5000);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
assertThat(httpPost.getConfig().getConnectTimeout()).isEqualTo(5000);
}
@Test
public void customizeConnectionRequestTimeout() throws IOException {
HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
executor.setConnectionRequestTimeout(7000);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
assertThat(httpPost.getConfig().getConnectionRequestTimeout()).isEqualTo(7000);
}
@Test
public void customizeReadTimeout() throws IOException {
HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
executor.setReadTimeout(10000);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
assertThat(httpPost.getConfig().getSocketTimeout()).isEqualTo(10000);
}
@Test
public void defaultSettingsOfHttpClientMergedOnExecutorCustomization() throws IOException {
RequestConfig defaultConfig = RequestConfig.custom().setConnectTimeout(1234).build();
CloseableHttpClient client = mock(CloseableHttpClient.class,
withSettings().extraInterfaces(Configurable.class));
Configurable configurable = (Configurable) client;
given(configurable.getConfig()).willReturn(defaultConfig);
HttpComponentsHttpInvokerRequestExecutor executor =
new HttpComponentsHttpInvokerRequestExecutor(client);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
assertThat(httpPost.getConfig()).as("Default client configuration is expected").isSameAs(defaultConfig);
executor.setConnectionRequestTimeout(4567);
HttpPost httpPost2 = executor.createHttpPost(config);
assertThat(httpPost2.getConfig()).isNotNull();
assertThat(httpPost2.getConfig().getConnectionRequestTimeout()).isEqualTo(4567);
// Default connection timeout merged
assertThat(httpPost2.getConfig().getConnectTimeout()).isEqualTo(1234);
}
@Test
public void localSettingsOverrideClientDefaultSettings() throws Exception {
RequestConfig defaultConfig = RequestConfig.custom()
.setConnectTimeout(1234).setConnectionRequestTimeout(6789).build();
CloseableHttpClient client = mock(CloseableHttpClient.class,
withSettings().extraInterfaces(Configurable.class));
Configurable configurable = (Configurable) client;
given(configurable.getConfig()).willReturn(defaultConfig);
HttpComponentsHttpInvokerRequestExecutor executor =
new HttpComponentsHttpInvokerRequestExecutor(client);
executor.setConnectTimeout(5000);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
RequestConfig requestConfig = httpPost.getConfig();
assertThat(requestConfig.getConnectTimeout()).isEqualTo(5000);
assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(6789);
assertThat(requestConfig.getSocketTimeout()).isEqualTo(-1);
}
@Test
public void mergeBasedOnCurrentHttpClient() throws Exception {
RequestConfig defaultConfig = RequestConfig.custom()
.setSocketTimeout(1234).build();
final CloseableHttpClient client = mock(CloseableHttpClient.class,
withSettings().extraInterfaces(Configurable.class));
Configurable configurable = (Configurable) client;
given(configurable.getConfig()).willReturn(defaultConfig);
HttpComponentsHttpInvokerRequestExecutor executor =
new HttpComponentsHttpInvokerRequestExecutor() {
@Override
public HttpClient getHttpClient() {
return client;
}
};
executor.setReadTimeout(5000);
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
RequestConfig requestConfig = httpPost.getConfig();
assertThat(requestConfig.getConnectTimeout()).isEqualTo(-1);
assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(-1);
assertThat(requestConfig.getSocketTimeout()).isEqualTo(5000);
// Update the Http client so that it returns an updated config
RequestConfig updatedDefaultConfig = RequestConfig.custom()
.setConnectTimeout(1234).build();
given(configurable.getConfig()).willReturn(updatedDefaultConfig);
executor.setReadTimeout(7000);
HttpPost httpPost2 = executor.createHttpPost(config);
RequestConfig requestConfig2 = httpPost2.getConfig();
assertThat(requestConfig2.getConnectTimeout()).isEqualTo(1234);
assertThat(requestConfig2.getConnectionRequestTimeout()).isEqualTo(-1);
assertThat(requestConfig2.getSocketTimeout()).isEqualTo(7000);
}
@Test
public void ignoreFactorySettings() throws IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(httpClient) {
@Override
protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) {
return null;
}
};
HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
HttpPost httpPost = executor.createHttpPost(config);
assertThat(httpPost.getConfig()).as("custom request config should not be set").isNull();
}
private HttpInvokerClientConfiguration mockHttpInvokerClientConfiguration(String serviceUrl) {
HttpInvokerClientConfiguration config = mock(HttpInvokerClientConfiguration.class);
given(config.getServiceUrl()).willReturn(serviceUrl);
return config;
}
}

View File

@@ -1,145 +0,0 @@
/*
* Copyright 2002-2020 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.remoting.httpinvoker;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.remoting.support.RemoteInvocationResult;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor;
import org.springframework.stereotype.Component;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Stephane Nicoll
*/
class HttpInvokerFactoryBeanIntegrationTests {
@Test
@SuppressWarnings("resource")
void testLoadedConfigClass() {
ApplicationContext context = new AnnotationConfigApplicationContext(InvokerAutowiringConfig.class);
MyBean myBean = context.getBean("myBean", MyBean.class);
assertThat(myBean.myService).isSameAs(context.getBean("myService"));
myBean.myService.handle();
myBean.myService.handleAsync();
}
@Test
@SuppressWarnings("resource")
void testNonLoadedConfigClass() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.registerBeanDefinition("config", new RootBeanDefinition(InvokerAutowiringConfig.class.getName()));
context.refresh();
MyBean myBean = context.getBean("myBean", MyBean.class);
assertThat(myBean.myService).isSameAs(context.getBean("myService"));
myBean.myService.handle();
myBean.myService.handleAsync();
}
@Test
@SuppressWarnings("resource")
void withConfigurationClassWithPlainFactoryBean() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ConfigWithPlainFactoryBean.class);
context.refresh();
MyBean myBean = context.getBean("myBean", MyBean.class);
assertThat(myBean.myService).isSameAs(context.getBean("myService"));
myBean.myService.handle();
myBean.myService.handleAsync();
}
interface MyService {
void handle();
@Async
public void handleAsync();
}
@Component("myBean")
static class MyBean {
@Autowired
MyService myService;
}
@Configuration
@ComponentScan
@Lazy
static class InvokerAutowiringConfig {
@Bean
AsyncAnnotationBeanPostProcessor aabpp() {
return new AsyncAnnotationBeanPostProcessor();
}
@Bean
@SuppressWarnings("deprecation")
HttpInvokerProxyFactoryBean myService() {
HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
factory.setServiceUrl("/svc/dummy");
factory.setServiceInterface(MyService.class);
factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult());
return factory;
}
@Bean
FactoryBean<String> myOtherService() {
throw new IllegalStateException("Don't ever call me");
}
}
@Configuration
static class ConfigWithPlainFactoryBean {
@Autowired
Environment env;
@Bean
MyBean myBean() {
return new MyBean();
}
@Bean
@SuppressWarnings("deprecation")
HttpInvokerProxyFactoryBean myService() {
String name = env.getProperty("testbean.name");
HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
factory.setServiceUrl("/svc/" + name);
factory.setServiceInterface(MyService.class);
factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult());
return factory;
}
}
}

View File

@@ -1,453 +0,0 @@
/*
* Copyright 2002-2021 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.remoting.httpinvoker;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.testfixture.beans.ITestBean;
import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationResult;
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* @author Juergen Hoeller
* @since 09.08.2004
*/
@SuppressWarnings("deprecation")
class HttpInvokerTests {
@Test
void httpInvokerProxyFactoryBeanAndServiceExporter() {
doTestHttpInvokerProxyFactoryBeanAndServiceExporter(false);
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithExplicitClassLoader() {
doTestHttpInvokerProxyFactoryBeanAndServiceExporter(true);
}
private void doTestHttpInvokerProxyFactoryBeanAndServiceExporter(boolean explicitClassLoader) {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContent(baos.toByteArray());
exporter.handleRequest(request, response);
return readRemoteInvocationResult(
new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
}
});
if (explicitClassLoader) {
((BeanClassLoaderAware) pfb.getHttpInvokerRequestExecutor()).setBeanClassLoader(getClass().getClassLoader());
}
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThat(proxy.getName()).isEqualTo("myname");
assertThat(proxy.getAge()).isEqualTo(99);
proxy.setAge(50);
assertThat(proxy.getAge()).isEqualTo(50);
proxy.setStringArray(new String[] {"str1", "str2"});
assertThat(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray())).isTrue();
proxy.setSomeIntegerArray(new Integer[] {1, 2, 3});
assertThat(Arrays.equals(new Integer[] {1, 2, 3}, proxy.getSomeIntegerArray())).isTrue();
proxy.setNestedIntegerArray(new Integer[][] {{1, 2, 3}, {4, 5, 6}});
Integer[][] integerArray = proxy.getNestedIntegerArray();
assertThat(Arrays.equals(new Integer[] {1, 2, 3}, integerArray[0])).isTrue();
assertThat(Arrays.equals(new Integer[] {4, 5, 6}, integerArray[1])).isTrue();
proxy.setSomeIntArray(new int[] {1, 2, 3});
assertThat(Arrays.equals(new int[] {1, 2, 3}, proxy.getSomeIntArray())).isTrue();
proxy.setNestedIntArray(new int[][] {{1, 2, 3}, {4, 5, 6}});
int[][] intArray = proxy.getNestedIntArray();
assertThat(Arrays.equals(new int[] {1, 2, 3}, intArray[0])).isTrue();
assertThat(Arrays.equals(new int[] {4, 5, 6}, intArray[1])).isTrue();
assertThatIllegalStateException().isThrownBy(() ->
proxy.exceptional(new IllegalStateException()));
assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
proxy.exceptional(new IllegalAccessException()));
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithIOException() throws Exception {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); });
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThatExceptionOfType(RemoteAccessException.class)
.isThrownBy(() -> proxy.setAge(50))
.withCauseInstanceOf(IOException.class);
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithGzipCompression() {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() {
@Override
protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException {
if ("gzip".equals(request.getHeader("Compression"))) {
return new GZIPInputStream(is);
}
else {
return is;
}
}
@Override
protected OutputStream decorateOutputStream(
HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException {
if ("gzip".equals(request.getHeader("Compression"))) {
return new GZIPOutputStream(os);
}
else {
return os;
}
}
};
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Compression", "gzip");
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContent(baos.toByteArray());
try {
exporter.handleRequest(request, response);
}
catch (ServletException ex) {
throw new IOException(ex.toString());
}
return readRemoteInvocationResult(
new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
}
@Override
protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
return new GZIPOutputStream(os);
}
@Override
protected InputStream decorateInputStream(InputStream is) throws IOException {
return new GZIPInputStream(is);
}
});
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThat(proxy.getName()).isEqualTo("myname");
assertThat(proxy.getAge()).isEqualTo(99);
proxy.setAge(50);
assertThat(proxy.getAge()).isEqualTo(50);
assertThatIllegalStateException().isThrownBy(() ->
proxy.exceptional(new IllegalStateException()));
assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
proxy.exceptional(new IllegalAccessException()));
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithWrappedInvocations() {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() {
@Override
protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
Object obj = ois.readObject();
if (!(obj instanceof TestRemoteInvocationWrapper)) {
throw new IOException("Deserialized object needs to be assignable to type [" +
TestRemoteInvocationWrapper.class.getName() + "]: " + obj);
}
return ((TestRemoteInvocationWrapper) obj).remoteInvocation;
}
@Override
protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos)
throws IOException {
oos.writeObject(new TestRemoteInvocationResultWrapper(result));
}
};
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContent(baos.toByteArray());
exporter.handleRequest(request, response);
return readRemoteInvocationResult(
new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
}
@Override
protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException {
oos.writeObject(new TestRemoteInvocationWrapper(invocation));
}
@Override
protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
Object obj = ois.readObject();
if (!(obj instanceof TestRemoteInvocationResultWrapper)) {
throw new IOException("Deserialized object needs to be assignable to type ["
+ TestRemoteInvocationResultWrapper.class.getName() + "]: " + obj);
}
return ((TestRemoteInvocationResultWrapper) obj).remoteInvocationResult;
}
});
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThat(proxy.getName()).isEqualTo("myname");
assertThat(proxy.getAge()).isEqualTo(99);
proxy.setAge(50);
assertThat(proxy.getAge()).isEqualTo(50);
assertThatIllegalStateException().isThrownBy(() ->
proxy.exceptional(new IllegalStateException()));
assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
proxy.exceptional(new IllegalAccessException()));
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithInvocationAttributes() {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
@Override
public Object invoke(RemoteInvocation invocation, Object targetObject)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
assertThat(invocation.getAttributes()).isNotNull();
assertThat(invocation.getAttributes().size()).isEqualTo(1);
assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue");
assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue");
return super.invoke(invocation, targetObject);
}
});
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setRemoteInvocationFactory(methodInvocation -> {
RemoteInvocation invocation = new RemoteInvocation(methodInvocation);
invocation.addAttribute("myKey", "myValue");
assertThatIllegalStateException().isThrownBy(() ->
invocation.addAttribute("myKey", "myValue"));
assertThat(invocation.getAttributes()).isNotNull();
assertThat(invocation.getAttributes().size()).isEqualTo(1);
assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue");
assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue");
return invocation;
});
pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContent(baos.toByteArray());
exporter.handleRequest(request, response);
return readRemoteInvocationResult(
new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
}
});
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThat(proxy.getName()).isEqualTo("myname");
assertThat(proxy.getAge()).isEqualTo(99);
}
@Test
void httpInvokerProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() {
TestBean target = new TestBean("myname", 99);
final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setServiceInterface(ITestBean.class);
exporter.setService(target);
exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
@Override
public Object invoke(RemoteInvocation invocation, Object targetObject)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
boolean condition = invocation instanceof TestRemoteInvocation;
assertThat(condition).isTrue();
assertThat(invocation.getAttributes()).isNull();
assertThat(invocation.getAttribute("myKey")).isNull();
return super.invoke(invocation, targetObject);
}
});
exporter.afterPropertiesSet();
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl("https://myurl");
pfb.setRemoteInvocationFactory(methodInvocation -> {
RemoteInvocation invocation = new TestRemoteInvocation(methodInvocation);
assertThat(invocation.getAttributes()).isNull();
assertThat(invocation.getAttribute("myKey")).isNull();
return invocation;
});
pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setContent(baos.toByteArray());
exporter.handleRequest(request, response);
return readRemoteInvocationResult(
new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
}
});
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
assertThat(proxy.getName()).isEqualTo("myname");
assertThat(proxy.getAge()).isEqualTo(99);
}
@Test
void httpInvokerWithSpecialLocalMethods() {
String serviceUrl = "https://myurl";
HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
pfb.setServiceInterface(ITestBean.class);
pfb.setServiceUrl(serviceUrl);
pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); });
pfb.afterPropertiesSet();
ITestBean proxy = (ITestBean) pfb.getObject();
// shouldn't go through to remote service
assertThat(proxy.toString().contains("HTTP invoker")).isTrue();
assertThat(proxy.toString().contains(serviceUrl)).isTrue();
assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode());
assertThat(proxy.equals(proxy)).isTrue();
// should go through
assertThatExceptionOfType(RemoteAccessException.class)
.isThrownBy(() -> proxy.setAge(50))
.withCauseInstanceOf(IOException.class);
}
@SuppressWarnings("serial")
private static class TestRemoteInvocation extends RemoteInvocation {
TestRemoteInvocation(MethodInvocation methodInvocation) {
super(methodInvocation);
}
}
@SuppressWarnings("serial")
private static class TestRemoteInvocationWrapper implements Serializable {
private final RemoteInvocation remoteInvocation;
TestRemoteInvocationWrapper(RemoteInvocation remoteInvocation) {
this.remoteInvocation = remoteInvocation;
}
}
@SuppressWarnings("serial")
private static class TestRemoteInvocationResultWrapper implements Serializable {
private final RemoteInvocationResult remoteInvocationResult;
TestRemoteInvocationResultWrapper(RemoteInvocationResult remoteInvocationResult) {
this.remoteInvocationResult = remoteInvocationResult;
}
}
}

View File

@@ -1,161 +0,0 @@
/*
* Copyright 2002-2019 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.remoting.jaxws;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.soap.AddressingFeature;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.remoting.RemoteAccessException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Juergen Hoeller
* @since 2.5
*/
public class JaxWsSupportTests {
@Test
public void testJaxWsPortAccess() throws Exception {
doTestJaxWsPortAccess((WebServiceFeature[]) null);
}
@Test
public void testJaxWsPortAccessWithFeature() throws Exception {
doTestJaxWsPortAccess(new AddressingFeature());
}
private void doTestJaxWsPortAccess(WebServiceFeature... features) throws Exception {
GenericApplicationContext ac = new GenericApplicationContext();
GenericBeanDefinition serviceDef = new GenericBeanDefinition();
serviceDef.setBeanClass(OrderServiceImpl.class);
ac.registerBeanDefinition("service", serviceDef);
GenericBeanDefinition exporterDef = new GenericBeanDefinition();
exporterDef.setBeanClass(SimpleJaxWsServiceExporter.class);
exporterDef.getPropertyValues().add("baseAddress", "http://localhost:9999/");
ac.registerBeanDefinition("exporter", exporterDef);
GenericBeanDefinition clientDef = new GenericBeanDefinition();
clientDef.setBeanClass(JaxWsPortProxyFactoryBean.class);
clientDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl");
clientDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/");
clientDef.getPropertyValues().add("username", "juergen");
clientDef.getPropertyValues().add("password", "hoeller");
clientDef.getPropertyValues().add("serviceName", "OrderService");
clientDef.getPropertyValues().add("serviceInterface", OrderService.class);
clientDef.getPropertyValues().add("lookupServiceOnStartup", Boolean.FALSE);
if (features != null) {
clientDef.getPropertyValues().add("portFeatures", features);
}
ac.registerBeanDefinition("client", clientDef);
GenericBeanDefinition serviceFactoryDef = new GenericBeanDefinition();
serviceFactoryDef.setBeanClass(LocalJaxWsServiceFactoryBean.class);
serviceFactoryDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl");
serviceFactoryDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/");
serviceFactoryDef.getPropertyValues().add("serviceName", "OrderService");
ac.registerBeanDefinition("orderService", serviceFactoryDef);
ac.registerBeanDefinition("accessor", new RootBeanDefinition(ServiceAccessor.class));
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
try {
ac.refresh();
OrderService orderService = ac.getBean("client", OrderService.class);
boolean condition = orderService instanceof BindingProvider;
assertThat(condition).isTrue();
((BindingProvider) orderService).getRequestContext();
String order = orderService.getOrder(1000);
assertThat(order).isEqualTo("order 1000");
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
orderService.getOrder(0))
.matches(ex -> ex instanceof OrderNotFoundException ||
ex instanceof RemoteAccessException);
// ignore RemoteAccessException as probably setup issue with JAX-WS provider vs JAXB
ServiceAccessor serviceAccessor = ac.getBean("accessor", ServiceAccessor.class);
order = serviceAccessor.orderService.getOrder(1000);
assertThat(order).isEqualTo("order 1000");
assertThatExceptionOfType(Exception.class).isThrownBy(() ->
serviceAccessor.orderService.getOrder(0))
.matches(ex -> ex instanceof OrderNotFoundException ||
ex instanceof WebServiceException);
// ignore WebServiceException as probably setup issue with JAX-WS provider vs JAXB
}
catch (BeanCreationException ex) {
if ("exporter".equals(ex.getBeanName()) && ex.getRootCause() instanceof ClassNotFoundException) {
// ignore - probably running on JDK without the JAX-WS impl present
}
else {
throw ex;
}
}
finally {
ac.close();
}
}
public static class ServiceAccessor {
@WebServiceRef
public OrderService orderService;
public OrderService myService;
@WebServiceRef(value = OrderServiceService.class, wsdlLocation = "http://localhost:9999/OrderService?wsdl")
public void setMyService(OrderService myService) {
this.myService = myService;
}
}
@WebServiceClient(targetNamespace = "http://jaxws.remoting.springframework.org/", name="OrderService")
public static class OrderServiceService extends Service {
public OrderServiceService() throws MalformedURLException {
super(new URL("http://localhost:9999/OrderService?wsdl"),
new QName("http://jaxws.remoting.springframework.org/", "OrderService"));
}
public OrderServiceService(URL wsdlDocumentLocation, QName serviceName) {
super(wsdlDocumentLocation, serviceName);
}
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2002-2019 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.remoting.jaxws;
import javax.xml.ws.WebFault;
/**
* @author Juergen Hoeller
*/
@WebFault
@SuppressWarnings("serial")
public class OrderNotFoundException extends Exception {
private final String faultInfo;
public OrderNotFoundException(String message) {
super(message);
this.faultInfo = null;
}
public OrderNotFoundException(String message, String faultInfo) {
super(message);
this.faultInfo = faultInfo;
}
public String getFaultInfo() {
return this.faultInfo;
}
}

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2002-2007 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.remoting.jaxws;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
/**
* @author Juergen Hoeller
*/
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface OrderService {
String getOrder(int id) throws OrderNotFoundException;
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2002-2012 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.remoting.jaxws;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import org.springframework.util.Assert;
/**
* @author Juergen Hoeller
*/
@WebService(serviceName="OrderService", portName="OrderService",
endpointInterface = "org.springframework.remoting.jaxws.OrderService")
public class OrderServiceImpl implements OrderService {
@Resource
private WebServiceContext webServiceContext;
@Override
public String getOrder(int id) throws OrderNotFoundException {
Assert.notNull(this.webServiceContext, "WebServiceContext has not been injected");
if (id == 0) {
throw new OrderNotFoundException("Order 0 not found");
}
return "order " + id;
}
}