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.core.rs.box; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.HttpMethod; import javax.ws.rs.OPTIONS; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.StreamingOutput; import javax.ws.rs.core.UriInfo; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.wink.webdav.WebDAVMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fujitsu.dc.common.utils.DcCoreUtils; import com.fujitsu.dc.core.DcCoreConfig; import com.fujitsu.dc.core.DcCoreException; import com.fujitsu.dc.core.annotations.ACL; import com.fujitsu.dc.core.auth.BoxPrivilege; import com.fujitsu.dc.core.model.DavCmp; import com.fujitsu.dc.core.model.DavRsCmp; import com.fujitsu.dc.core.model.impl.es.DavCmpEsImpl; /** * DcEngineSvcCollectionResource?JAX-RS. */ public final class DcEngineSvcCollectionResource { /** * . */ private static Logger log = LoggerFactory.getLogger(DcEngineSvcCollectionResource.class); DavCmp davCmp = null; DavCollectionResource dcr = null; DavRsCmp davRsCmp; /** * . * @param parent DavRsCmp * @param davCmp DavCmp */ public DcEngineSvcCollectionResource(final DavRsCmp parent, final DavCmp davCmp) { this.davCmp = davCmp; this.dcr = new DavCollectionResource(parent, davCmp); this.davRsCmp = new DavRsCmp(parent, davCmp); } /** * PROPFIND??. * @param requestBodyXml * @param depth Depth * @param contentLength Content-Length * @param transferEncoding Transfer-Encoding * @return JAX-RS Response */ @WebDAVMethod.PROPFIND public Response propfind(final Reader requestBodyXml, @HeaderParam(DcCoreUtils.HttpHeaders.DEPTH) final String depth, @HeaderParam(HttpHeaders.CONTENT_LENGTH) final Long contentLength, @HeaderParam("Transfer-Encoding") final String transferEncoding) { return this.davRsCmp.doPropfind(requestBodyXml, depth, contentLength, transferEncoding, BoxPrivilege.READ_PROPERTIES, BoxPrivilege.READ_ACL); } /** * DELETE????????. * @return JAX-RS */ @DELETE public Response delete() { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE); if (!this.davRsCmp.getDavCmp().isEmpty()) { throw DcCoreException.Dav.HAS_CHILDREN; } return this.davCmp.delete(null).build(); } /** * PROPPATCH??. * @param requestBodyXml * @return JAX-RS Response */ @WebDAVMethod.PROPPATCH public Response proppatch(final Reader requestBodyXml) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_PROPERTIES); return this.davRsCmp.doProppatch(requestBodyXml); } /** * ACL??. ACL??. * @param reader XML * @return JAX-RS Response */ @ACL public Response acl(final Reader reader) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.WRITE_ACL); return this.davCmp.acl(reader).build(); } /** * OPTIONS. * @return JAX-RS Response */ @OPTIONS public Response options() { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.READ); return DcCoreUtils.responseBuilderForOptions(HttpMethod.DELETE, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.PROPFIND, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.PROPPATCH, com.fujitsu.dc.common.utils.DcCoreUtils.HttpMethod.ACL).build(); } /** * ?Jax-RS?. * @return DavFileResource */ @Path("__src") public DcEngineSourceCollection src() { DavCmp nextCmp = this.davCmp.getChild(DavCmp.SERVICE_SRC_COLLECTION); return new DcEngineSourceCollection(this.davRsCmp, nextCmp); } /** * relay_GET. * @param path ?? * @param uriInfo URI * @param headers * @return JAX-RS Response */ @Path("{path}") @GET public Response relayget(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.GET, uriInfo, path, headers, null); } /** * relay_POST. * @param path ?? * @param uriInfo URI * @param headers * @param is * @return JAX-RS Response */ @Path("{path}") @POST public Response relaypost(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers, final InputStream is) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.POST, uriInfo, path, headers, is); } /** * relay_PUT. * @param path ?? * @param uriInfo URI * @param headers * @param is * @return JAX-RS Response */ @Path("{path}") @PUT public Response relayput(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers, final InputStream is) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.PUT, uriInfo, path, headers, is); } /** * relay_DELETE. * @param path ?? * @param uriInfo URI * @param headers * @return JAX-RS Response */ @Path("{path}") @DELETE public Response relaydelete(@PathParam("path") String path, @Context final UriInfo uriInfo, @Context HttpHeaders headers) { // this.davRsCmp.checkAccessContext(this.davRsCmp.getAccessContext(), BoxPrivilege.EXEC); return relaycommon(HttpMethod.DELETE, uriInfo, path, headers, null); } /** * relay??. * @param method * @param uriInfo URI * @param path ?? * @param headers * @param is * @return JAX-RS Response */ public Response relaycommon(String method, UriInfo uriInfo, String path, HttpHeaders headers, InputStream is) { String cellName = this.davRsCmp.getCell().getName(); String boxName = this.davRsCmp.getBox().getName(); String requestUrl = String.format("http://%s:%s/%s/%s/%s/service/%s", DcCoreConfig.getEngineHost(), DcCoreConfig.getEnginePort(), DcCoreConfig.getEnginePath(), cellName, boxName, path); // baseUrl? String baseUrl = uriInfo.getBaseUri().toString(); // ??? HttpClient client = new DefaultHttpClient(); HttpUriRequest req = null; if (method.equals(HttpMethod.POST)) { HttpPost post = new HttpPost(requestUrl); InputStreamEntity ise = new InputStreamEntity(is, -1); ise.setChunked(true); post.setEntity(ise); req = post; } else if (method.equals(HttpMethod.PUT)) { HttpPut put = new HttpPut(requestUrl); InputStreamEntity ise = new InputStreamEntity(is, -1); ise.setChunked(true); put.setEntity(ise); req = put; } else if (method.equals(HttpMethod.DELETE)) { HttpDelete delete = new HttpDelete(requestUrl); req = delete; } else { HttpGet get = new HttpGet(requestUrl); req = get; } req.addHeader("X-Baseurl", baseUrl); req.addHeader("X-Request-Uri", uriInfo.getRequestUri().toString()); // ?INDEXIDTYPE? if (davCmp instanceof DavCmpEsImpl) { DavCmpEsImpl test = (DavCmpEsImpl) davCmp; req.addHeader("X-Dc-Es-Index", test.getEsColType().getIndex().getName()); req.addHeader("X-Dc-Es-Id", test.getNodeId()); req.addHeader("X-Dc-Es-Type", test.getEsColType().getType()); req.addHeader("X-Dc-Es-Routing-Id", this.davRsCmp.getCell().getId()); req.addHeader("X-Dc-Box-Schema", this.davRsCmp.getBox().getSchema()); } // ??? MultivaluedMap<String, String> multivalueHeaders = headers.getRequestHeaders(); for (Iterator<Entry<String, List<String>>> it = multivalueHeaders.entrySet().iterator(); it.hasNext();) { Entry<String, List<String>> entry = it.next(); String key = (String) entry.getKey(); if (key.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH)) { continue; } List<String> valueList = (List<String>) entry.getValue(); for (Iterator<String> i = valueList.iterator(); i.hasNext();) { String value = (String) i.next(); req.setHeader(key, value); } } if (log.isDebugEnabled()) { log.debug("?EngineRelay " + req.getMethod() + " " + req.getURI()); Header[] reqHeaders = req.getAllHeaders(); for (int i = 0; i < reqHeaders.length; i++) { log.debug("RelayHeader[" + reqHeaders[i].getName() + "] : " + reqHeaders[i].getValue()); } } // Engine?? HttpResponse objResponse = null; try { objResponse = client.execute(req); } catch (ClientProtocolException e) { throw DcCoreException.ServiceCollection.SC_INVALID_HTTP_RESPONSE_ERROR; } catch (Exception ioe) { throw DcCoreException.ServiceCollection.SC_ENGINE_CONNECTION_ERROR.reason(ioe); } // ResponseBuilder res = Response.status(objResponse.getStatusLine().getStatusCode()); Header[] headersResEngine = objResponse.getAllHeaders(); // ? for (int i = 0; i < headersResEngine.length; i++) { // Engine????Transfer-Encoding???? // ?MW????????Content-Length???Transfer-Encoding???? // 2?????????????????????? if ("Transfer-Encoding".equalsIgnoreCase(headersResEngine[i].getName())) { continue; } // Engine????Date???? // Web??MW?Jetty???2????????? if (HttpHeaders.DATE.equalsIgnoreCase(headersResEngine[i].getName())) { continue; } res.header(headersResEngine[i].getName(), headersResEngine[i].getValue()); } InputStream isResBody = null; // ? HttpEntity entity = objResponse.getEntity(); if (entity != null) { try { isResBody = entity.getContent(); } catch (IllegalStateException e) { throw DcCoreException.ServiceCollection.SC_UNKNOWN_ERROR.reason(e); } catch (IOException e) { throw DcCoreException.ServiceCollection.SC_ENGINE_CONNECTION_ERROR.reason(e); } final InputStream isInvariable = isResBody; // ?? StreamingOutput strOutput = new StreamingOutput() { @Override public void write(final OutputStream os) throws IOException { int chr; try { while ((chr = isInvariable.read()) != -1) { os.write(chr); } } finally { isInvariable.close(); } } }; res.entity(strOutput); } // ?? return res.build(); } }