diff --git a/pom.xml b/pom.xml index baa0d3c..2ca84aa 100644 --- a/pom.xml +++ b/pom.xml @@ -19,10 +19,9 @@ Проксик для тестирования и эмуляции запросов к банку - 8022 - 8080 - ${service.port} ${service.secondary.ports} - ${server.port} + 8022 + 8080 + ${server.port} ${server.rest.port} UTF-8 Anatoly Cherkasov <a.cherkasov@rbkmoney.com> 2a8b44ac628c1bdb729abd04ed7a2a54676e574b diff --git a/src/main/java/com/rbkmoney/proxy/mocketbank/configuration/TomcatEmbeddedConfiguration.java b/src/main/java/com/rbkmoney/proxy/mocketbank/configuration/TomcatEmbeddedConfiguration.java index 9d01a96..e59d23c 100644 --- a/src/main/java/com/rbkmoney/proxy/mocketbank/configuration/TomcatEmbeddedConfiguration.java +++ b/src/main/java/com/rbkmoney/proxy/mocketbank/configuration/TomcatEmbeddedConfiguration.java @@ -1,14 +1,21 @@ package com.rbkmoney.proxy.mocketbank.configuration; +import com.rbkmoney.woody.api.flow.WFlow; import org.apache.catalina.connector.Connector; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.OncePerRequestFilter; -import java.util.ArrayList; -import java.util.List; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** * This is the configuration class for configuring the {@link ServletWebServerFactory} @@ -20,31 +27,80 @@ import java.util.List; @Configuration public class TomcatEmbeddedConfiguration { - @Value("${server.port}") - private String mainPort; + public static final String HEALTH = "/actuator/health"; - @Value("#{'${server.secondary.ports}'.split(',')}") - private List secondaryPorts; + @Value("${server.rest.port}") + private int restPort; + + @Value("/${server.rest.endpoint}/") + private String restEndpoint; @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); - - Connector[] additionalConnectors = this.additionalConnector(); - if (additionalConnectors.length > 0) { - tomcat.addAdditionalTomcatConnectors(additionalConnectors); - } + Connector connector = new Connector(); + connector.setPort(restPort); + tomcat.addAdditionalTomcatConnectors(connector); return tomcat; } - private Connector[] additionalConnector() { - List result = new ArrayList<>(); - for (String port : secondaryPorts) { - Connector connector = new Connector(); - connector.setPort(Integer.valueOf(port)); - result.add(connector); - } - return result.toArray(new Connector[]{}); + @Bean + public FilterRegistrationBean externalPortRestrictingFilter() { + Filter filter = new OncePerRequestFilter() { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + String servletPath = request.getServletPath(); + if ((request.getLocalPort() == restPort) + && !(servletPath.startsWith(restEndpoint) || servletPath.startsWith(HEALTH))) { + response.sendError(404, "Unknown address"); + return; + } + filterChain.doFilter(request, response); + } + }; + + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(filter); + filterRegistrationBean.setOrder(-100); + filterRegistrationBean.setName("httpPortFilter"); + filterRegistrationBean.addUrlPatterns("/*"); + return filterRegistrationBean; } + @Bean + public FilterRegistrationBean woodyFilter() { + WFlow wFlow = new WFlow(); + Filter filter = new OncePerRequestFilter() { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + if ((request.getLocalPort() == restPort) + && request.getServletPath().startsWith(restEndpoint)) { + wFlow.createServiceFork(() -> { + try { + filterChain.doFilter(request, response); + } catch (IOException | ServletException e) { + sneakyThrow(e); + } + }).run(); + return; + } + filterChain.doFilter(request, response); + } + + private T sneakyThrow(Throwable t) throws E { + throw (E) t; + } + }; + + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); + filterRegistrationBean.setFilter(filter); + filterRegistrationBean.setOrder(-50); + filterRegistrationBean.setName("woodyFilter"); + filterRegistrationBean.addUrlPatterns(restEndpoint + "*"); + return filterRegistrationBean; + } } diff --git a/src/main/java/com/rbkmoney/proxy/mocketbank/controller/MocketBankController.java b/src/main/java/com/rbkmoney/proxy/mocketbank/controller/MocketBankController.java index 4e9398b..115de8c 100644 --- a/src/main/java/com/rbkmoney/proxy/mocketbank/controller/MocketBankController.java +++ b/src/main/java/com/rbkmoney/proxy/mocketbank/controller/MocketBankController.java @@ -18,7 +18,7 @@ import java.io.IOException; import java.nio.ByteBuffer; @RestController -@RequestMapping(value = "/mocketbank") +@RequestMapping("/${server.rest.endpoint}") public class MocketBankController { private final Logger log = LoggerFactory.getLogger(this.getClass()); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b6a55a5..8162b17 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -15,9 +15,10 @@ info: stage: dev --- server: - port: @service.port@ - secondary: - ports: @service.secondary.ports@ + port: @server.port@ + rest: + port: @server.rest.port@ + endpoint: mocketbank --- proxy-mocketbank-mpi: url: http://127.0.0.1:8018 diff --git a/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/DeadlineTest.java b/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/DeadlineTest.java index a0651dc..004c8a5 100644 --- a/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/DeadlineTest.java +++ b/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/DeadlineTest.java @@ -37,7 +37,7 @@ import static org.junit.Assert.fail; properties = { "restTemplate.networkTimeout=10000", "server.port=7021", - "server.secondary.ports=7022", + "server.rest.port=7022", "proxy-mocketbank-mpi.url=http://127.0.0.1:${server.port}" } ) diff --git a/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/ExternalPortRestrictingTest.java b/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/ExternalPortRestrictingTest.java new file mode 100644 index 0000000..31c2703 --- /dev/null +++ b/src/test/java/com/rbkmoney/proxy/mocketbank/configuration/ExternalPortRestrictingTest.java @@ -0,0 +1,50 @@ +package com.rbkmoney.proxy.mocketbank.configuration; + +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; + +import static com.rbkmoney.proxy.mocketbank.configuration.TomcatEmbeddedConfiguration.HEALTH; +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = {"server.rest.port=65434"} +) +public class ExternalPortRestrictingTest { + + private static final String FAKE_REST_PATH = "/you-not-found"; + private static final String MAPPED_REST_ENDPATH = "/term_url"; + + @Value("${server.rest.port}") + private int restPort; + + @Value("/${server.rest.endpoint}") + private String restEndpoint; + + @Test + public void test() throws IOException { + String baseUrl = "http://localhost:" + restPort; + String restUrl = baseUrl + restEndpoint; + HttpGet httpGetTransaction = new HttpGet(restUrl + MAPPED_REST_ENDPATH); + HttpGet httpGetHealth = new HttpGet(baseUrl + HEALTH); + HttpGet httpGetWrongAddress = new HttpGet(baseUrl + FAKE_REST_PATH); + + assertEquals(HttpStatus.SC_METHOD_NOT_ALLOWED, getHttpClient().execute(httpGetTransaction).getStatusLine().getStatusCode()); + assertEquals(HttpStatus.SC_OK, getHttpClient().execute(httpGetHealth).getStatusLine().getStatusCode()); + assertEquals(HttpStatus.SC_NOT_FOUND, getHttpClient().execute(httpGetWrongAddress).getStatusLine().getStatusCode()); + } + + private CloseableHttpClient getHttpClient() { + return HttpClientBuilder.create().build(); + } +}