This is an automated email from the ASF dual-hosted git repository.
grv pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git The following commit(s) were added to refs/heads/trunk by this push: new 6ac1f28 Implemented: Add support to read and register resources defined in XML DSL(OFBIZ-11995) 6ac1f28 is described below commit 6ac1f284915ff1de659bda944e26b90bdab2f75c Author: Girish Vasmatkar <[hidden email]> AuthorDate: Wed Sep 16 18:21:27 2020 +0530 Implemented: Add support to read and register resources defined in XML DSL(OFBIZ-11995) --- .../apache/ofbiz/ws/rs/core/OFBizApiConfig.java | 40 ++++ .../ofbiz/ws/rs/process/RestRequestHandler.java | 256 +++++++++++++++++++++ .../ofbiz/ws/rs/process/ServiceRequestHandler.java | 102 ++++++++ 3 files changed, 398 insertions(+) diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java index 911c880..5a168fe 100644 --- a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java +++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/core/OFBizApiConfig.java @@ -21,19 +21,29 @@ package org.apache.ofbiz.ws.rs.core; import java.io.File; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import javax.ws.rs.core.MediaType; + import org.apache.ofbiz.base.component.ComponentConfig; import org.apache.ofbiz.base.component.ComponentException; import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.ws.rs.model.ModelApi; import org.apache.ofbiz.ws.rs.model.ModelApiReader; +import org.apache.ofbiz.ws.rs.model.ModelOperation; +import org.apache.ofbiz.ws.rs.model.ModelResource; +import org.apache.ofbiz.ws.rs.process.ServiceRequestHandler; +import org.apache.ofbiz.ws.rs.security.Secured; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.logging.LoggingFeature; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; +import org.glassfish.jersey.server.model.ResourceMethod; public class OFBizApiConfig extends ResourceConfig { private static final String MODULE = OFBizApiConfig.class.getName(); @@ -58,6 +68,7 @@ public class OFBizApiConfig extends ResourceConfig { private void registerDSLResources() { loadApiDefinitions(); + traverseAndRegisterApiDefinitions(); } private void loadApiDefinitions() { @@ -78,4 +89,33 @@ public class OFBizApiConfig extends ResourceConfig { } }); } + + private void traverseAndRegisterApiDefinitions() { + if (UtilValidate.isEmpty(MICRO_APIS)) { + Debug.logInfo("No API defintion to process", MODULE); + return; + } + MICRO_APIS.forEach((k, v) -> { + Debug.logInfo("Registring Resource Definitions from API - " + k, MODULE); + List<ModelResource> resources = v.getResources(); + resources.forEach(modelResource -> { + Resource.Builder resourceBuilder = Resource.builder(modelResource.getPath()).name(modelResource.getName()); + for (ModelOperation op : modelResource.getOperations()) { + if (UtilValidate.isEmpty(op.getPath())) { // Add the method to the parent resource + ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod(op.getVerb().toUpperCase()); + methodBuilder.produces(MediaType.APPLICATION_JSON).nameBindings(Secured.class); + String serviceName = op.getService(); + methodBuilder.handledBy(new ServiceRequestHandler(serviceName)); + } else { + Resource.Builder childResourceBuilder = resourceBuilder.addChildResource(op.getPath()); + ResourceMethod.Builder childResourceMethodBuilder = childResourceBuilder.addMethod(op.getVerb().toUpperCase()); + childResourceMethodBuilder.produces(MediaType.APPLICATION_JSON).nameBindings(Secured.class); + String serviceName = op.getService(); + childResourceMethodBuilder.handledBy(new ServiceRequestHandler(serviceName)); + } + } + registerResources(resourceBuilder.build()); + }); + }); + } } diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/RestRequestHandler.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/RestRequestHandler.java new file mode 100644 index 0000000..0309cdf --- /dev/null +++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/RestRequestHandler.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.ofbiz.ws.rs.process; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.HttpMethod; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.ofbiz.base.util.UtilValidate; +import org.glassfish.jersey.message.internal.MediaTypes; +import org.glassfish.jersey.process.Inflector; +import org.glassfish.jersey.server.ContainerRequest; +import org.glassfish.jersey.server.ExtendedUriInfo; + +public abstract class RestRequestHandler implements Inflector<ContainerRequestContext, Response> { + + @Inject + private HttpHeaders httpHeaders; + + @Inject + private UriInfo uriInfo; + + @Inject + private ExtendedUriInfo extendedUriInfo; + + @Inject + private ResourceInfo resourceInfo; + + @Inject + private ServletContext servletContext; + + @Inject + private HttpServletRequest httpRequest; + + /** + * @return the httpHeaders + */ + protected HttpHeaders getHttpHeaders() { + return httpHeaders; + } + + /** + * @return the uriInfo + */ + protected UriInfo getUriInfo() { + return uriInfo; + } + + /** + * @return the extendedUriInfo + */ + protected ExtendedUriInfo getExtendedUriInfo() { + return extendedUriInfo; + } + + /** + * @return the resourceInfo + */ + protected ResourceInfo getResourceInfo() { + return resourceInfo; + } + + /** + * @return the servletContext + */ + protected ServletContext getServletContext() { + return servletContext; + } + + /** + * @return the httpRequest + */ + protected HttpServletRequest getHttpRequest() { + return httpRequest; + } + + /** + * @param ctx + * @return + */ + @Override + public Response apply(ContainerRequestContext ctx) { + // TODO Auto-generated method stub + String method = ctx.getMethod(); + switch (method) { + case HttpMethod.POST: + return doPost(ctx); + case HttpMethod.GET: + return doGet(ctx); + case HttpMethod.DELETE: + return doDelete(ctx); + case HttpMethod.PUT: + return doPut(ctx); + case HttpMethod.PATCH: + return doPatch(ctx); + } + return null; + } + + /** + * @param data + * @param arguments + * @return + */ + protected abstract Response execute(ContainerRequestContext data, Map<String, Object> arguments); + + /** + * @param requestContext + * @return + */ + @SuppressWarnings("unchecked") + protected Map<String, Object> extractRequestBody(ContainerRequestContext requestContext) { + if (requestContext instanceof ContainerRequest) { + ContainerRequest request = (ContainerRequest) requestContext; + if (requestContext.hasEntity()) { + request.bufferEntity(); + if (isJson(requestContext)) { + Map<String, Object> entity = request.readEntity(Map.class); + if (entity == null) { + return Collections.emptyMap(); + } + return entity; + } + } + } + return Collections.emptyMap(); + } + + /** + * @param requestContext + * @return + */ + protected Map<String, Object> extractPathParameters(ContainerRequestContext requestContext) { + return extract(requestContext.getUriInfo().getPathParameters()); + } + + /** + * @param requestContext + * @return + */ + protected Map<String, Object> extractQueryParameters(ContainerRequestContext requestContext) { + return extract(requestContext.getUriInfo().getQueryParameters()); + } + + /** + * @param multivaluedMap + * @return + */ + protected Map<String, Object> extract(MultivaluedMap<String, String> multivaluedMap) { + Map<String, Object> result = new HashMap<>(); + multivaluedMap.forEach((name, values) -> { + if (UtilValidate.isNotEmpty(values)) { + result.put(name, (values.size() != 1) ? values : values.get(0)); + } + }); + return result; + } + + /** + * @param requestContext + * @return + */ + private boolean isJson(ContainerRequestContext requestContext) { + final MediaType mediaType = requestContext.getMediaType(); + if (UtilValidate.isNotEmpty(mediaType) && MediaTypes.typeEqual(mediaType, MediaType.APPLICATION_JSON_TYPE)) { + return true; + } + return false; + } + + /** + * @param requestContext + * @return + */ + private Response doGet(ContainerRequestContext requestContext) { + Map<String, Object> arguments = new HashMap<>(); + arguments.putAll(extractPathParameters(requestContext)); + arguments.putAll(extractQueryParameters(requestContext)); + return execute(requestContext, arguments); + } + + /** + * @param requestContext + * @return + */ + private Response doPost(ContainerRequestContext requestContext) { + Map<String, Object> arguments = new HashMap<>(); + arguments.putAll(extractRequestBody(requestContext)); + arguments.putAll(extractPathParameters(requestContext)); + arguments.putAll(extractQueryParameters(requestContext)); + return execute(requestContext, arguments); + } + + /** + * @param requestContext + * @return + */ + private Response doPut(ContainerRequestContext requestContext) { + Map<String, Object> arguments = new HashMap<>(); + arguments.putAll(extractRequestBody(requestContext)); + arguments.putAll(extractPathParameters(requestContext)); + arguments.putAll(extractQueryParameters(requestContext)); + return execute(requestContext, arguments); + } + + /** + * @param requestContext + * @return + */ + private Response doPatch(ContainerRequestContext requestContext) { + Map<String, Object> arguments = new HashMap<>(); + arguments.putAll(extractRequestBody(requestContext)); + arguments.putAll(extractPathParameters(requestContext)); + arguments.putAll(extractQueryParameters(requestContext)); + return execute(requestContext, arguments); + } + + /** + * @param requestContext + * @return + */ + private Response doDelete(ContainerRequestContext requestContext) { + Map<String, Object> arguments = new HashMap<>(); + arguments.putAll(extractPathParameters(requestContext)); + arguments.putAll(extractQueryParameters(requestContext)); + return execute(requestContext, arguments); + } +} diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java new file mode 100644 index 0000000..51ce63b --- /dev/null +++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/process/ServiceRequestHandler.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.ofbiz.ws.rs.process; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Response; + +import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.entity.GenericValue; +import org.apache.ofbiz.service.DispatchContext; +import org.apache.ofbiz.service.GenericServiceException; +import org.apache.ofbiz.service.LocalDispatcher; +import org.apache.ofbiz.service.ModelParam; +import org.apache.ofbiz.service.ModelService; +import org.apache.ofbiz.service.ServiceUtil; +import org.apache.ofbiz.ws.rs.util.RestApiUtil; + +public final class ServiceRequestHandler extends RestRequestHandler { + + private String service; + + public ServiceRequestHandler(String service) { + this.service = service; + } + + /** + * @param data + * @return + * @throws GenericServiceException + */ + @Override + protected Response execute(ContainerRequestContext data, Map<String, Object> arguments) { + LocalDispatcher dispatcher = (LocalDispatcher) getServletContext().getAttribute("dispatcher"); + Map<String, Object> serviceContext = null; + try { + serviceContext = dispatcher.getDispatchContext().makeValidContext(service, ModelService.IN_PARAM, + arguments); + } catch (GenericServiceException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + ModelService svc = getModelService(dispatcher.getDispatchContext()); + GenericValue userLogin = (GenericValue) getHttpRequest().getAttribute("userLogin"); + serviceContext.put("userLogin", userLogin); + Map<String, Object> result = null; + try { + result = dispatcher.runSync(service, serviceContext); + } catch (GenericServiceException e) { + throw new InternalServerErrorException(e.getMessage()); + } + Map<String, Object> responseData = new LinkedHashMap<>(); + if (ServiceUtil.isSuccess(result)) { + Set<String> outParams = svc.getOutParamNames(); + for (String outParamName : outParams) { + ModelParam outParam = svc.getParam(outParamName); + if (!outParam.isInternal()) { + Object value = result.get(outParamName); + if (UtilValidate.isNotEmpty(value)) { + responseData.put(outParamName, value); + } + } + } + return RestApiUtil.success((String) result.get(ModelService.SUCCESS_MESSAGE), responseData); + } else { + return RestApiUtil.error(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), + Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase(), + (String) result.get(ModelService.ERROR_MESSAGE)); + } + } + + private ModelService getModelService(DispatchContext dispatchContext) { + ModelService svc = null; + try { + svc = dispatchContext.getModelService(service); + } catch (GenericServiceException gse) { + throw new NotFoundException(gse.getMessage()); + } + return svc; + } +} |
Free forum by Nabble | Edit this page |