Skip to content

Commit

Permalink
[#noissue] Included v3 react front application
Browse files Browse the repository at this point in the history
  • Loading branch information
smilu97 committed Sep 12, 2023
1 parent 7be4cc6 commit 345536d
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,32 @@
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.List;
import java.util.Objects;

/**
* @author youngjin.kim2
*/
public class HttpIntentRoutingFilter implements Filter {

private static final FrontApplicationRegistration DEFAULT_FRONT_REGISTRATION = FrontApplicationRegistration.of("/");

private static final List<String> RESOURCE_BASE_PATHS = List.of(
"assets",
"fonts",
"img"
);

private final Logger logger = LogManager.getLogger(this.getClass());

private final String legacyEntryHtmlResource;
private final String v2EntryHtmlResource;
private final String v3EntryHtmlResource;

public HttpIntentRoutingFilter(
String legacyEntryHtmlResource,
String v2EntryHtmlResource,
String v3EntryHtmlResource
) {
this.legacyEntryHtmlResource = legacyEntryHtmlResource;
this.v2EntryHtmlResource = v2EntryHtmlResource;
this.v3EntryHtmlResource = v3EntryHtmlResource;
private final List<FrontApplicationRegistration> registrations;

public HttpIntentRoutingFilter(List<FrontApplicationRegistration> registrations) {
this.registrations = Objects.requireNonNullElse(registrations, List.of(DEFAULT_FRONT_REGISTRATION));
}

public HttpIntentRoutingFilter(String htmlResource) {
this(htmlResource, htmlResource, htmlResource);
public HttpIntentRoutingFilter() {
this(List.of(DEFAULT_FRONT_REGISTRATION));
}

@Override
Expand All @@ -71,97 +72,93 @@ public void doFilter(
ServletResponse response,
FilterChain chain
) throws IOException, ServletException {
RequestType type = getRequestType(request);
switch (type) {
case LEGACY_FRONT_ENTRY:
forwardToFrontAppEntry(request, response, chain, this.legacyEntryHtmlResource);
break;
case V2_FRONT_ENTRY:
forwardToFrontAppEntry(request, response, chain, this.v2EntryHtmlResource);
break;
case V3_FRONT_ENTRY:
forwardToFrontAppEntry(request, response, chain, this.v3EntryHtmlResource);
break;
case LEGACY_STATIC_RESOURCE:
case V2_STATIC_RESOURCE:
case V3_STATIC_RESOURCE:
case REST_API:
case UNKNOWN:
chain.doFilter(request, response);
if (request instanceof HttpServletRequest) {
route((HttpServletRequest) request, response, chain);
} else {
chain.doFilter(request, response);
}
}

private void forwardToFrontAppEntry(
ServletRequest request,
private void route(
HttpServletRequest request,
ServletResponse response,
FilterChain chain,
String htmlResource
FilterChain chain
) throws ServletException, IOException {
if (htmlResource == null) {
String uri = request.getRequestURI();

if (uri.startsWith("/api/")) {
chain.doFilter(request, response);
return;
}

HttpServletRequest httpRequest = (HttpServletRequest) request;
logger.debug("requestUri: {} --(forward)--> {}", httpRequest.getRequestURI(), htmlResource);
for (FrontApplicationRegistration registration: this.registrations) {
if (uri.startsWith(registration.getBasePath())) {
routeToFrontApplication(request, response, chain, registration);
return;
}
}

RequestDispatcher dispatcher = request.getRequestDispatcher(htmlResource);
dispatcher.forward(request, response);
chain.doFilter(request, response);
}

private static RequestType getRequestType(ServletRequest request) {
if (!(request instanceof HttpServletRequest)) {
return RequestType.UNKNOWN;
private void routeToFrontApplication(
HttpServletRequest request,
ServletResponse response,
FilterChain chain,
FrontApplicationRegistration frontRegistration
) throws ServletException, IOException {
String basePath = frontRegistration.getBasePath();
String path = trimFirstSlash(request.getRequestURI().substring(basePath.length()));
String firstToken = path.split("/", 2)[0];
if (isStaticResource(firstToken)) {
chain.doFilter(request, response);
} else {
String entryHtml = basePath + "/index.html";
forwardTo(request, response, entryHtml);
logger.debug("requestUri: {} --(forward)--> {}", request.getRequestURI(), entryHtml);
}
}

HttpServletRequest httpRequest = (HttpServletRequest) request;
StringTokenizer tokenizer = new StringTokenizer(httpRequest.getRequestURI(), "/");
if (!tokenizer.hasMoreTokens()) {
return RequestType.LEGACY_FRONT_ENTRY;
}
private static void forwardTo(
HttpServletRequest request,
ServletResponse response,
String entryHtml
) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher(entryHtml);
dispatcher.forward(request, response);
}

String t0 = tokenizer.nextToken();
switch (t0) {
case "api":
return RequestType.REST_API;
case "v2":
return getRequestType(tokenizer, RequestType.V2_STATIC_RESOURCE, RequestType.V2_FRONT_ENTRY);
case "v3":
return getRequestType(tokenizer, RequestType.V3_STATIC_RESOURCE, RequestType.V3_FRONT_ENTRY);
default:
return getRequestType(t0, RequestType.LEGACY_STATIC_RESOURCE, RequestType.LEGACY_FRONT_ENTRY);
private static boolean isStaticResource(String firstToken) {
for (String resourceBasePath : RESOURCE_BASE_PATHS) {
if (firstToken.equals(resourceBasePath)) {
return true;
}
}
return firstToken.indexOf('.') != -1;
}

private static RequestType getRequestType(
StringTokenizer tokenizer,
RequestType resourceType,
RequestType entryType
) {
if (tokenizer.hasMoreElements()) {
return getRequestType(tokenizer.nextToken(), resourceType, entryType);
} else {
return entryType;
private static String trimFirstSlash(String s) {
if (s.length() > 0 && s.charAt(0) == '/') {
return s.substring(1);
}
return s;
}

private static RequestType getRequestType(String token, RequestType resourceType, RequestType entryType) {
if (token.equals("assets") || token.indexOf('.') >= 0) {
return resourceType;
} else {
return entryType;
public static class FrontApplicationRegistration {

private final String basePath;

public FrontApplicationRegistration(String basePath) {
this.basePath = Objects.requireNonNull(basePath, "basePath");
}
}

private enum RequestType {
LEGACY_FRONT_ENTRY,
LEGACY_STATIC_RESOURCE,
V2_FRONT_ENTRY,
V2_STATIC_RESOURCE,
V3_FRONT_ENTRY,
V3_STATIC_RESOURCE,
REST_API,
UNKNOWN,
public static FrontApplicationRegistration of(String basePath) {
return new FrontApplicationRegistration(basePath);
}

public String getBasePath() {
return basePath;
}
}

}
16 changes: 13 additions & 3 deletions web/src/main/resources/applicationContext-web.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

<bean id="commandHeaderTBaseSerializerFactory" class="com.navercorp.pinpoint.thrift.io.CommandHeaderTBaseSerializerFactory" factory-method="getDefaultInstance">
</bean>
Expand Down Expand Up @@ -52,9 +52,19 @@
<constructor-arg ref="metadataRowKeyDistributor2"/>
</bean>

<util:list id="frontApplicationRegistrations">
<bean class="com.navercorp.pinpoint.web.servlet.HttpIntentRoutingFilter$FrontApplicationRegistration">
<constructor-arg name="basePath" value="/v3" />
</bean>
<bean class="com.navercorp.pinpoint.web.servlet.HttpIntentRoutingFilter$FrontApplicationRegistration">
<constructor-arg name="basePath" value="/" />
</bean>
</util:list>

<bean id="rewriteFilter" class="com.navercorp.pinpoint.web.servlet.HttpIntentRoutingFilter">
<constructor-arg index="0" value="/index.html" />
<constructor-arg name="registrations" ref="frontApplicationRegistrations" />
</bean>

<bean id="additionalServletRegistrationBeanFactory" class="com.navercorp.pinpoint.web.servlet.AdditionalServletRegistrationBeanFactory" />
<bean id="apiServletRegistrationBean" factory-bean="additionalServletRegistrationBeanFactory" factory-method="addRegistration">
<constructor-arg index="0" value="/api/*"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class HttpIntentRoutingFilterTest {
@Test
public void rewriteTest() {
Assertions.assertThrows(NullPointerException.class, () -> {
HttpIntentRoutingFilter httpIntentRoutingFilter = new HttpIntentRoutingFilter("/index.html");
HttpIntentRoutingFilter httpIntentRoutingFilter = new HttpIntentRoutingFilter();

HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(servletRequest.getRequestURI()).thenReturn(ADMIN_REWRITE_TARGET);
Expand All @@ -50,7 +50,7 @@ public void rewriteTest() {

@Test
public void restApiWithRewritePathTest() throws IOException, ServletException {
HttpIntentRoutingFilter httpIntentRoutingFilter = new HttpIntentRoutingFilter("/index.html");
HttpIntentRoutingFilter httpIntentRoutingFilter = new HttpIntentRoutingFilter();

HttpServletRequest servletRequest = Mockito.mock(HttpServletRequest.class);
Mockito.when(servletRequest.getRequestURI()).thenReturn("/api" + ADMIN_REWRITE_TARGET + "/removeApplicationName");
Expand Down

0 comments on commit 345536d

Please sign in to comment.