From 3c47280ecb56768bcaa872be0f614b70d486ce6b Mon Sep 17 00:00:00 2001 From: prathabanKavin Date: Fri, 11 Nov 2022 11:27:22 +0530 Subject: [PATCH] Add crud APIs for commercial features --- .../service/api/CommercialFeatureService.java | 356 ++++++++++++++++++ .../impl/CommercialFeatureServiceImpl.java | 184 +++++++++ .../src/main/webapp/WEB-INF/cxf-servlet.xml | 2 + 3 files changed, 542 insertions(+) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/CommercialFeatureService.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/CommercialFeatureServiceImpl.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/CommercialFeatureService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/CommercialFeatureService.java new file mode 100644 index 0000000000..d567f286e2 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/CommercialFeatureService.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.wso2.carbon.device.mgt.jaxrs.service.api; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Info; +import io.swagger.annotations.ResponseHeader; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import org.apache.axis2.transport.http.HTTPConstants; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * Commercial Feature related REST-API implementation. + */ +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "Commercial feature Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "DeviceCommercialFeatureManagement"), + @ExtensionProperty(name = "context", value = "/api/device-mgt/v1.0/commercialfeature"), + }) + } + ), + tags = { + @Tag(name = "device_management") + } +) +@Scopes( + scopes = { + @Scope( + name = "View commercial feature records", + description = "View commercial feature records", + key = "perm:metadata:view", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/metadata/view"} + ), + @Scope( + name = "Create a commercial feature record", + description = "Create a commercial feature record", + key = "perm:metadata:create", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/metadata/create"} + ), + @Scope( + name = "Update a commercial feature record", + description = "Updating a specified commercial feature record", + key = "perm:metadata:update", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/metadata/update"} + ), + @Scope( + name = "Delete a commercial feature record", + description = "Delete a specified commercial feature record", + key = "perm:metadata:remove", + roles = {"Internal/devicemgt-user"}, + permissions = {"/device-mgt/metadata/remove"} + ) + } +) +@Api(value = "Device Commercial Feature Management") +@Path("/commercialfeature") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public interface CommercialFeatureService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get all commercial feature entries", + notes = "Provides a list of commercial feature entries, which are stored as key-value pairs.", + tags = "Device Commercial Feature Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:metadata:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of comercial feature entries.", + response = MetadataList.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while fetching the commercial feature entry list.", + response = ErrorResponse.class) + }) + Response getAllCommercialFeatureEntries( + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.") + @QueryParam("offset") + int offset, + @ApiParam( + name = "limit", + value = "Provide how many metadata entries you require from the starting pagination index/offset.", + defaultValue = "5") + @QueryParam("limit") + int limit); + + @GET + @Path("/{metaKey}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_GET, + value = "Get commercial feature by metaKey", + notes = "Retrieve a commercial feature entry by providing a metaKey value", + tags = "Device Metadata Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:metadata:view") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the requested commercial feature entry.", + response = Metadata.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while fetching the commercial feature entry.", + response = ErrorResponse.class) + }) + Response getCommercialFeatureEntry( + @ApiParam( + name = "metaKey", + value = "Key of the metadata", + required = true) + @PathParam("metaKey") String metaKey); + + @POST + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_PUT, + value = "Create commercial feature entry", + notes = "Create a entry in metadata repository", + tags = "Device Metadata Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:metadata:create") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully created the commercial feature entry.", + response = Metadata.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 409, + message = "Conflict. \n The provided metadataKey is already exist.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while creating the commercial feature entry.", + response = ErrorResponse.class) + }) + Response createCommercialFeatureEntry( + Metadata metadata + ); + + @PUT + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_PUT, + value = "Update commercial feature entry", + notes = "Update commercial feature entry by the provided metaKey of the Metadata object, if the metaKey is not " + + "already exist a new entry will be inserted.", + tags = "Device Metadata Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:metadata:update") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully updated the provided commercial feature entry.", + response = Metadata.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while updating the commercial feature entry.", + response = ErrorResponse.class) + }) + Response updateCommercialFeatureEntry( + Metadata metadata + ); + + @DELETE + @Path("/{metaKey}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = HTTPConstants.HEADER_DELETE, + value = "Delete commercial feature entry", + notes = "Delete commercial feature entry by providing a metaKey value", + tags = "Device Metadata Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:metadata:remove") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully deleted the requested commercial feature entry.", + response = Metadata.class, + responseHeaders = { + @ResponseHeader( + name = "Content-Type", + description = "The content type of the body"), + @ResponseHeader( + name = "ETag", + description = "Entity Tag of the response resource.\n" + + "Used by caches, or in conditional requests."), + @ResponseHeader( + name = "Last-Modified", + description = "Date and time the resource was last modified.\n" + + "Used by caches, or in conditional requests."), + }), + @ApiResponse( + code = 404, + message = "Not Found. \n The requested commercial feature entry to be deleted is not found.", + response = ErrorResponse.class), + @ApiResponse( + code = 500, + message = "Internal Server Error. " + + "\n Server error occurred while deleting the commercial feature entry.", + response = ErrorResponse.class) + }) + Response deleteCommercialFeatureEntry( + @ApiParam( + name = "metaKey", + value = "Key of the metadata", + required = true) + @PathParam("metaKey") String metaKey + ); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/CommercialFeatureServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/CommercialFeatureServiceImpl.java new file mode 100644 index 0000000000..d06a2194b7 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/CommercialFeatureServiceImpl.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved. + * + * Entgra (Pvt) Ltd. 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.wso2.carbon.device.mgt.jaxrs.service.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.PaginationRequest; +import org.wso2.carbon.device.mgt.common.PaginationResult; +import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyAlreadyExistsException; +import org.wso2.carbon.device.mgt.common.exceptions.MetadataKeyNotFoundException; +import org.wso2.carbon.device.mgt.common.metadata.mgt.Metadata; +import org.wso2.carbon.device.mgt.common.exceptions.MetadataManagementException; +import org.wso2.carbon.device.mgt.common.metadata.mgt.MetadataManagementService; +import org.wso2.carbon.device.mgt.jaxrs.beans.MetadataList; +import org.wso2.carbon.device.mgt.jaxrs.service.api.CommercialFeatureService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.user.api.UserStoreException; + +import java.util.List; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * This class implements the CommercialFeatureService. + */ +@Path("/commercialfeature") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class CommercialFeatureServiceImpl implements CommercialFeatureService { + + private static final Log log = LogFactory.getLog(CommercialFeatureServiceImpl.class); + + private boolean checkTenantPermission(){ + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true); + try { + if(tenantDomain == "carbon.super" && DeviceMgtAPIUtils.isAdmin()){ + return true; + } else { + return false; + } + } catch (UserStoreException e) { + throw new RuntimeException(e); + } + } + + @GET + @Override + public Response getAllCommercialFeatureEntries( + @QueryParam("offset") int offset, + @DefaultValue("5") + @QueryParam("limit") int limit) { + if(checkTenantPermission()){ + RequestValidationUtil.validatePaginationParameters(offset, limit); + PaginationRequest request = new PaginationRequest(offset, limit); + MetadataList metadataList = new MetadataList(); + try { + MetadataManagementService metadataManagementService = DeviceMgtAPIUtils.getMetadataManagementService(); + PaginationResult result = metadataManagementService.retrieveAllMetadata(request); + metadataList.setCount(result.getRecordsTotal()); + metadataList.setMetadataList((List) result.getData()); + return Response.status(Response.Status.OK).entity(metadataList).build(); + } catch (MetadataManagementException e) { + String msg = "Error occurred while retrieving commercial feature list for given parameters [offset:" + + offset + ", limit:" + limit + " ]"; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + return Response.status(Response.Status.FORBIDDEN).entity("Invalid request. You do not have permission").build(); + } + } + + @GET + @Override + @Path("/{metaKey}") + public Response getCommercialFeatureEntry( + @PathParam("metaKey") String metaKey) { + if(checkTenantPermission()){ + Metadata metadata; + try { + metadata = DeviceMgtAPIUtils.getMetadataManagementService().retrieveMetadata(metaKey); + return Response.status(Response.Status.OK).entity(metadata).build(); + } catch (MetadataManagementException e) { + String msg = "Error occurred while getting the commercial feature entry for metaKey:" + metaKey; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + return Response.status(Response.Status.FORBIDDEN).entity("Invalid request. You do not have permission").build(); + } + } + + @POST + @Override + public Response createCommercialFeatureEntry(Metadata metadata) { + if(checkTenantPermission()){ + RequestValidationUtil.validateMetadata(metadata); + try { + Metadata createdMetadata = DeviceMgtAPIUtils.getMetadataManagementService().createMetadata(metadata); + return Response.status(Response.Status.CREATED).entity(createdMetadata).build(); + } catch (MetadataKeyAlreadyExistsException e) { + String msg = "Commercial feature entry metaKey:" + metadata.getMetaKey() + " is already exist."; + log.error(msg, e); + return Response.status(Response.Status.CONFLICT).entity(msg).build(); + } catch (MetadataManagementException e) { + String msg = "Error occurred while creating the commercial feature entry for metaKey:" + metadata.getMetaKey(); + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + return Response.status(Response.Status.FORBIDDEN).entity("Invalid request. You do not have permission").build(); + } + } + + @PUT + @Override + public Response updateCommercialFeatureEntry(Metadata metadata) { + if(checkTenantPermission()){ + RequestValidationUtil.validateMetadata(metadata); + try { + Metadata updatedMetadata = DeviceMgtAPIUtils.getMetadataManagementService().updateMetadata(metadata); + return Response.status(Response.Status.OK).entity(updatedMetadata).build(); + } catch (MetadataManagementException e) { + String msg = "Error occurred while updating the commercial feature entry for metaKey:" + metadata.getMetaKey(); + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + return Response.status(Response.Status.FORBIDDEN).entity("Invalid request. You do not have permission").build(); + } + } + + @DELETE + @Override + @Path("/{metaKey}") + public Response deleteCommercialFeatureEntry( + @PathParam("metaKey") String metaKey) { + if(checkTenantPermission()){ + try { + DeviceMgtAPIUtils.getMetadataManagementService().deleteMetadata(metaKey); + return Response.status(Response.Status.OK).entity("Commercial feature entry is deleted successfully.").build(); + } catch (MetadataKeyNotFoundException e) { + String msg = "Commercial feature entry metaKey:" + metaKey + " is not found."; + log.error(msg, e); + return Response.status(Response.Status.NOT_FOUND).entity(msg).build(); + } catch (MetadataManagementException e) { + String msg = "Error occurred while deleting the commercial feature entry for metaKey:" + metaKey; + log.error(msg, e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + } + } else { + return Response.status(Response.Status.FORBIDDEN).entity("Invalid request. You do not have permission").build(); + } + } +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml index efce569c42..f92163109c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -49,6 +49,7 @@ + @@ -99,6 +100,7 @@ +