diff --git a/pom.xml b/pom.xml
index aef54e3c..597ab496 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,289 +1,287 @@
-
- 4.0.0
- com.metamug
- mason
- 3.3
- jar
- com.metamug:mason
- API SDK
- https://metamug.com
-
- UTF-8
- 1.8
- 1.8
-
-
-
- Apache License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
- repo
-
-
-
-
- Anish Hirlekar
- anish.hirlekar@metamug.com
- Metamug Technologies
- http://www.metamug.com
-
- Developer
-
- +5:30
-
-
- Deepak Mishra
- deepak.mishra@metamug.com
- Metamug Technologies
- http://www.metamug.com
-
- Developer
-
- +5:30
-
-
- Kaustubh Damle
- kaustubh.damle@metamug.com
- Metamug Technologies
- http://www.metamug.com
-
- Developer
-
- +5:30
-
-
-
- scm:git:git@github.com:metamug/mason.git
- scm:git:git@github.com:metamug/mason.git
- git@github.com:metamug/mason.git
-
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
-
-
- release
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- 1.8
- 1.8
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.4
-
-
- attach-sources
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.10.3
-
- true
- true
- true
- true
- true
- -Xdoclint:none
-
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
- 2.5.3
-
- true
- false
- release
- deploy
-
-
-
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.7
- true
-
- ossrh
- https://oss.sonatype.org/
- true
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 1.6
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
+
+ 4.0.0
+ com.metamug
+ mason
+ 3.3
+ jar
+ com.metamug:mason
+ API SDK
+ https://metamug.com
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+ Apache License, Version 2.0
+ http://www.apache.org/licenses/LICENSE-2.0.txt
+ repo
+
+
+
+
+ Anish Hirlekar
+ anish.hirlekar@metamug.com
+ Metamug Technologies
+ http://www.metamug.com
+
+ Developer
+
+ +5:30
+
+
+ Deepak Mishra
+ deepak.mishra@metamug.com
+ Metamug Technologies
+ http://www.metamug.com
+
+ Developer
+
+ +5:30
+
+
+ Kaustubh Damle
+ kaustubh.damle@metamug.com
+ Metamug Technologies
+ http://www.metamug.com
+
+ Developer
+
+ +5:30
+
+
+
+ scm:git:git@github.com:metamug/mason.git
+ scm:git:git@github.com:metamug/mason.git
+ git@github.com:metamug/mason.git
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+ ossrh
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
+
+ release
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.4
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.3
+
+ true
+ true
+ true
+ true
+ true
+ -Xdoclint:none
+
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 2.5.3
+
+ true
+ false
+ release
+ deploy
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.7
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
-
-
- org.eluder.coveralls
- coveralls-maven-plugin
- 4.3.0
-
-
- org.jacoco
- jacoco-maven-plugin
- 0.7.9
-
-
-
- prepare-agent
-
-
-
- report
- prepare-package
-
- report
-
-
-
- prepare-integration-test-agent
-
- prepare-agent-integration
-
-
-
- generate-integration-test-report
-
- report-integration
-
-
-
-
-
-
-
-
-
-
-
- org.codehaus.groovy
- groovy-all
- 2.4.15
-
-
- org.apache.ivy
- ivy
- 2.4.0
-
-
- com.squareup.okhttp3
- okhttp
- 3.10.0
-
-
- mysql
- mysql-connector-java
- 8.0.15
-
-
- com.google.protobuf
- protobuf-java
-
-
-
-
- org.json
- json
- 20180813
-
-
- com.github.wnameless.json
- json-flattener
- 0.7.1
-
-
- org.apache.commons
- commons-text
- 1.6
-
-
- org.eclipse.persistence
- org.eclipse.persistence.moxy
- 2.6.4
-
-
- javax.servlet
- jstl
- 1.2
-
-
- junit
- junit
- 4.12
- test
-
-
- org.mockito
- mockito-all
- 1.10.19
- test
-
-
- org.hamcrest
- hamcrest-core
- 1.3
- test
-
-
- javax.servlet
- javax.servlet-api
- 4.0.1
-
-
- com.metamug
- mtg-api
- 1.5
-
-
- javax
- javaee-web-api
- 8.0
-
-
- com.jayway.jsonpath
- json-path
- 2.4.0
-
-
-
+
+ org.eluder.coveralls
+ coveralls-maven-plugin
+ 4.3.0
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.7.9
+
+
+
+ prepare-agent
+
+
+
+ report
+ prepare-package
+
+ report
+
+
+
+ prepare-integration-test-agent
+
+ prepare-agent-integration
+
+
+
+ generate-integration-test-report
+
+ report-integration
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ 2.4.15
+
+
+ org.apache.ivy
+ ivy
+ 2.4.0
+
+
+ com.squareup.okhttp3
+ okhttp
+ 3.10.0
+
+
+ mysql
+ mysql-connector-java
+ 8.0.15
+
+
+ com.google.protobuf
+ protobuf-java
+
+
+
+
+ org.json
+ json
+ 20180813
+
+
+ com.github.wnameless.json
+ json-flattener
+ 0.7.1
+
+
+ org.apache.commons
+ commons-text
+ 1.6
+
+
+ org.eclipse.persistence
+ org.eclipse.persistence.moxy
+ 2.6.4
+
+
+ javax.servlet
+ jstl
+ 1.2
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.10.19
+ test
+
+
+ org.hamcrest
+ hamcrest-core
+ 1.3
+ test
+
+
+ javax.servlet
+ javax.servlet-api
+ 4.0.1
+
+
+ com.metamug
+ mtg-api
+ 1.5
+
+
+ javax
+ javaee-web-api
+ 8.0
+
+
+ com.jayway.jsonpath
+ json-path
+ 2.4.0
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/metamug/mason/Router.java b/src/main/java/com/metamug/mason/Router.java
index 1a7cfcd0..a3f905d5 100644
--- a/src/main/java/com/metamug/mason/Router.java
+++ b/src/main/java/com/metamug/mason/Router.java
@@ -506,17 +506,22 @@
*/
package com.metamug.mason;
-import com.metamug.entity.Request;
-import com.metamug.mason.entity.RootResource;
import static com.metamug.mason.entity.request.FormStrategy.APPLICATION_FORM_URLENCODED;
import static com.metamug.mason.entity.request.HtmlStrategy.APPLICATION_HTML;
import static com.metamug.mason.entity.request.JsonStrategy.APPLICATION_JSON;
-import com.metamug.mason.entity.request.RequestAdapter;
import static com.metamug.mason.entity.request.MultipartFormStrategy.MULTIPART_FORM_DATA;
+import static com.metamug.mason.tag.ResourceTagHandler.MSG_RESOURCE_NOT_FOUND;
+
+import com.metamug.entity.Request;
+import com.metamug.mason.entity.RootResource;
+import com.metamug.mason.entity.request.RequestAdapter;
import com.metamug.mason.service.AuthService;
import com.metamug.mason.service.ConnectionProvider;
import com.metamug.mason.service.QueryManagerService;
-import static com.metamug.mason.tag.ResourceTagHandler.MSG_RESOURCE_NOT_FOUND;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -524,6 +529,7 @@
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
+
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -532,237 +538,234 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
* Rest Controller. Handles all the incoming requests
*
* @author Kaisteel
*/
+@WebFilter(urlPatterns = "/rest/*", filterName = "Router", description = "Default REST filter", initParams = {
+ @WebInitParam(name = "datasource", value = "jdbc/mason") })
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 25)
public class Router implements Filter {
- private static final String JSP_EXTN = ".jsp";
- private static final String RESOURCES_FOLDER = "/WEB-INF/resources/";
- private String encoding;
-
- public static final String HEADER_CONTENT_TYPE = "Content-Type";
- public static final String QUERY_FILE_NAME = "query.properties";
- public static final String MASON_QUERY = "masonQuery"; //to hold queries from properties file
- public static final String DATA_SOURCE = "datasource";
- public static final String MTG_AUTH_BASIC = "MTG_AUTH_BASIC";
- public static final String MTG_AUTH_BEARER = "MTG_AUTH_BEARER";
-
- private ConnectionProvider connectionProvider;
- public static final String CONNECTION_PROVIDER = "connectionProvider";
- public static final String MASON_REQUEST = "mtgReq";
-
- public Router() {
-
- }
-
- /**
- *
- * @param request The servlet request we are processing
- * @param response The servlet response we are creating
- * @param chain The filter chain we are processing
- *
- * @exception IOException if an input/output error occurs
- * @exception ServletException if a servlet error occurs
- */
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest) request;
- HttpServletResponse res = (HttpServletResponse) response;
- //Setting character encoding
- if (null == request.getCharacterEncoding()) {
- request.setCharacterEncoding(encoding);
- }
-
- String path = req.getServletPath();
- String[] tokens = path.split("/");
- int versionTokenIndex = -1;
- for (int i = 0; i < tokens.length; i++) {
- if (tokens[i].matches("^.*(v\\d+\\.\\d+).*$")) {
- versionTokenIndex = i;
- break;
- }
- }
- //check auth request
- if (versionTokenIndex == -1 && req.getMethod().equalsIgnoreCase("post") && !path.contains("query")) {
- RootResource rootResource = new RootResource(req, res);
- rootResource.processAuth(new AuthService(connectionProvider));
- return;
- }
- if (tokens.length <= 2 || path.contains("index") || path.contains("docs")) {
- chain.doFilter(request, response);
- return;
- }
- processRequest(req, res);
- }
-
- /**
- * Servlet version of the request handling. Cast objects to handle REST
- * request
- *
- * @param req
- * @param res
- * @param tokens The URI split by /
- * @throws IOException
- */
- private void processRequest(HttpServletRequest req, HttpServletResponse res)
- throws IOException {
-
- String contentType = req.getContentType() == null ? APPLICATION_HTML : req.getContentType().toLowerCase();
- String method = req.getMethod().toLowerCase();
-
- boolean validContentType = contentType.contains(APPLICATION_HTML) || contentType.contains("application/xml")
- || contentType.contains(APPLICATION_FORM_URLENCODED) || contentType.contains(APPLICATION_JSON) || contentType.contains(MULTIPART_FORM_DATA);
-
- if (!"get".equals(method) && !"delete".equals(method) && !validContentType) {
- writeError(res, 415, "Unsupported Media Type"); //methods having content(POST,DELETE) in body, sent with invalid contentType
- return;
- }
-
- res.setContentType(APPLICATION_JSON);
- //requesting a REST resource
- String resourceName = "";
- try {
- //get queries
- Request mtgReq = RequestAdapter.create(req);
- resourceName = mtgReq.getResource().getName();
-
- String jspPath = RESOURCES_FOLDER + "v" + mtgReq.getResource().getVersion() + "/" + resourceName + JSP_EXTN;
- File file = new File(req.getServletContext().getRealPath(jspPath));
-
- if(file.exists()) {
- req.setAttribute(MASON_REQUEST, mtgReq);
-
- //Adding to request, otherwise the user has to write ${applicationScope.datasource}
- req.setAttribute(DATA_SOURCE, req.getServletContext().getAttribute(DATA_SOURCE));
- req.setAttribute(CONNECTION_PROVIDER, connectionProvider);
-
- //Query map of stored queries in a file
- Object queryMap = req.getServletContext().getAttribute(MASON_QUERY);
- req.setAttribute(MASON_QUERY, queryMap);
-
- //save method as attribute because jsp only accepts GET and POST
- //https://stackoverflow.com/a/46489035
- req.setAttribute("mtgMethod", req.getMethod()); //needed by ExceptionTagHandler
- req.getRequestDispatcher(jspPath).forward(
- new HttpServletRequestWrapper(req) {
- @Override
- public String getMethod() {
- String method = super.getMethod();
- if (method.equalsIgnoreCase("delete") || method.equalsIgnoreCase("put")) {
- return "POST";
- } else {
- return method;
- }
- }
- }, res
- );
- } else {
- writeError(res, 404, MSG_RESOURCE_NOT_FOUND);
- }
-
- } catch (IOException | ServletException | JSONException ex) {
- if (ex.getClass().toString().contains("com.eclipsesource.json.ParseException")) {
- writeError(res, 422, "Could not parse the body of the request according to the provided Content-Type.");
- } else if (ex.getCause() != null) {
- String cause = ex.getCause().toString().split(": ")[1].replaceAll("(\\s|\\n|\\r|\\n\\r)+", " ");
- writeError(res, 500, cause);
- } else if (ex.getMessage().contains("ELException")) {
- writeError(res, 512, "Incorrect test condition in '" + resourceName + "' resource");
- } else {
- writeError(res, 500, ex.getMessage().replaceAll("(\\s|\\n|\\r|\\n\\r)+", " "));
- Logger.getLogger(Router.class.getName()).log(Level.SEVERE, "Router " + resourceName + ":{0}", ex.getMessage());
- }
- Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
- } catch (NullPointerException ex) {
- Logger.getLogger(Router.class.getName()).log(Level.SEVERE, "Router " + resourceName + ":{0}", ex.getMessage());
- //The 404error.jsp works fine when a non-existing resource is called. But requesting a dispatcher for non-existing resource it returns Null during test executiong and a call to forward() on such a dispatcher creates NPE and the RouterTest fails. This catch if for that.
- writeError(res, 404, "Resource doesn't exist." + ex.getMessage());
- }
- }
-
- /**
- * Error message to be returned
- *
- * @param res HTTP Response
- * @param status Http Status Code
- * @param message Message in Response
- * @throws IOException
- */
- private void writeError(HttpServletResponse res, int status, String message) throws IOException {
-
- try (PrintWriter writer = res.getWriter()) {
- res.setContentType("application/json;charset=UTF-8");
- res.setCharacterEncoding("UTF-8");
- res.setStatus(status);
- JSONObject obj = new JSONObject();
- obj.put("status", status);
- obj.put("message", message);
- writer.print(obj.toString());
- writer.flush();
- }
- }
-
- /**
- * Destroy method for this filter
- */
- @Override
- public void destroy() {
- try {
- connectionProvider.shutdown();
- } catch (SQLException | NamingException ex) {
- Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
- }
- }
-
- /**
- * Init method for this filter
- *
- * @param config
- */
- @Override
- public void init(FilterConfig config) {
- encoding = config.getInitParameter("requestEncoding");
- if (encoding == null) {
- encoding = "UTF-8";
- }
-
- if (config.getInitParameter(DATA_SOURCE) != null) {
- config.getServletContext().setAttribute(DATA_SOURCE, config.getInitParameter("datasource"));
- } else {
- config.getServletContext().setAttribute(DATA_SOURCE, "jdbc/mason");
- }
-
- if (config.getInitParameter(MTG_AUTH_BASIC) != null) {
- config.getServletContext().setAttribute(MTG_AUTH_BASIC, config.getInitParameter(MTG_AUTH_BASIC));
- }
- if (config.getInitParameter(MTG_AUTH_BEARER) != null) {
- config.getServletContext().setAttribute(MTG_AUTH_BEARER, config.getInitParameter(MTG_AUTH_BEARER));
- }
-
- InputStream queryFileInputStream = Router.class.getClassLoader().getResourceAsStream(QUERY_FILE_NAME);
- QueryManagerService queryManagerService = new QueryManagerService(queryFileInputStream);
-
- try {
- connectionProvider = new ConnectionProvider((String) config.getServletContext().getAttribute(DATA_SOURCE));
- //connectionProvider.getMasonDatasource();
- config.getServletContext().setAttribute(MASON_QUERY, queryManagerService.getQueryMap());
- config.getServletContext().setAttribute(CONNECTION_PROVIDER, connectionProvider);
- queryFileInputStream.close();
- } catch (IOException | SQLException | NamingException ex) {
- Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
- } catch (NullPointerException nx) {
- //Logger.getLogger(Router.class.getName()).log(Level.SEVERE, QUERY_FILE_NAME + " file does not exist!", nx);
- }
- }
+ private static final String JSP_EXTN = ".jsp";
+ private static final String RESOURCES_FOLDER = "/WEB-INF/resources/";
+ private String encoding;
+
+ public static final String HEADER_CONTENT_TYPE = "Content-Type";
+ public static final String QUERY_FILE_NAME = "query.properties";
+ public static final String MASON_QUERY = "masonQuery"; // to hold queries from properties file
+ public static final String DATA_SOURCE = "datasource";
+ public static final String MTG_AUTH_BASIC = "MTG_AUTH_BASIC";
+ public static final String MTG_AUTH_BEARER = "MTG_AUTH_BEARER";
+
+ private ConnectionProvider connectionProvider;
+ public static final String CONNECTION_PROVIDER = "connectionProvider";
+ public static final String MASON_REQUEST = "mtgReq";
+
+ public Router() {
+
+ }
+
+ /**
+ *
+ * @param request The servlet request we are processing
+ * @param response The servlet response we are creating
+ * @param chain The filter chain we are processing
+ *
+ * @exception IOException if an input/output error occurs
+ * @exception ServletException if a servlet error occurs
+ */
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest) request;
+ HttpServletResponse res = (HttpServletResponse) response;
+ // Setting character encoding
+ if (null == request.getCharacterEncoding()) {
+ request.setCharacterEncoding(encoding);
+ }
+
+ String path = req.getServletPath();
+ String[] tokens = path.split("/");
+ int versionTokenIndex = -1;
+ for (int i = 0; i < tokens.length; i++) {
+ if (tokens[i].matches("^.*(v\\d+\\.\\d+).*$")) {
+ versionTokenIndex = i;
+ break;
+ }
+ }
+ // check auth request
+ if (versionTokenIndex == -1 && req.getMethod().equalsIgnoreCase("post") && !path.contains("query")) {
+ RootResource rootResource = new RootResource(req, res);
+ rootResource.processAuth(new AuthService(connectionProvider));
+ return;
+ }
+ if (tokens.length <= 2 || path.contains("index") || path.contains("docs")) {
+ chain.doFilter(request, response);
+ return;
+ }
+ processRequest(req, res);
+ }
+
+ /**
+ * Servlet version of the request handling. Cast objects to handle REST request
+ *
+ * @param req
+ * @param res
+ * @throws IOException
+ */
+ private void processRequest(HttpServletRequest req, HttpServletResponse res) throws IOException {
+
+ String contentType = req.getContentType() == null ? APPLICATION_HTML : req.getContentType().toLowerCase();
+ String method = req.getMethod().toLowerCase();
+
+ boolean validContentType = contentType.contains(APPLICATION_HTML) || contentType.contains("application/xml")
+ || contentType.contains(APPLICATION_FORM_URLENCODED) || contentType.contains(APPLICATION_JSON)
+ || contentType.contains(MULTIPART_FORM_DATA);
+
+ if (!"get".equals(method) && !"delete".equals(method) && !validContentType) {
+ writeError(res, 415, "Unsupported Media Type"); //methods having content(POST,DELETE) in body, sent with invalid contentType
+ return;
+ }
+
+ res.setContentType(APPLICATION_JSON);
+ // requesting a REST resource
+ String resourceName = "";
+ try {
+ // get queries
+ Request mtgReq = RequestAdapter.create(req);
+ resourceName = mtgReq.getResource().getName();
+
+ String jspPath = RESOURCES_FOLDER + "v" + mtgReq.getResource().getVersion() + "/" + resourceName + JSP_EXTN;
+ File file = new File(req.getServletContext().getRealPath(jspPath));
+
+ if (file.exists()) {
+ req.setAttribute(MASON_REQUEST, mtgReq);
+
+ //Adding to request, otherwise the user has to write ${applicationScope.datasource}
+ req.setAttribute(DATA_SOURCE, req.getServletContext().getAttribute(DATA_SOURCE));
+ req.setAttribute(CONNECTION_PROVIDER, connectionProvider);
+
+ // Query map of stored queries in a file
+ Object queryMap = req.getServletContext().getAttribute(MASON_QUERY);
+ req.setAttribute(MASON_QUERY, queryMap);
+
+ // save method as attribute because jsp only accepts GET and POST
+ // https://stackoverflow.com/a/46489035
+ req.setAttribute("mtgMethod", req.getMethod()); // needed by ExceptionTagHandler
+ req.getRequestDispatcher(jspPath).forward(new HttpServletRequestWrapper(req) {
+ @Override
+ public String getMethod() {
+ String method = super.getMethod();
+ if (method.equalsIgnoreCase("delete") || method.equalsIgnoreCase("put")) {
+ return "POST";
+ } else {
+ return method;
+ }
+ }
+ }, res);
+ } else {
+ writeError(res, 404, MSG_RESOURCE_NOT_FOUND);
+ }
+
+ } catch (IOException | ServletException | JSONException ex) {
+ if (ex.getClass().toString().contains("com.eclipsesource.json.ParseException")) {
+ writeError(res, 422, "Could not parse the body of the request according to the provided Content-Type.");
+ } else if (ex.getCause() != null) {
+ String cause = ex.getCause().toString().split(": ")[1].replaceAll("(\\s|\\n|\\r|\\n\\r)+", " ");
+ writeError(res, 500, cause);
+ } else if (ex.getMessage().contains("ELException")) {
+ writeError(res, 512, "Incorrect test condition in '" + resourceName + "' resource");
+ } else {
+ writeError(res, 500, ex.getMessage().replaceAll("(\\s|\\n|\\r|\\n\\r)+", " "));
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, "Router " + resourceName + ":{0}", ex.getMessage());
+ }
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ } catch (NullPointerException ex) {
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, "Router " + resourceName + ":{0}", ex.getMessage());
+ //The 404error.jsp works fine when a non-existing resource is called. But requesting a dispatcher for non-existing resource it returns Null during test executiong and a call to forward() on such a dispatcher creates NPE and the RouterTest fails. This catch if for that.
+ writeError(res, 404, "Resource doesn't exist." + ex.getMessage());
+ }
+ }
+
+ /**
+ * Error message to be returned
+ *
+ * @param res HTTP Response
+ * @param status HTTP Status Code
+ * @param message Message in Response
+ * @throws IOException
+ */
+ private void writeError(HttpServletResponse res, int status, String message) throws IOException {
+
+ try (PrintWriter writer = res.getWriter()) {
+ res.setContentType("application/json;charset=UTF-8");
+ res.setCharacterEncoding("UTF-8");
+ res.setStatus(status);
+ JSONObject obj = new JSONObject();
+ obj.put("status", status);
+ obj.put("message", message);
+ writer.print(obj.toString());
+ writer.flush();
+ }
+ }
+
+ /**
+ * Destroy method for this filter
+ */
+ @Override
+ public void destroy() {
+ try {
+ connectionProvider.shutdown();
+ } catch (SQLException | NamingException ex) {
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+
+ /**
+ * Init method for this filter
+ *
+ * @param config
+ */
+ @Override
+ public void init(FilterConfig config) {
+ encoding = config.getInitParameter("requestEncoding");
+ if (encoding == null) {
+ encoding = "UTF-8";
+ }
+
+ if (config.getInitParameter(DATA_SOURCE) != null) {
+ config.getServletContext().setAttribute(DATA_SOURCE, config.getInitParameter(DATA_SOURCE));
+ } else {
+ config.getServletContext().setAttribute(DATA_SOURCE, "jdbc/mason");
+ }
+
+ if (config.getInitParameter(MTG_AUTH_BASIC) != null) {
+ config.getServletContext().setAttribute(MTG_AUTH_BASIC, config.getInitParameter(MTG_AUTH_BASIC));
+ }
+ if (config.getInitParameter(MTG_AUTH_BEARER) != null) {
+ config.getServletContext().setAttribute(MTG_AUTH_BEARER, config.getInitParameter(MTG_AUTH_BEARER));
+ }
+
+ InputStream queryFileInputStream = Router.class.getClassLoader().getResourceAsStream(QUERY_FILE_NAME);
+ QueryManagerService queryManagerService = new QueryManagerService(queryFileInputStream);
+
+ try {
+ connectionProvider = new ConnectionProvider((String) config.getServletContext().getAttribute(DATA_SOURCE));
+ config.getServletContext().setAttribute(MASON_QUERY, queryManagerService.getQueryMap());
+ config.getServletContext().setAttribute(CONNECTION_PROVIDER, connectionProvider);
+ queryFileInputStream.close();
+ } catch (IOException | SQLException | NamingException ex) {
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ } catch (NullPointerException nx) {
+ Logger.getLogger(Router.class.getName()).log(Level.SEVERE, QUERY_FILE_NAME + " file does not exist!", nx);
+ }
+ }
}
diff --git a/src/main/java/com/metamug/mason/entity/auth/JWebToken.java b/src/main/java/com/metamug/mason/entity/auth/JWebToken.java
index fbe2e491..6ac2fb0f 100644
--- a/src/main/java/com/metamug/mason/entity/auth/JWebToken.java
+++ b/src/main/java/com/metamug/mason/entity/auth/JWebToken.java
@@ -506,6 +506,10 @@
*/
package com.metamug.mason.entity.auth;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@@ -517,11 +521,9 @@
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
+
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
*
@@ -529,119 +531,118 @@
*/
public class JWebToken {
- private static final String SECRET_KEY = "FREE_MASON"; //@TODO Add Signature here
- private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
- private static final String ISSUER = "mason.metamug.net";
- private static final String JWT_HEADER = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
- private JSONObject payload = new JSONObject();
- private String signature;
- private String encodedHeader;
+ private static final String SECRET_KEY = "FREE_MASON"; // @TODO Add Signature here
+ private static final String ISSUER = "mason.metamug.net";
+ private static final String JWT_HEADER = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
+ private JSONObject payload = new JSONObject();
+ private String signature;
+ private String encodedHeader;
- private JWebToken() {
- encodedHeader = encode(new JSONObject(JWT_HEADER));
- }
+ private JWebToken() {
+ encodedHeader = encode(new JSONObject(JWT_HEADER));
+ }
- public JWebToken(JSONObject payload) {
- this(payload.getString("sub"), payload.getJSONArray("aud"), payload.getLong("exp"));
- }
+ public JWebToken(JSONObject payload) {
+ this(payload.getString("sub"), payload.getJSONArray("aud"), payload.getLong("exp"));
+ }
- public JWebToken(String sub, JSONArray aud, long expires) {
- this();
- payload.put("sub", sub);
- payload.put("aud", aud);
- payload.put("exp", expires);
- payload.put("iat", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
- payload.put("iss", ISSUER);
- payload.put("jti", UUID.randomUUID().toString()); //how do we use this?
- signature = hmacSha256(encodedHeader + "." + encode(payload), SECRET_KEY);
- }
+ public JWebToken(String sub, JSONArray aud, long expires) {
+ this();
+ payload.put("sub", sub);
+ payload.put("aud", aud);
+ payload.put("exp", expires);
+ payload.put("iat", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
+ payload.put("iss", ISSUER);
+ payload.put("jti", UUID.randomUUID().toString()); // how do we use this?
+ signature = hmacSha256(encodedHeader + "." + encode(payload), SECRET_KEY);
+ }
- /**
- * For verification
- *
- * @param token
- * @throws java.security.NoSuchAlgorithmException
- */
- public JWebToken(String token) throws NoSuchAlgorithmException {
- this();
- String[] parts = token.split("\\.");
- if (parts.length != 3) {
- throw new IllegalArgumentException("Invalid Token format");
- }
- if (encodedHeader.equals(parts[0])) {
- encodedHeader = parts[0];
- } else {
- throw new NoSuchAlgorithmException("JWT Header is Incorrect: " + parts[0]);
- }
+ /**
+ * For verification
+ *
+ * @param token
+ * @throws java.security.NoSuchAlgorithmException
+ */
+ public JWebToken(String token) throws NoSuchAlgorithmException {
+ this();
+ String[] parts = token.split("\\.");
+ if (parts.length != 3) {
+ throw new IllegalArgumentException("Invalid Token format");
+ }
+ if (encodedHeader.equals(parts[0])) {
+ encodedHeader = parts[0];
+ } else {
+ throw new NoSuchAlgorithmException("JWT Header is Incorrect: " + parts[0]);
+ }
- payload = new JSONObject(decode(parts[1]));
- if (payload.isEmpty()) {
- throw new JSONException("Payload is Empty: ");
- }
- if (!payload.has("exp")) {
- throw new JSONException("Payload doesn't contain expiry " + payload);
- }
- signature = parts[2];
- }
+ payload = new JSONObject(decode(parts[1]));
+ if (payload.isEmpty()) {
+ throw new JSONException("Payload is Empty: ");
+ }
+ if (!payload.has("exp")) {
+ throw new JSONException("Payload doesn't contain expiry " + payload);
+ }
+ signature = parts[2];
+ }
- @Override
- public String toString() {
- return encodedHeader + "." + encode(payload) + "." + signature;
- }
+ @Override
+ public String toString() {
+ return encodedHeader + "." + encode(payload) + "." + signature;
+ }
- public boolean isValid() {
- return payload.getLong("exp") > (LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)) //token not expired
- && signature.equals(hmacSha256(encodedHeader + "." + encode(payload), SECRET_KEY)); //signature matched
- }
+ public boolean isValid() {
+ return payload.getLong("exp") > (LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)) // token not expired
+ && signature.equals(hmacSha256(encodedHeader + "." + encode(payload), SECRET_KEY)); // signature matched
+ }
- public String getSubject() {
- return payload.getString("sub");
- }
+ public String getSubject() {
+ return payload.getString("sub");
+ }
- public List getAudience() {
- JSONArray arr = payload.getJSONArray("aud");
- List list = new ArrayList<>();
- for (int i = 0; i < arr.length(); i++) {
- list.add(arr.getString(i));
- }
- return list;
- }
+ public List getAudience() {
+ JSONArray arr = payload.getJSONArray("aud");
+ List list = new ArrayList<>();
+ for (int i = 0; i < arr.length(); i++) {
+ list.add(arr.getString(i));
+ }
+ return list;
+ }
- private static String encode(JSONObject obj) {
- return encode(obj.toString().getBytes(StandardCharsets.UTF_8));
- }
+ private static String encode(JSONObject obj) {
+ return encode(obj.toString().getBytes(StandardCharsets.UTF_8));
+ }
- private static String encode(byte[] bytes) {
- return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
- }
+ private static String encode(byte[] bytes) {
+ return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
+ }
- private static String decode(String encodedString) {
- return new String(Base64.getUrlDecoder().decode(encodedString));
- }
+ private static String decode(String encodedString) {
+ return new String(Base64.getUrlDecoder().decode(encodedString));
+ }
- /**
- * Sign with HMAC SHA256 (HS256)
- *
- * @param data
- * @return
- * @throws Exception
- */
- private String hmacSha256(String data, String secret) {
- try {
+ /**
+ * Sign with HMAC SHA256 (HS256)
+ *
+ * @param data
+ * @return
+ * @throws Exception
+ */
+ private String hmacSha256(String data, String secret) {
+ try {
- //MessageDigest digest = MessageDigest.getInstance("SHA-256");
- byte[] hash = secret.getBytes(StandardCharsets.UTF_8);//digest.digest(secret.getBytes(StandardCharsets.UTF_8));
+ // MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] hash = secret.getBytes(StandardCharsets.UTF_8);// digest.digest(secret.getBytes(StandardCharsets.UTF_8));
- Mac sha256Hmac = Mac.getInstance("HmacSHA256");
- SecretKeySpec secretKey = new SecretKeySpec(hash, "HmacSHA256");
- sha256Hmac.init(secretKey);
+ Mac sha256Hmac = Mac.getInstance("HmacSHA256");
+ SecretKeySpec secretKey = new SecretKeySpec(hash, "HmacSHA256");
+ sha256Hmac.init(secretKey);
- byte[] signedBytes = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
- return encode(signedBytes);
- } catch (NoSuchAlgorithmException | InvalidKeyException ex) {
- Logger.getLogger(JWebToken.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
- return null;
- }
- }
+ byte[] signedBytes = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
+ return encode(signedBytes);
+ } catch (NoSuchAlgorithmException | InvalidKeyException ex) {
+ Logger.getLogger(JWebToken.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+ return null;
+ }
+ }
}
diff --git a/src/main/java/com/metamug/mason/entity/response/JSONOutput.java b/src/main/java/com/metamug/mason/entity/response/JSONOutput.java
index 07881bce..c5d37506 100644
--- a/src/main/java/com/metamug/mason/entity/response/JSONOutput.java
+++ b/src/main/java/com/metamug/mason/entity/response/JSONOutput.java
@@ -506,125 +506,128 @@
*/
package com.metamug.mason.entity.response;
-import com.metamug.entity.Response;
-import com.metamug.mason.io.mpath.MPathUtil;
-import com.metamug.mason.io.objectreturn.ObjectReturn;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.logging.Level;
import java.util.logging.Logger;
+
import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException;
+
import org.apache.taglibs.standard.tag.common.sql.ResultImpl;
import org.json.JSONArray;
import org.json.JSONObject;
+import com.metamug.entity.Response;
+import com.metamug.mason.io.mpath.MPathUtil;
+import com.metamug.mason.io.objectreturn.ObjectReturn;
+
/**
* JSONs Output Object
*/
public class JSONOutput extends MasonOutput{
- @Override
- protected JSONObject getContent() {
- JSONObject responseJson = new JSONObject();
- outputMap.entrySet().forEach( entry -> {
- Object obj = entry.getValue();
- String key = entry.getKey();
- if(obj == null) {
- responseJson.put(key, new JSONObject());
- } else if (obj instanceof ResultImpl) {
- responseJson.put(key, getJson((ResultImpl) obj));
- } else if (obj instanceof JSONObject) {
- responseJson.put(key, obj);
- } else if (obj instanceof JSONArray) {
- responseJson.put(key, obj);
- } else if (obj instanceof String) {
- responseJson.put(key, obj);
- } else if (obj instanceof List) {
- JSONArray array = new JSONArray();
+ @Override
+ protected JSONObject getContent() {
+ JSONObject responseJson = new JSONObject();
+ outputMap.entrySet().forEach( entry -> {
+ Object obj = entry.getValue();
+ String key = entry.getKey();
+ if(obj == null) {
+ responseJson.put(key, new JSONObject());
+ } else if (obj instanceof ResultImpl) {
+ responseJson.put(key, getJson((ResultImpl) obj));
+ } else if (obj instanceof JSONObject) {
+ responseJson.put(key, obj);
+ } else if (obj instanceof JSONArray) {
+ responseJson.put(key, obj);
+ } else if (obj instanceof String) {
+ responseJson.put(key, obj);
+ } else if (obj instanceof List) {
+ JSONArray array = new JSONArray();
List