Java tutorial
/** * personium.io * Copyright 2014 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 com.fujitsu.dc.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 com.fujitsu.dc.engine.DcEngineContext; import com.fujitsu.dc.engine.DcEngineException; import com.fujitsu.dc.engine.source.ISourceManager; import com.fujitsu.dc.engine.utils.DcEngineConfig; /** * 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-Dc-Es-Index") private String index; /** ???. */ @HeaderParam("X-Dc-Es-Type") private String type; /** ???ID. */ @HeaderParam("X-Dc-Es-Id") private String id; /** ???RoutingID. */ @HeaderParam("X-Dc-Es-Routing-Id") private String routingId; /** . */ 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; } /** * GET. * @param cell Cell?? * @param scheme URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @GET public final Response evalJsgiForGet(@PathParam("cell") final String cell, @PathParam("scheme") final String scheme, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, scheme, svcName, request, response, is); } /** * POST. * @param cell Cell?? * @param scheme URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @POST public final Response evalJsgiForPost(@PathParam("cell") final String cell, @PathParam("scheme") final String scheme, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, scheme, svcName, request, response, is); } /** * PUT. * @param cell Cell?? * @param scheme URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @PUT public final Response evalJsgiForPutMethod(@PathParam("cell") final String cell, @PathParam("scheme") final String scheme, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, scheme, svcName, request, response, is); } /** * DELETE. * @param cell Cell?? * @param scheme URI * @param svcName ?? * @param request * @param response ? * @param is * @return Response */ @DELETE public final Response evalJsgiForDeleteMethod(@PathParam("cell") final String cell, @PathParam("scheme") final String scheme, @PathParam("id") final String svcName, @Context final HttpServletRequest request, @Context final HttpServletResponse response, final InputStream is) { return run(cell, scheme, 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 scheme URI * @param svcName ??? * @param req Request * @param res Response * @param is * @return Response */ public final Response run(final String cell, final String scheme, final String svcName, final HttpServletRequest req, final HttpServletResponse res, final InputStream is) { StringBuilder msg = new StringBuilder(); msg.append("[" + DcEngineConfig.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(" scheme:"); msg.append(scheme); 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 targetScheme = scheme; if (scheme == null) { targetScheme = getScheme(); } String targetServiceName = svcName; String baseUrl; try { baseUrl = parseRequestUri(req, res); } catch (MalformedURLException e) { // URL??????? return makeErrorResponse("Server Error", DcEngineException.STATUSCODE_SERVER_ERROR); } Response response = null; DcEngineContext dcContext = null; try { try { dcContext = new DcEngineContext(); } catch (DcEngineException e) { return errorResponse(e); } // ??? try { this.sourceManager = this.getServiceCollectionManager(); dcContext.setSourceManager(this.sourceManager); this.serviceSubject = this.sourceManager.getServiceSubject(); } catch (DcEngineException e) { return errorResponse(e); } // ?? dcContext.loadGlobalObject(baseUrl, targetCell, targetScheme, targetScheme, targetServiceName); // ??? String source = ""; try { String sourceName = this.sourceManager.getScriptNameForServicePath(targetServiceName); source = this.sourceManager.getSource(sourceName); } catch (DcEngineException e) { return errorResponse(e); } catch (Exception e) { log.info("User Script not found to targetCell(" + targetCell + ", targetScheme(" + targetScheme + "), targetServiceName(" + targetServiceName + ")"); log.info(e.getMessage(), e); return errorResponse(new DcEngineException("404 Not Found (User Script)", DcEngineException.STATUSCODE_NOTFOUND)); } // JSGI try { response = dcContext.runJsgi(source, req, res, is, this.serviceSubject); } catch (DcEngineException e) { return errorResponse(e); } catch (Exception e) { log.warn(" unknown Exception(" + e.getMessage() + ")"); return errorResponse(new DcEngineException("404 Not Found (Service Excute Error)", DcEngineException.STATUSCODE_NOTFOUND)); } } finally { IOUtils.closeQuietly(dcContext); } return response; } /** * ??. * @param e Exception * @return Response */ final Response errorResponse(final DcEngineException 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 getScheme(); /** * ??. * @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???????? // /dc-engine/engine-test/ds-engine-test/service/hello?a=b&c=d // DC??????URI????????? // ?DC-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?????????? // /dc-engine/engine-test/ds-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????????? // ?????? String defaultBaseUrl = DcEngineConfig.getDefaultBaseUrl(); baseUrl = req.getHeader(KEY_HEADER_BASEURL); if (baseUrl == null || baseUrl.length() == 0) { baseUrl = defaultBaseUrl; } // ?????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 DcEngineException DcEngineException */ public abstract ISourceManager getServiceCollectionManager() throws DcEngineException; }