Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- added StatusWrapper interface
  • Loading branch information
jiachen1120 authored and stevehu committed Dec 14, 2020
1 parent 5ba000b commit 54516c3
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 0 deletions.
11 changes: 11 additions & 0 deletions handler/src/main/java/com/networknt/handler/LightHttpHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import com.networknt.config.Config;
import com.networknt.handler.config.HandlerConfig;
import com.networknt.httpstring.AttachmentConstants;
import com.networknt.service.SingletonServiceFactory;
import com.networknt.status.Status;
import com.networknt.status.StatusWrapper;
import com.networknt.utility.Constants;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
Expand Down Expand Up @@ -76,6 +78,15 @@ default void setExchangeStatus(HttpServerExchange exchange, String code, final O
* @param status error status
*/
default void setExchangeStatus(HttpServerExchange exchange, Status status) {
// Wrap default status into custom status if the implementation of StatusWrapper was provided
StatusWrapper statusWrapper;
try {
statusWrapper = SingletonServiceFactory.getBean(StatusWrapper.class);
} catch (NoClassDefFoundError e) {
statusWrapper = null;
}
status = statusWrapper == null ? status : statusWrapper.wrap(status, exchange);

exchange.setStatusCode(status.getStatusCode());
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/json");
status.setDescription(status.getDescription().replaceAll("\\\\", "\\\\\\\\"));
Expand Down
4 changes: 4 additions & 0 deletions status/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-core</artifactId>
</dependency>
</dependencies>

</project>
24 changes: 24 additions & 0 deletions status/src/main/java/com/networknt/status/StatusWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.networknt.status;

import io.undertow.server.HttpServerExchange;

/**
* Interface to allow custom Status and then inject the customized status into framework through SingletonFactory
* <p>
* Implement the interface and configure in service.yml
* - com.networknt.status.StatusWrapper
* - custom implementation
*
* @author Jiachen Sun
*/

public interface StatusWrapper {
/**
* Encapsulate the default status of the framework as a custom status
*
* @param status The status to be wrapped
* @param exchange The source of custom info used to wrap status
* @return the custom status
*/
Status wrap(Status status, HttpServerExchange exchange);
}
66 changes: 66 additions & 0 deletions status/src/test/java/com/networknt/status/StatusWrapperTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.networknt.status;

import com.networknt.config.Config;
import com.networknt.service.SingletonServiceFactory;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SeparateClassloaderTestRunner.class)
public class StatusWrapperTest {
private static Config config = null;
private static final String homeDir = System.getProperty("user.home");

@BeforeClass
public static void setUp() throws Exception {
config = Config.getInstance();

// write a config file into the user home directory.
List<String> implementationList = new ArrayList<>();
implementationList.add("com.networknt.status.TestStatusWrapper");
Map<String, List<String>> implementationMap = new HashMap<>();
implementationMap.put("com.networknt.status.StatusWrapper", implementationList);
List<Map<String, List<String>>> interfaceList = new ArrayList<>();
interfaceList.add(implementationMap);
Map<String, Object> singletons = new HashMap<>();
singletons.put("singletons", interfaceList);
config.getMapper().writeValue(new File(homeDir + "/service.json"), singletons);

// Add home directory to the classpath of the system class loader.
AppURLClassLoader classLoader = new AppURLClassLoader(new URL[0], ClassLoader.getSystemClassLoader());
classLoader.addURL(new File(homeDir).toURI().toURL());
config.setClassLoader(classLoader);
}

@AfterClass
public static void tearDown() {
// Remove the service.yml from home directory
File test = new File(homeDir + "/service.json");
test.delete();
}

@Test
public void testStatusWrap() {
StatusWrapper statusWrapper = SingletonServiceFactory.getBean(StatusWrapper.class);
Status status = new Status("ERR10001");
status = statusWrapper.wrap(status, null);
Assert.assertEquals("{\"error\":{\"statusCode\":401,\"code\":\"ERR10001\",\"message\":\"AUTH_TOKEN_EXPIRED\",\"description\":\"Jwt token in authorization header expired\",\"customInfo\":\"custom_info\",\"severity\":\"ERROR\"}}", status.toString());
}

@Test
public void testStatusWrapWithArgs() {
StatusWrapper statusWrapper = SingletonServiceFactory.getBean(StatusWrapper.class);
Status status = new Status("ERR11000","arg1", "arg2");
status = statusWrapper.wrap(status, null);
Assert.assertEquals("{\"error\":{\"statusCode\":400,\"code\":\"ERR11000\",\"message\":\"VALIDATOR_REQUEST_PARAMETER_QUERY_MISSING\",\"description\":\"Query parameter arg1 is required on path arg2 but not found in request.\",\"customInfo\":\"custom_info\",\"severity\":\"ERROR\"}}", status.toString());
}
}
42 changes: 42 additions & 0 deletions status/src/test/java/com/networknt/status/TestStatusWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.networknt.status;

import io.undertow.server.HttpServerExchange;

public class TestStatusWrapper implements StatusWrapper {
@Override
public Status wrap(Status status, HttpServerExchange exchange) {
return new TestStatus(status, exchange);
}

private class TestStatus extends Status {
private String customInfo;

public TestStatus(Status status, HttpServerExchange exchange) {
this.setStatusCode(status.getStatusCode());
this.setCode(status.getCode());
this.setDescription(status.getDescription());
this.setMessage(status.getMessage());
this.setSeverity(status.getSeverity());
this.setCustomInfo("custom_info");
}

public String getCustomInfo() {
return customInfo;
}

public void setCustomInfo(String customInfo) {
this.customInfo = customInfo;
}

@Override
public String toString() {
String message = "{\"error\":" + "{\"statusCode\":" + getStatusCode()
+ ",\"code\":\"" + getCode()
+ "\",\"message\":\"" + getMessage()
+ "\",\"description\":\"" + getDescription()
+ "\",\"customInfo\":\"" + getCustomInfo()
+ "\",\"severity\":\"" + getSeverity() + "\"}" + "}";
return message;
}
}
}

0 comments on commit 54516c3

Please sign in to comment.