You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by jo...@apache.org on 2023/12/22 12:15:18 UTC
(causeway) branch spring6-kroviz updated: CAUSEWAY-3264 first draft of ExtProxy module
This is an automated email from the ASF dual-hosted git repository.
joergrade pushed a commit to branch spring6-kroviz
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/spring6-kroviz by this push:
new 89c2677e64 CAUSEWAY-3264 first draft of ExtProxy module
89c2677e64 is described below
commit 89c2677e64df8ee84e17965027621e004f67afc7
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Thu Dec 21 12:29:33 2023 +0100
CAUSEWAY-3264 first draft of ExtProxy module
---
.../core/config/CausewayConfiguration.java | 20 ++++++
extensions/vro/proxy/adoc/antora.yml | 19 ++++++
extensions/vro/proxy/adoc/modules/proxy/nav.adoc | 5 ++
.../vro/proxy/adoc/modules/proxy/pages/about.adoc | 74 ++++++++++++++++++++
.../adoc/modules/proxy/partials/module-nav.adoc | 2 +
extensions/vro/proxy/impl/pom.xml | 59 ++++++++++++++++
.../proxy/impl/CausewayModuleExtProxy.java | 78 ++++++++++++++++++++++
.../extensions/proxy/impl/ProxyFilter.java | 25 +++++++
.../extensions/proxy/impl/ProxyServer.java | 61 +++++++++++++++++
.../proxy/impl/CausewayModuleExtProxyImplTest.java | 57 ++++++++++++++++
extensions/vro/proxy/pom.xml | 44 ++++++++++++
11 files changed, 444 insertions(+)
diff --git a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
index db7c008390..9598434973 100644
--- a/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
+++ b/core/config/src/main/java/org/apache/causeway/core/config/CausewayConfiguration.java
@@ -3381,6 +3381,26 @@ public class CausewayConfiguration {
}
+ private final Proxy proxy = new Proxy();
+ @Data
+ public static class Proxy {
+
+ /**
+ * Which urls are allowed to be proxied.
+ *
+ * <p>
+ * The (safe) default is an empty list, meaning nothing is allowed to be accessed via the proxy,
+ * Allowed url (prefixes) need to be whitelisted - use commas to separat multiple entries
+ * eg:
+ * </p>
+ * <p>
+ * <code>http://www.w3.org, https://www.apache.org</code>
+ * </p>
+ */
+ private List<String> allow= listOf();
+
+ }
+
private final ExecutionLog executionLog = new ExecutionLog();
@Data
public static class ExecutionLog {
diff --git a/extensions/vro/proxy/adoc/antora.yml b/extensions/vro/proxy/adoc/antora.yml
new file mode 100644
index 0000000000..c83b9c2982
--- /dev/null
+++ b/extensions/vro/proxy/adoc/antora.yml
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# http://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.
+
+name: vro
+version: latest
diff --git a/extensions/vro/proxy/adoc/modules/proxy/nav.adoc b/extensions/vro/proxy/adoc/modules/proxy/nav.adoc
new file mode 100644
index 0000000000..2d0e8b246d
--- /dev/null
+++ b/extensions/vro/proxy/adoc/modules/proxy/nav.adoc
@@ -0,0 +1,5 @@
+
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
+
+include::vro:ROOT:partial$component-nav.adoc[]
+
diff --git a/extensions/vro/proxy/adoc/modules/proxy/pages/about.adoc b/extensions/vro/proxy/adoc/modules/proxy/pages/about.adoc
new file mode 100644
index 0000000000..949d1b468c
--- /dev/null
+++ b/extensions/vro/proxy/adoc/modules/proxy/pages/about.adoc
@@ -0,0 +1,74 @@
+= Proxy Extension
+
+:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
+
+
+This extension offers a HTTP proxy, that allows to reroute request.
+
+
+== Setup
+
+=== Dependency Management
+
+In your application's top level `pom.xml`, add a dependency for this module's own bill of materials (BOM):
+
+[source,xml,subs="attributes+"]
+.pom.xml
+----
+<dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.causeway.extensions</groupId>
+ <artifactId>causeway-extensions-proxy</artifactId>
+ <scope>import</scope>
+ <type>pom</type>
+ <version>{page-causewayprev}</version>
+ </dependency>
+ </dependencies>
+</dependencyManagement>
+----
+
+
+=== Dependencies / Imports
+
+In the webapp module of your application, add the following dependency:
+
+[source,xml]
+.pom.xml
+----
+<dependency>
+ <groupId>org.apache.causeway.extensions</groupId>
+ <artifactId>causeway-extensions-proxy-impl</artifactId>
+</dependency>
+----
+
+In your application's xref:userguide::modules.adoc#appmanifest[App Manifest], import the extension's implementation module:
+
+[source,java]
+.AppManifest.java
+----
+@Configuration
+@Import({
+ CausewayModuleExtProxy.class,
+ ...
+})
+public class AppManifest {
+}
+----
+
+
+== Configuration
+
+Update the configuration properties:
+
+[source,yml]
+.application.yml
+----
+causeway:
+ extensions:
+ proxy:
+ allow: ... # <.>
+ deny: ... # <.>
+----
+<.> xref:refguide:config:sections/causeway.extensions.adoc#causeway.extensions.proxy.allow[causeway.extensions.proxy.allow]
+<.> xref:refguide:config:sections/causeway.extensions.adoc#causeway.extensions.proxy.deny[causeway.extensions.proxy.deny]
diff --git a/extensions/vro/proxy/adoc/modules/proxy/partials/module-nav.adoc b/extensions/vro/proxy/adoc/modules/proxy/partials/module-nav.adoc
new file mode 100644
index 0000000000..35e610e252
--- /dev/null
+++ b/extensions/vro/proxy/adoc/modules/proxy/partials/module-nav.adoc
@@ -0,0 +1,2 @@
+** xref:vro:cors:about.adoc[CORS]
+
diff --git a/extensions/vro/proxy/impl/pom.xml b/extensions/vro/proxy/impl/pom.xml
new file mode 100644
index 0000000000..a4c7c22026
--- /dev/null
+++ b/extensions/vro/proxy/impl/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
+ license agreements. See the NOTICE file distributed with this work for additional
+ information regarding copyright ownership. The ASF licenses this file to
+ you 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 http://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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.causeway.extensions</groupId>
+ <artifactId>causeway-extensions-proxy</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>causeway-extensions-proxy-impl</artifactId>
+ <name>Apache Causeway Ext - Proxy (impl)</name>
+
+ <properties>
+ <jar-plugin.automaticModuleName>org.apache.causeway.extensions.proxy.impl</jar-plugin.automaticModuleName>
+ <git-plugin.propertiesDir>org/apache/causeway/extensions/proxy/impl</git-plugin.propertiesDir>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.apache.causeway.core</groupId>
+ <artifactId>causeway-core-metamodel</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.causeway.core</groupId>
+ <artifactId>causeway-core-webapp</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+
+ <!-- TESTING -->
+
+ <dependency>
+ <groupId>org.apache.causeway.core</groupId>
+ <artifactId>causeway-core-internaltestsupport</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxy.java b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxy.java
new file mode 100644
index 0000000000..914ee3601b
--- /dev/null
+++ b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxy.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.causeway.extensions.proxy.impl;
+
+import java.util.Collections;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import org.apache.causeway.applib.annotation.PriorityPrecedence;
+import org.apache.causeway.core.config.CausewayConfiguration;
+
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+import jakarta.servlet.Filter;
+
+/**
+ * @since 3.0 {@index}
+ */
+@Configuration
+@Qualifier("Proxy")
+@Log4j2
+public class CausewayModuleExtProxy {
+
+ @Bean
+ public FilterRegistrationBean<Filter> createCorsFilterRegistration(
+ final CausewayConfiguration causewayConfiguration) {
+
+ String proxyBase = "/proxy/";//restEasyConfiguration.getJaxrs().getDefaultPath();
+ if (!proxyBase.endsWith("/*")) {
+ proxyBase = proxyBase + "/*";
+ }
+ log.info("Setting up Proxy to allow base at '{}' with {}",
+ proxyBase,
+ causewayConfiguration.getExtensions().getProxy());
+
+ final FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
+ filterRegistrationBean.setFilter(createProxyFilter(causewayConfiguration));
+ filterRegistrationBean.setUrlPatterns(Collections.singletonList(proxyBase));
+ filterRegistrationBean.setOrder(PriorityPrecedence.EARLY - 100);
+
+ return filterRegistrationBean;
+ }
+
+ private ProxyFilter createProxyFilter(CausewayConfiguration configuration) {
+
+ val causewayProxyConfig = configuration.getExtensions().getProxy();
+
+ // corsConfiguration.setAllowCredentials(causewayCorsConfig.isAllowCredentials());
+
+ val source = new UrlBasedCorsConfigurationSource();
+// source.registerCorsConfiguration("/**", causewayProxyConfig);
+
+ final ProxyServer proxyServer = new ProxyServer();
+ return new ProxyFilter(proxyServer);
+ }
+
+}
diff --git a/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyFilter.java b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyFilter.java
new file mode 100644
index 0000000000..523bdc3bc3
--- /dev/null
+++ b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyFilter.java
@@ -0,0 +1,25 @@
+package org.apache.causeway.extensions.proxy.impl;
+
+import java.io.IOException;
+
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import lombok.RequiredArgsConstructor;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+@RequiredArgsConstructor
+public class ProxyFilter extends OncePerRequestFilter {
+ private final ProxyServer processor;
+
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+ // CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
+ // boolean isValid = this.processor.processRequest(request, response);
+ // if (isValid && !CorsUtils.isPreFlightRequest(request)) {
+ filterChain.doFilter(request, response);
+// }
+ }
+}
\ No newline at end of file
diff --git a/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyServer.java b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyServer.java
new file mode 100644
index 0000000000..7fe9648549
--- /dev/null
+++ b/extensions/vro/proxy/impl/src/main/java/org/apache/causeway/extensions/proxy/impl/ProxyServer.java
@@ -0,0 +1,61 @@
+package org.apache.causeway.extensions.proxy.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import lombok.extern.slf4j.XSlf4j;
+
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+
+@Service
+@Slf4j
+public class ProxyServer {
+ public static void run() throws IOException {
+ final ServerSocket serverSocket = new ServerSocket(9999);
+ log.info("Proxy server running on port 9999");
+
+ while (true) {
+ Socket clientSocket = serverSocket.accept();
+ new Thread(() -> {
+ try {
+ final Socket inputSocket = new Socket("destination_server_address", 80);
+ final InputStream clientInput = clientSocket.getInputStream();
+ final OutputStream clientOutput = clientSocket.getOutputStream();
+ final InputStream serverInput = inputSocket.getInputStream();
+ final OutputStream serverOutput = inputSocket.getOutputStream();
+
+ // Transfer data from client to server
+ new Thread(() -> {
+ try {
+ int data;
+ while ((data = clientInput.read()) != -1) {
+ serverOutput.write(data);
+ }
+ } catch (IOException e) {
+ log.error("Error reading from client", e);
+ }
+ }).start();
+
+ // Transfer data from server to client
+ new Thread(() -> {
+ try {
+ int data;
+ while ((data = serverInput.read()) != -1) {
+ clientOutput.write(data);
+ }
+ } catch (IOException e) {
+ log.error("Error writing to client", e);
+ }
+ }).start();
+ } catch (IOException e) {
+ log.error("Error creating socket for <destination_server_address>");
+ }
+ }).start();
+ }
+ }
+}
diff --git a/extensions/vro/proxy/impl/src/test/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxyImplTest.java b/extensions/vro/proxy/impl/src/test/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxyImplTest.java
new file mode 100644
index 0000000000..5ebaa03394
--- /dev/null
+++ b/extensions/vro/proxy/impl/src/test/java/org/apache/causeway/extensions/proxy/impl/CausewayModuleExtProxyImplTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * http://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.apache.causeway.extensions.proxy.impl;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.causeway.core.config.CausewayConfiguration;
+import org.apache.causeway.core.config.RestEasyConfiguration;
+import org.apache.causeway.core.metamodel._testing.MetaModelContext_forTesting;
+
+import lombok.val;
+
+class CausewayModuleExtProxyImplTest {
+
+ private CausewayConfiguration causewayDefaultConfiguration;
+ private RestEasyConfiguration restEasyConfiguration;
+
+ @BeforeEach
+ void setUp() {
+ causewayDefaultConfiguration = MetaModelContext_forTesting
+ .buildDefault()
+ .getConfiguration();
+ restEasyConfiguration = new RestEasyConfiguration();
+ }
+
+ @Test
+ void defaultCausewayConfiguration_shouldYieldCorsUrlPatternWithWildcard() {
+ // given
+ val causewayModuleExtCors = new CausewayModuleExtProxy();
+
+ // when
+ val filterRegistration = causewayModuleExtCors.createCorsFilterRegistration(causewayDefaultConfiguration); //, restEasyConfiguration
+
+ // then
+ assertTrue(filterRegistration.getUrlPatterns().contains("/restful/*"));
+ }
+
+}
diff --git a/extensions/vro/proxy/pom.xml b/extensions/vro/proxy/pom.xml
new file mode 100644
index 0000000000..8b6e31b760
--- /dev/null
+++ b/extensions/vro/proxy/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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
+
+ http://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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.causeway.extensions</groupId>
+ <artifactId>causeway-extensions</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>causeway-extensions-proxy</artifactId>
+ <name>Apache Causeway Ext - Proxy (parent)</name>
+ <description>
+ Implementation of a Proxy Filter
+ </description>
+
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>impl</module>
+ </modules>
+
+</project>