Java tutorial
/** * Personium * Copyright 2014 - 2017 FUJITSU LIMITED * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.personium.engine.rs; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import io.personium.engine.PersoniumEngineContext; import io.personium.engine.PersoniumEngineException; import io.personium.engine.source.ISourceManager; import io.personium.engine.utils.PersoniumEngineConfig; /** * Service. */ public abstract class AbstractService { /** . */ private static Log log = LogFactory.getLog(AbstractService.class); /** ??. */ private String sourcePath = ""; /** Service??. */ private String serviceName = ""; /** . */ @Context private ServletContext context; /** URL???????. */ private static final String KEY_HEADER_BASEURL = "X-Baseurl"; /** URL???????. */ private static final String KEY_HEADER_REQUEST_URI = "X-Request-Uri"; /** HTTP?. */ private static final int PORT_HTTP = 80; /** HTTPS?. */ private static final int PORT_HTTPS = 443; /** ??? . */ @HeaderParam("X-Personium-Es-Index") private String index; /** ???. */ @HeaderParam("X-Personium-Es-Type") private String type; /** ???ID. */ @HeaderParam("X-Personium-Es-Id") private String id; /** ???RoutingID. */ @HeaderParam("X-Personium-Es-Routing-Id") private String routingId; /** ???FsPath. */ @HeaderParam("X-Personium-Fs-Path") private String fsPath; /** FsRoutingId obtained from the request header. */ @HeaderParam("X-Personium-Fs-Routing-Id") private String fsRoutingId; /** . */ String serviceSubject; /** ?. */ ISourceManager sourceManager; /** * ????. * @return */ public final String getSourcePath() { return this.sourcePath; } /** * ???. * @param value */ public final void setSourcePath(final String value) { this.sourcePath = value; } /** * Service????. * @return Service?? */ public final String getServiceName() { return this.serviceName; } /** * Service???. * @param value Service?? */ public final void setServiceName(final String value) { this.serviceName = value; } /** * ??. * @return the index */ public final String getIndex() { return index; } /** * ??. * @return the type */ public final String getType() { return type; } /** * ID??. * @return the id */ public final String getId() { return id; } /** * RoutingID??. * @return the routingId */ public final String getRoutingId() { return routingId; } /** * FsPath??. * @return the fsPath */ public final String getFsPath() { return fsPath; } /** * Get fsRoutingId. * @return fsRoutingId */ public String getFsRoutingId() { return fsRoutingId; } /** * GET. * @param cell Cell?? * @param schema URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @GET public final Response evalJsgiForGet(@PathParam("cell") final String cell, @PathParam("schema") final String schema, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, schema, svcName, request, response, is); } /** * POST. * @param cell Cell?? * @param schema URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @POST public final Response evalJsgiForPost(@PathParam("cell") final String cell, @PathParam("schema") final String schema, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, schema, svcName, request, response, is); } /** * PUT. * @param cell Cell?? * @param schema URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @PUT public final Response evalJsgiForPutMethod(@PathParam("cell") final String cell, @PathParam("schema") final String schema, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, schema, svcName, request, response, is); } /** * DELETE. * @param cell Cell?? * @param schema URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @DELETE public final Response evalJsgiForDeleteMethod(@PathParam("cell") final String cell, @PathParam("schema") final String schema, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, schema, svcName, request, response, is); } /** * ??. * @param value */ public final void setServletContext(final ServletContext value) { this.context = value; } /** * ?. * @return */ public final ServletContext getServletContext() { return this.context; } /** * Service. * @param cell Cell?? * @param schema URI * @param svcName ??? * @param req Request * @param res Response * @param is * @return Response */ public final Response run(final String cell, final String schema, final String svcName, final HttpServletRequest req, final HttpServletResponse res, final InputStream is) { StringBuilder msg = new StringBuilder(); msg.append("[" + PersoniumEngineConfig.getVersion() + "] " + ">>> Request Started "); msg.append(" method:"); msg.append(req.getMethod()); msg.append(" method:"); msg.append(req.getRequestURL()); msg.append(" url:"); msg.append(cell); msg.append(" schema:"); msg.append(schema); msg.append(" svcName:"); msg.append(svcName); log.info(msg); // ? ???? Enumeration<String> multiheaders = req.getHeaderNames(); for (String headerName : Collections.list(multiheaders)) { Enumeration<String> headers = req.getHeaders(headerName); for (String header : Collections.list(headers)) { log.debug("RequestHeader['" + headerName + "'] = " + header); } } this.setServiceName(svcName); // ?URL?? String targetCell = cell; if (cell == null) { targetCell = getCell(); } String targetSchema = schema; if (schema == null) { targetSchema = getSchemaURI(); } String targetServiceName = svcName; String baseUrl; try { baseUrl = parseRequestUri(req, res); } catch (MalformedURLException e) { // URL??????? return makeErrorResponse("Server Error", PersoniumEngineException.STATUSCODE_SERVER_ERROR); } Response response = null; PersoniumEngineContext pecx = null; try { try { pecx = new PersoniumEngineContext(); } catch (PersoniumEngineException e) { return errorResponse(e); } // ??? try { this.sourceManager = this.getServiceCollectionManager(); pecx.setSourceManager(this.sourceManager); this.serviceSubject = this.sourceManager.getServiceSubject(); } catch (PersoniumEngineException e) { return errorResponse(e); } // ?? pecx.loadGlobalObject(baseUrl, targetCell, targetSchema, targetSchema, targetServiceName); // ??? String source = ""; try { String sourceName = this.sourceManager.getScriptNameForServicePath(targetServiceName); source = this.sourceManager.getSource(sourceName); } catch (PersoniumEngineException e) { return errorResponse(e); } catch (Exception e) { log.info("User Script not found to targetCell(" + targetCell + ", targetschema(" + targetSchema + "), targetServiceName(" + targetServiceName + ")"); log.info(e.getMessage(), e); return errorResponse(new PersoniumEngineException("404 Not Found (User Script)", PersoniumEngineException.STATUSCODE_NOTFOUND)); } // JSGI try { response = pecx.runJsgi(source, req, res, is, this.serviceSubject); } catch (PersoniumEngineException e) { return errorResponse(e); } catch (Exception e) { log.warn(" unknown Exception(" + e.getMessage() + ")"); return errorResponse(new PersoniumEngineException("404 Not Found (Service Execute Error)", PersoniumEngineException.STATUSCODE_NOTFOUND)); } } finally { IOUtils.closeQuietly(pecx); } return response; } /** * ??. * @param e Exception * @return Response */ final Response errorResponse(final PersoniumEngineException e) { return makeErrorResponse(e.getMessage(), e.getStatusCode()); } /** * ???. * @param msg * @param code * @return Response */ private Response makeErrorResponse(final String msg, final int code) { return Response.status(code).header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML) .header(HttpHeaders.CONTENT_LENGTH, msg.getBytes().length).entity(msg).build(); } /** * Cell???. * @return Cell?? */ public abstract String getCell(); /** * URI?. * @return URI */ public abstract String getSchemaURI(); /** * ??. * @param req Request * @param res Response * @return URL * @throws MalformedURLException */ public final String parseRequestUri(final HttpServletRequest req, final HttpServletResponse res) throws MalformedURLException { String baseUrl = ""; // URI??URI???????? // /personium-engine/engine-test/ds-engine-test/service/hello?a=b&c=d // DC??????URI????????? // ?Personium-Engine???URI??? String requestUri = req.getHeader(KEY_HEADER_REQUEST_URI); if (requestUri == null || requestUri.length() == 0) { requestUri = req.getRequestURI(); String query = req.getQueryString(); if (query != null && query.length() > 0) { requestUri += "?" + query; } } // URI?????????? // /personium-engine/engine-test/personium-engine-test/service/hello int indexQ = requestUri.indexOf("?"); String scriptName = requestUri; if (indexQ > 0) { scriptName = requestUri.substring(0, indexQ); } // ?????JSGI???? req.setAttribute("env.requestUri", requestUri); req.setAttribute("scriptName", scriptName); // ?????URL?? // DC??????URL????????? baseUrl = req.getHeader(KEY_HEADER_BASEURL); // ?????JSGI???? URL baseUrlObj = new URL(baseUrl); int port = baseUrlObj.getPort(); String proto = baseUrlObj.getProtocol(); String host = baseUrlObj.getHost(); String hostHeader = host; if (port < 0) { if ("http".endsWith(proto)) { port = PORT_HTTP; } if ("https".endsWith(proto)) { port = PORT_HTTPS; } } else { hostHeader += ":" + port; } req.setAttribute("HostHeader", hostHeader); req.setAttribute("host", baseUrlObj.getHost()); req.setAttribute("port", port); req.setAttribute("scheme", proto); return baseUrl; } /** * ServiceCollectionManager?. * @return ISourceManager * @throws PersoniumEngineException Exception about Engine */ public abstract ISourceManager getServiceCollectionManager() throws PersoniumEngineException; }