feat:support async metadata transfer. (#1744)
Signed-off-by: Haotian Zhang <928016560@qq.com>pull/1757/head
parent
040a21d6f5
commit
546a6072c7
@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.metadata.pojo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpUpgradeHandler;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Snapshot of HttpServletRequest.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public final class SnapshotHttpServletRequest implements HttpServletRequest {
|
||||
|
||||
/**
|
||||
* HTTP method.
|
||||
*/
|
||||
private final String method;
|
||||
|
||||
/**
|
||||
* Request URI.
|
||||
*/
|
||||
private final String requestURI;
|
||||
|
||||
/**
|
||||
* Query string.
|
||||
*/
|
||||
private final String queryString;
|
||||
|
||||
/**
|
||||
* HTTP headers.
|
||||
*/
|
||||
private final HttpHeaders headers;
|
||||
|
||||
/**
|
||||
* HTTP cookies.
|
||||
*/
|
||||
private final Cookie[] cookies;
|
||||
|
||||
private SnapshotHttpServletRequest(Builder builder) {
|
||||
this.method = builder.method;
|
||||
this.requestURI = builder.requestURI;
|
||||
this.queryString = builder.queryString;
|
||||
this.headers = HttpHeaders.readOnlyHttpHeaders(builder.headers);
|
||||
this.cookies = builder.cookies != null ? builder.cookies.clone() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* create SnapshotHttpServletRequest from HttpServletRequest.
|
||||
*
|
||||
* @param request original request
|
||||
* @return snapshot
|
||||
*/
|
||||
public static SnapshotHttpServletRequest from(HttpServletRequest request) {
|
||||
Builder builder = new Builder()
|
||||
.method(request.getMethod())
|
||||
.requestURI(request.getRequestURI())
|
||||
.queryString(request.getQueryString())
|
||||
.cookies(request.getCookies());
|
||||
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
if (headerNames != null) {
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
Enumeration<String> headerValues = request.getHeaders(headerName);
|
||||
if (headerValues != null) {
|
||||
while (headerValues.hasMoreElements()) {
|
||||
builder.header(headerName, headerValues.nextElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestURI() {
|
||||
return requestURI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQueryString() {
|
||||
return queryString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return headers.getFirst(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getHeaders(String name) {
|
||||
List<String> values = headers.get(name);
|
||||
if (values != null && !values.isEmpty()) {
|
||||
return Collections.enumeration(values);
|
||||
}
|
||||
return Collections.enumeration(Collections.emptyList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getHeaderNames() {
|
||||
return Collections.enumeration(headers.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cookie[] getCookies() {
|
||||
return cookies != null ? cookies.clone() : null;
|
||||
}
|
||||
|
||||
// ========== Unsupported operations ==========
|
||||
@Override
|
||||
public String getAuthType() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathInfo() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPathTranslated() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContextPath() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteUser() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestedSessionId() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuffer getRequestURL() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServletPath() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSession getSession(boolean create) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpSession getSession() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdValid() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromCookie() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromURL() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequestedSessionIdFromUrl() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password) throws ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() throws ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String name) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getContentLengthLong() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getParameterNames() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScheme() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPort() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteAddr() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteHost() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, Object o) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Locale> getLocales() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestDispatcher getRequestDispatcher(String path) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealPath(String path) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemotePort() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalName() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalAddr() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalPort() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() throws IllegalStateException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttribute(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getAttributeNames() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCharacterEncoding() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCharacterEncoding(String env) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentLength() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntHeader(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDateHeader(String name) {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support this operation");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String method;
|
||||
private String requestURI;
|
||||
private String queryString;
|
||||
private HttpHeaders headers = new HttpHeaders();
|
||||
private Cookie[] cookies;
|
||||
|
||||
public Builder method(String method) {
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder requestURI(String requestURI) {
|
||||
this.requestURI = requestURI;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder queryString(String queryString) {
|
||||
this.queryString = queryString;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder header(String name, String value) {
|
||||
if (name != null && value != null) {
|
||||
this.headers.add(name, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder cookies(Cookie[] cookies) {
|
||||
if (cookies != null) {
|
||||
this.cookies = cookies.clone();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SnapshotHttpServletRequest build() {
|
||||
return new SnapshotHttpServletRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.metadata.pojo;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.server.RequestPath;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* Snapshot of ServerHttpRequest.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public final class SnapshotServerHttpRequest implements ServerHttpRequest {
|
||||
|
||||
/**
|
||||
* HTTP method.
|
||||
*/
|
||||
private final HttpMethod method;
|
||||
|
||||
/**
|
||||
* HTTP URI.
|
||||
*/
|
||||
private final URI uri;
|
||||
|
||||
/**
|
||||
* HTTP attributes.
|
||||
*/
|
||||
private final Map<String, Object> attributes;
|
||||
|
||||
/**
|
||||
* HTTP path.
|
||||
*/
|
||||
private final String path;
|
||||
|
||||
/**
|
||||
* HTTP headers.
|
||||
*/
|
||||
private final HttpHeaders headers;
|
||||
|
||||
/**
|
||||
* HTTP query params.
|
||||
*/
|
||||
private final MultiValueMap<String, String> queryParams;
|
||||
|
||||
/**
|
||||
* HTTP cookies.
|
||||
*/
|
||||
private final MultiValueMap<String, HttpCookie> cookies;
|
||||
|
||||
/**
|
||||
* HTTP remote address.
|
||||
*/
|
||||
private final InetSocketAddress remoteAddress;
|
||||
|
||||
/**
|
||||
* HTTP local address.
|
||||
*/
|
||||
private final InetSocketAddress localAddress;
|
||||
|
||||
/**
|
||||
* HTTP request id.
|
||||
*/
|
||||
private final String id;
|
||||
|
||||
private SnapshotServerHttpRequest(Builder builder) {
|
||||
this.method = builder.method;
|
||||
this.uri = builder.uri;
|
||||
this.attributes = builder.attributes;
|
||||
this.path = builder.path;
|
||||
this.headers = HttpHeaders.readOnlyHttpHeaders(builder.headers);
|
||||
this.queryParams = new LinkedMultiValueMap<>(builder.queryParams);
|
||||
this.cookies = new LinkedMultiValueMap<>(builder.cookies);
|
||||
this.remoteAddress = builder.remoteAddress;
|
||||
this.localAddress = builder.localAddress;
|
||||
this.id = builder.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* create SnapshotServerHttpRequest from ServerHttpRequest.
|
||||
*
|
||||
* @param request original request
|
||||
* @return snapshot
|
||||
*/
|
||||
public static SnapshotServerHttpRequest from(ServerHttpRequest request) {
|
||||
return new Builder()
|
||||
.method(request.getMethod())
|
||||
.uri(request.getURI())
|
||||
.path(request.getPath().value())
|
||||
.headers(request.getHeaders())
|
||||
.queryParams(request.getQueryParams())
|
||||
.cookies(request.getCookies())
|
||||
.remoteAddress(request.getRemoteAddress())
|
||||
.localAddress(request.getLocalAddress())
|
||||
.id(request.getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodValue() {
|
||||
return method.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPath getPath() {
|
||||
return RequestPath.parse(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiValueMap<String, String> getQueryParams() {
|
||||
return queryParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiValueMap<String, HttpCookie> getCookies() {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetSocketAddress getLocalAddress() {
|
||||
return localAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<DataBuffer> getBody() {
|
||||
throw new UnsupportedOperationException("Snapshot request does not support body access");
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private HttpMethod method;
|
||||
private URI uri;
|
||||
private Map<String, Object> attributes = new HashMap<>();
|
||||
private String path;
|
||||
private HttpHeaders headers = new HttpHeaders();
|
||||
private MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
|
||||
private MultiValueMap<String, HttpCookie> cookies = new LinkedMultiValueMap<>();
|
||||
private InetSocketAddress remoteAddress;
|
||||
private InetSocketAddress localAddress;
|
||||
private String id;
|
||||
|
||||
public Builder method(HttpMethod method) {
|
||||
this.method = method;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder uri(URI uri) {
|
||||
this.uri = uri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder attributes(Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder path(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder headers(HttpHeaders headers) {
|
||||
if (headers != null) {
|
||||
this.headers = new HttpHeaders();
|
||||
this.headers.putAll(headers);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder queryParams(MultiValueMap<String, String> queryParams) {
|
||||
if (queryParams != null) {
|
||||
this.queryParams = new LinkedMultiValueMap<>(queryParams);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder cookies(MultiValueMap<String, HttpCookie> cookies) {
|
||||
if (cookies != null) {
|
||||
this.cookies = new LinkedMultiValueMap<>(cookies);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder remoteAddress(InetSocketAddress remoteAddress) {
|
||||
this.remoteAddress = remoteAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder localAddress(InetSocketAddress localAddress) {
|
||||
this.localAddress = localAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SnapshotServerHttpRequest build() {
|
||||
return new SnapshotServerHttpRequest(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.metadata.provider;
|
||||
|
||||
import com.tencent.cloud.common.util.UrlUtils;
|
||||
import com.tencent.cloud.metadata.pojo.SnapshotHttpServletRequest;
|
||||
import com.tencent.polaris.metadata.core.MessageMetadataContainer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.mock.web.MockCookie;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link ServletMetadataProvider}.
|
||||
*
|
||||
* @author Haotian Zhang, Shedfree Wu
|
||||
*/
|
||||
public class ServletMetadataProviderTest {
|
||||
|
||||
private static final String notExistKey = "empty";
|
||||
|
||||
@Test
|
||||
public void testServletMetadataProviderWithoutAsync() {
|
||||
String headerKey1 = "header1";
|
||||
String headerKey2 = "header2";
|
||||
String headerValue1 = "value1";
|
||||
String headerValue2 = "value2/test";
|
||||
String queryKey1 = "qk1";
|
||||
String queryKey2 = "qk2";
|
||||
String queryValue1 = "qv1";
|
||||
String queryValue2 = "qv2/test";
|
||||
String cookieKey1 = "ck1";
|
||||
String cookieKey2 = "ck2";
|
||||
String cookieValue1 = "cv1";
|
||||
String cookieValue2 = "cv2/test";
|
||||
String path = "/echo/test";
|
||||
String callerIp = "localhost";
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(headerKey1, headerValue1);
|
||||
request.addHeader(headerKey2, UrlUtils.encode(headerValue2));
|
||||
request.setCookies(new MockCookie(cookieKey1, cookieValue1), new MockCookie(cookieKey2, UrlUtils.encode(cookieValue2)));
|
||||
request.setMethod(HttpMethod.GET.name());
|
||||
request.setRequestURI(path);
|
||||
request.setQueryString(queryKey1 + "=" + queryValue1 + "&" + queryKey2 + "=" + UrlUtils.encode(queryValue2));
|
||||
|
||||
ServletMetadataProvider servletMetadataProvider = new ServletMetadataProvider(request, callerIp);
|
||||
assertThat(servletMetadataProvider.getHttpServletRequest()).isNotInstanceOf(SnapshotHttpServletRequest.class);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, headerKey1)).isEqualTo(headerValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, headerKey2)).isEqualTo(headerValue2);
|
||||
// com.tencent.polaris.metadata.core.manager.ComposeMetadataProvider.getRawMetadataMapValue need return null when key don't exist
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, notExistKey)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, cookieKey1)).isEqualTo(cookieValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, cookieKey2)).isEqualTo(cookieValue2);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, notExistKey)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, queryKey1)).isEqualTo(queryValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, queryKey2)).isEqualTo(queryValue2);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, notExistKey)).isNull();
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(notExistKey, queryKey1)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_METHOD)).isEqualTo("GET");
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_PATH)).isEqualTo(path);
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_CALLER_IP)).isEqualTo(callerIp);
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(notExistKey)).isNull();
|
||||
|
||||
request.setRequestURI("/echo/" + UrlUtils.decode("a@b"));
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_PATH)).isEqualTo("/echo/a@b");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServletMetadataProviderWithAsync() {
|
||||
String headerKey1 = "header1";
|
||||
String headerKey2 = "header2";
|
||||
String headerValue1 = "value1";
|
||||
String headerValue2 = "value2/test";
|
||||
String queryKey1 = "qk1";
|
||||
String queryKey2 = "qk2";
|
||||
String queryValue1 = "qv1";
|
||||
String queryValue2 = "qv2/test";
|
||||
String cookieKey1 = "ck1";
|
||||
String cookieKey2 = "ck2";
|
||||
String cookieValue1 = "cv1";
|
||||
String cookieValue2 = "cv2/test";
|
||||
String path = "/echo/test";
|
||||
String callerIp = "localhost";
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader(headerKey1, headerValue1);
|
||||
request.addHeader(headerKey2, UrlUtils.encode(headerValue2));
|
||||
request.setCookies(new MockCookie(cookieKey1, cookieValue1), new MockCookie(cookieKey2, UrlUtils.encode(cookieValue2)));
|
||||
request.setMethod(HttpMethod.GET.name());
|
||||
request.setRequestURI(path);
|
||||
request.setQueryString(queryKey1 + "=" + queryValue1 + "&" + queryKey2 + "=" + UrlUtils.encode(queryValue2));
|
||||
|
||||
ServletMetadataProvider servletMetadataProvider = new ServletMetadataProvider(request, callerIp, true);
|
||||
assertThat(servletMetadataProvider.getHttpServletRequest()).isInstanceOf(SnapshotHttpServletRequest.class);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, headerKey1)).isEqualTo(headerValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, headerKey2)).isEqualTo(headerValue2);
|
||||
// com.tencent.polaris.metadata.core.manager.ComposeMetadataProvider.getRawMetadataMapValue need return null when key don't exist
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, notExistKey)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, cookieKey1)).isEqualTo(cookieValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, cookieKey2)).isEqualTo(cookieValue2);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_COOKIE, notExistKey)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, queryKey1)).isEqualTo(queryValue1);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, queryKey2)).isEqualTo(queryValue2);
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_QUERY, notExistKey)).isNull();
|
||||
assertThat(servletMetadataProvider.getRawMetadataMapValue(notExistKey, queryKey1)).isNull();
|
||||
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_METHOD)).isEqualTo("GET");
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_PATH)).isEqualTo(path);
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_CALLER_IP)).isEqualTo(callerIp);
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(notExistKey)).isNull();
|
||||
|
||||
request.setRequestURI("/echo/" + UrlUtils.decode("a@b"));
|
||||
servletMetadataProvider = new ServletMetadataProvider(request, callerIp, true);
|
||||
assertThat(servletMetadataProvider.getRawMetadataStringValue(MessageMetadataContainer.LABEL_KEY_PATH)).isEqualTo("/echo/a@b");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.common.async;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Metadata Properties from local properties file.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.cloud.tencent.async")
|
||||
public class PolarisAsyncProperties {
|
||||
|
||||
/**
|
||||
* Enable async or not.
|
||||
*/
|
||||
private Boolean enabled = false;
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PolarisAsyncProperties{" +
|
||||
"enabled=" + enabled +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.common.async;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Autoconfiguration of polaris async.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class PolarisAsyncPropertiesAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public PolarisAsyncProperties polarisAsyncProperties() {
|
||||
return new PolarisAsyncProperties();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.common.async;
|
||||
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
|
||||
/**
|
||||
* Test for {@link PolarisAsyncPropertiesAutoConfiguration}.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
public class PolarisAsyncPropertiesAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withPropertyValues(
|
||||
"spring.application.name=test"
|
||||
);
|
||||
|
||||
private final WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner().withPropertyValues(
|
||||
"spring.application.name=test"
|
||||
);
|
||||
|
||||
private final ReactiveWebApplicationContextRunner reactiveWebApplicationContextRunner = new ReactiveWebApplicationContextRunner().withPropertyValues(
|
||||
"spring.application.name=test"
|
||||
);
|
||||
|
||||
/**
|
||||
* No any web application.
|
||||
*/
|
||||
@Test
|
||||
public void test1() {
|
||||
this.applicationContextRunner
|
||||
.withConfiguration(AutoConfigurations.of(PolarisAsyncPropertiesAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
Assertions.assertThat(context).hasSingleBean(PolarisAsyncProperties.class);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* web application.
|
||||
*/
|
||||
@Test
|
||||
public void test2() {
|
||||
this.webApplicationContextRunner
|
||||
.withConfiguration(AutoConfigurations.of(PolarisAsyncPropertiesAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
Assertions.assertThat(context).hasSingleBean(PolarisAsyncProperties.class);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* reactive web application.
|
||||
*/
|
||||
@Test
|
||||
public void test3() {
|
||||
this.reactiveWebApplicationContextRunner
|
||||
.withConfiguration(AutoConfigurations.of(PolarisAsyncPropertiesAutoConfiguration.class))
|
||||
.run(context -> {
|
||||
Assertions.assertThat(context).hasSingleBean(PolarisAsyncProperties.class);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Tencent is pleased to support the open source community by making spring-cloud-tencent available.
|
||||
*
|
||||
* Copyright (C) 2021 Tencent. All rights reserved.
|
||||
*
|
||||
* Licensed under the BSD 3-Clause License (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
* 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 com.tencent.cloud.common.async;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link PolarisAsyncProperties}.
|
||||
*
|
||||
* @author Haotian Zhang
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = PolarisAsyncPropertiesTest.TestApplication.class,
|
||||
properties = {"spring.config.location = classpath:application-test.yml"})
|
||||
public class PolarisAsyncPropertiesTest {
|
||||
|
||||
@Autowired
|
||||
private PolarisAsyncProperties polarisAsyncProperties;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(polarisAsyncProperties.getEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
protected static class TestApplication {
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue