This is an automated email from the ASF dual-hosted git repository.

dockerzhang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/inlong.git


The following commit(s) were added to refs/heads/master by this push:
     new 577ecaed0a [INLONG-8231][Manager] Add tenant into param and body of 
each request (#8232)
577ecaed0a is described below

commit 577ecaed0a1c10eefb116ecf8ecd2341ea8e8205
Author: vernedeng <[email protected]>
AuthorDate: Fri Jun 16 15:19:37 2023 +0800

    [INLONG-8231][Manager] Add tenant into param and body of each request 
(#8232)
---
 .../manager/web/filter/TenantInsertionFilter.java  |  75 +++++++++++++
 .../inlong/manager/web/filter/WebFilterConfig.java |  11 ++
 .../inlong/manager/web/utils/HttpContextUtils.java |  13 ++-
 .../manager/web/utils/InlongRequestWrapper.java    |   7 ++
 .../web/filter/TenantInsertionFilterTest.java      | 118 +++++++++++++++++++++
 5 files changed, 219 insertions(+), 5 deletions(-)

diff --git 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/TenantInsertionFilter.java
 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/TenantInsertionFilter.java
new file mode 100644
index 0000000000..6cce47a23a
--- /dev/null
+++ 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/TenantInsertionFilter.java
@@ -0,0 +1,75 @@
+/*
+ * 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.inlong.manager.web.filter;
+
+import org.apache.inlong.manager.web.utils.InlongRequestWrapper;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+
+import static org.apache.inlong.common.util.BasicAuth.BASIC_AUTH_TENANT_HEADER;
+
+/**
+ * Tenant info insertion filter.
+ * Add tenant into param and body of each request
+ */
+@Slf4j
+public class TenantInsertionFilter implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse 
servletResponse, FilterChain filterChain)
+            throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        String tenant = request.getHeader(BASIC_AUTH_TENANT_HEADER);
+        if (StringUtils.isBlank(tenant)) {
+            String errMsg = "tenant should not be blank";
+            log.error(errMsg);
+            ((HttpServletResponse) 
servletResponse).sendError(HttpServletResponse.SC_BAD_REQUEST, errMsg);
+            return;
+        }
+
+        InlongRequestWrapper inlongWrapper;
+        if (request instanceof ShiroHttpServletRequest) {
+            ShiroHttpServletRequest shiroWrapper = (ShiroHttpServletRequest) 
request;
+            inlongWrapper = (InlongRequestWrapper) shiroWrapper.getRequest();
+        } else if (request instanceof InlongRequestWrapper) {
+            inlongWrapper = (InlongRequestWrapper) request;
+        } else {
+            String errMsg = "request should be one of ShiroHttpServletRequest 
or InlongRequestWrapper type";
+            log.error(errMsg);
+            ((HttpServletResponse) 
servletResponse).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
errMsg);
+            return;
+        }
+
+        inlongWrapper.addParameter(BASIC_AUTH_TENANT_HEADER, tenant);
+        inlongWrapper.addBodyParam(BASIC_AUTH_TENANT_HEADER, tenant);
+        filterChain.doFilter(inlongWrapper, servletResponse);
+
+    }
+}
diff --git 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/WebFilterConfig.java
 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/WebFilterConfig.java
index fecddeb36c..79e457f18f 100644
--- 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/WebFilterConfig.java
+++ 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/filter/WebFilterConfig.java
@@ -46,4 +46,15 @@ public class WebFilterConfig {
         return bean;
     }
 
+    @Bean
+    public FilterRegistrationBean registerTenantInsertionFilter() {
+        FilterRegistrationBean<TenantInsertionFilter> bean = new 
FilterRegistrationBean<>();
+        bean.setOrder(1);
+        bean.setFilter(new TenantInsertionFilter());
+        bean.addUrlPatterns("/*");
+        bean.setMatchAfter(true);
+        bean.setName("tenantInsertionFilter");
+        return bean;
+    }
+
 }
diff --git 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/HttpContextUtils.java
 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/HttpContextUtils.java
index f56416d31c..d2544160b2 100644
--- 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/HttpContextUtils.java
+++ 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/HttpContextUtils.java
@@ -43,7 +43,7 @@ public class HttpContextUtils {
      * @param request
      * @return
      */
-    public static Map<String, String> getParameterMapAll(HttpServletRequest 
request) {
+    public static Map<String, String> getParameterMapAll(ServletRequest 
request) {
         Enumeration<String> parameters = request.getParameterNames();
 
         Map<String, String> params = new HashMap<>();
@@ -94,19 +94,22 @@ public class HttpContextUtils {
      * @return
      */
     public static String getBodyString(ServletRequest request) {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder builder = new StringBuilder();
         try (InputStream inputStream = request.getInputStream()) {
             try (BufferedReader reader =
                     new BufferedReader(new InputStreamReader(inputStream, 
StandardCharsets.UTF_8))) {
                 String line = "";
                 while ((line = reader.readLine()) != null) {
-                    sb.append(line);
+                    builder.append(line);
                 }
             }
         } catch (IOException e) {
-            log.error("failed to get body string of request={}", request);
+            log.error("failed to get body string of request={}", request, e);
         }
-        return sb.toString();
+        if (builder.length() == 0) {
+            return "{}";
+        }
+        return builder.toString();
     }
 
 }
\ No newline at end of file
diff --git 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/InlongRequestWrapper.java
 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/InlongRequestWrapper.java
index 276bc77e1f..08bc0cc729 100644
--- 
a/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/InlongRequestWrapper.java
+++ 
b/inlong-manager/manager-web/src/main/java/org/apache/inlong/manager/web/utils/InlongRequestWrapper.java
@@ -31,7 +31,9 @@ import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
 import java.util.Map;
+import java.util.Vector;
 
 /**
  * Inlong http request wrapper
@@ -133,6 +135,11 @@ public class InlongRequestWrapper extends 
HttpServletRequestWrapper {
         return this.headers.get(name);
     }
 
+    @Override
+    public Enumeration<String> getParameterNames() {
+        return new Vector<>(params.keySet()).elements();
+    }
+
     public void addHeader(String name, String value) {
         headers.put(name, value);
     }
diff --git 
a/inlong-manager/manager-web/src/test/java/org/apache/inlong/manager/web/filter/TenantInsertionFilterTest.java
 
b/inlong-manager/manager-web/src/test/java/org/apache/inlong/manager/web/filter/TenantInsertionFilterTest.java
new file mode 100644
index 0000000000..73c3b092a1
--- /dev/null
+++ 
b/inlong-manager/manager-web/src/test/java/org/apache/inlong/manager/web/filter/TenantInsertionFilterTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.inlong.manager.web.filter;
+
+import org.apache.inlong.common.util.BasicAuth;
+import org.apache.inlong.manager.web.utils.HttpContextUtils;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.mock.web.MockFilterChain;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Test for {@link TenantInsertionFilter}
+ */
+public class TenantInsertionFilterTest extends WebFilterConfig {
+
+    @Test
+    public void testNormal() {
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        String testTenant = "testTenant";
+        req.addHeader(BasicAuth.BASIC_AUTH_TENANT_HEADER, testTenant);
+        Servlet servlet = new HttpServlet() {
+        };
+
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        HttpServletRequestFilter httpServletRequestFilter = new 
HttpServletRequestFilter();
+        EmptyTenantFilter emptyTenantFilter = new EmptyTenantFilter();
+        TenantInsertionFilter tenantInsertionFilter = new 
TenantInsertionFilter();
+
+        FilterChecker checker = new FilterChecker(testTenant);
+        MockFilterChain filterChain = new MockFilterChain(servlet, 
httpServletRequestFilter, emptyTenantFilter,
+                tenantInsertionFilter, checker);
+        Assertions.assertDoesNotThrow(() -> filterChain.doFilter(req, res));
+        Assertions.assertEquals(HttpServletResponse.SC_OK, res.getStatus());
+
+    }
+
+    @Test
+    public void testEmptyTenant() {
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        Servlet servlet = new HttpServlet() {
+        };
+
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        HttpServletRequestFilter httpServletRequestFilter = new 
HttpServletRequestFilter();
+        TenantInsertionFilter tenantInsertionFilter = new 
TenantInsertionFilter();
+
+        MockFilterChain filterChain = new MockFilterChain(servlet, 
httpServletRequestFilter, tenantInsertionFilter);
+        Assertions.assertDoesNotThrow(() -> filterChain.doFilter(req, res));
+        Assertions.assertEquals(HttpServletResponse.SC_BAD_REQUEST, 
res.getStatus());
+    }
+
+    @Test
+    public void testErrorWrapper() {
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        String testTenant = "testTenant";
+        req.addHeader(BasicAuth.BASIC_AUTH_TENANT_HEADER, testTenant);
+        Servlet servlet = new HttpServlet() {
+        };
+
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        TenantInsertionFilter tenantInsertionFilter = new 
TenantInsertionFilter();
+
+        MockFilterChain filterChain = new MockFilterChain(servlet, 
tenantInsertionFilter);
+        Assertions.assertDoesNotThrow(() -> filterChain.doFilter(req, res));
+        Assertions.assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
res.getStatus());
+    }
+
+    class FilterChecker implements Filter {
+
+        String targetTenant;
+
+        public FilterChecker(String targetTenant) {
+            this.targetTenant = targetTenant;
+        }
+        @Override
+        public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain)
+                throws IOException, ServletException {
+            HttpServletRequest httpServletRequest = (HttpServletRequest) 
request;
+            String tenant = 
httpServletRequest.getParameter(BasicAuth.BASIC_AUTH_TENANT_HEADER);
+            Assertions.assertEquals(targetTenant, tenant);
+            Map<String, String> paraMap = 
HttpContextUtils.getParameterMapAll(request);
+            
Assertions.assertTrue(paraMap.containsKey(BasicAuth.BASIC_AUTH_TENANT_HEADER));
+            String body = HttpContextUtils.getBodyString(request);
+            
Assertions.assertTrue(body.contains(BasicAuth.BASIC_AUTH_TENANT_HEADER));
+        }
+    }
+}
\ No newline at end of file

Reply via email to