From fd7a137b07970c0a751528dd9975c27109df5977 Mon Sep 17 00:00:00 2001 From: prabathabey Date: Mon, 30 May 2016 13:39:52 +0530 Subject: [PATCH] Improving jax-rs APIS of CDM-F --- .../device/mgt/jaxrs/beans/ActivityList.java | 108 ++++++++++++++++++ .../api/ActivityInfoProviderService.java | 25 ++-- .../ApplicationManagementAdminService.java | 2 +- .../admin/DeviceManagementAdminService.java | 2 +- .../admin/GroupManagementAdminService.java | 2 +- .../api/admin/UserManagementAdminService.java | 2 +- .../impl/ActivityProviderServiceImpl.java | 26 +++-- ...ApplicationManagementAdminServiceImpl.java | 2 +- .../DeviceManagementAdminServiceImpl.java | 2 +- .../GroupManagementAdminServiceImpl.java | 2 +- .../admin/UserManagementAdminServiceImpl.java | 2 +- .../impl/util/RequestValidationUtil.java | 39 +++++++ .../util/UnexpectedServerErrorException.java | 34 ++++++ .../mgt/common/operation/mgt/Activity.java | 10 ++ .../common/operation/mgt/ActivityStatus.java | 9 ++ .../operation/mgt/OperationManagerImpl.java | 4 +- .../mgt/dao/impl/GenericOperationDAOImpl.java | 75 ++++++------ 17 files changed, 283 insertions(+), 63 deletions(-) create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java create mode 100644 components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java new file mode 100644 index 0000000000..68240514ee --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/beans/ActivityList.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.beans; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; + +import java.util.ArrayList; +import java.util.List; + +@ApiModel(value = "List of activities", description = "This contains a set of activities that matches a given " + + "criteria as a collection") +public class ActivityList { + + private int count; + private String next; + private String previous; + + private List activities = new ArrayList<>(); + + /** + * Number of Devices returned. + */ + @ApiModelProperty(value = "Number of activities returned.") + @JsonProperty("count") + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + + /** + * Link to the next subset of resources qualified. \nEmpty if no more resources are to be returned. + */ + @ApiModelProperty(value = "Link to the next subset of resources qualified. \n " + + "Empty if no more resources are to be returned.") + @JsonProperty("next") + public String getNext() { + return next; + } + + public void setNext(String next) { + this.next = next; + } + + /** + * Link to the previous subset of resources qualified. \nEmpty if current subset is the first subset returned. + */ + @ApiModelProperty(value = "Link to the previous subset of resources qualified. \n" + + "Empty if current subset is the first subset returned.") + @JsonProperty("previous") + public String getPrevious() { + return previous; + } + + public void setPrevious(String previous) { + this.previous = previous; + } + + /** + **/ + @ApiModelProperty(value = "List of devices returned") + @JsonProperty("activities") + public List getList() { + return activities; + } + + public void setList(List activities) { + this.activities = activities; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" count: ").append(count).append(",\n"); + sb.append(" next: ").append(next).append(",\n"); + sb.append(" previous: ").append(previous).append(",\n"); + sb.append(" devices: [").append(activities).append("\n"); + sb.append("]}\n"); + return sb.toString(); + } + + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java index 027dfbed52..4aba0d8013 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/ActivityInfoProviderService.java @@ -22,6 +22,8 @@ import io.swagger.annotations.*; import org.wso2.carbon.apimgt.annotations.api.API; import org.wso2.carbon.apimgt.annotations.api.Permission; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; +import org.wso2.carbon.device.mgt.jaxrs.beans.ActivityList; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @@ -44,7 +46,6 @@ public interface ActivityInfoProviderService { @ApiOperation( produces = MediaType.APPLICATION_JSON, httpMethod = "GET", - response = Activity.class, value = "Retrieve details of a particular activity.", notes = "This will return information of a particular activity i.e. meta information of an operation, " + "etc; including the responses from the devices.", @@ -71,12 +72,20 @@ public interface ActivityInfoProviderService { code = 304, message = "Not Modified. \n Empty body because the client has already the latest version of " + "the requested resource."), + @ApiResponse( + code = 400, + message = "Bad Request. \n Invalid request or validation error.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found. \n No activity is found under the provided id."), @ApiResponse( code = 406, message = "Not Acceptable.\n The requested media type is not supported"), @ApiResponse( code = 500, - message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.") + message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.", + response = ErrorResponse.class) }) @Permission(scope = "activity-view", permissions = {"/permission/admin/device-mgt/admin/activities/view"}) Response getActivity( @@ -96,8 +105,6 @@ public interface ActivityInfoProviderService { @ApiOperation( produces = MediaType.APPLICATION_JSON, httpMethod = "GET", - response = Activity.class, - responseContainer = "List", value = "Retrieve details of a particular activity.", notes = "This will return information of a particular activities i.e. meta information of operations, " + "etc; including the responses from the devices which happened after given time.", @@ -106,8 +113,7 @@ public interface ActivityInfoProviderService { @ApiResponse( code = 200, message = "OK. \n Activity details are successfully fetched", - response = Activity.class, - responseContainer = "List", + response = ActivityList.class, responseHeaders = { @ResponseHeader( name = "Content-Type", @@ -130,7 +136,8 @@ public interface ActivityInfoProviderService { message = "Not Acceptable.\n The requested media type is not supported"), @ApiResponse( code = 500, - message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.") + message = "Internal Server ErrorResponse. \n Server error occurred while fetching activity data.", + response = ErrorResponse.class) }) @Permission(scope = "activity-view", permissions = {"/permission/admin/device-mgt/admin/activities/view"}) Response getActivities( @@ -138,8 +145,8 @@ public interface ActivityInfoProviderService { name = "timestamp", value = "Validates if the requested variant has not been modified since the time specified, this " + "should be provided in unix format in seconds.", - required = false) - @QueryParam("timestamp") String timestamp, + required = true) + @QueryParam("timestamp") long timestamp, @ApiParam( name = "If-Modified-Since", value = "Validates if the requested variant has not been modified since the time specified", diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java index 27156015be..df5c122043 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/ApplicationManagementAdminService.java @@ -31,7 +31,7 @@ import javax.ws.rs.core.Response; @API(name = "Application", version = "1.0.0", context = "/devicemgt_admin/applications", tags = {"devicemgt_admin"}) -@Path("/applications") +@Path("/admin/applications") @Api(value = "Application Management Administrative Service", description = "This an API intended to be used by " + "'internal' components to log in as an admin user and do a selected number of operations. " + "Further, this is strictly restricted to admin users only ") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java index 3a70fe6890..2112a89e81 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/DeviceManagementAdminService.java @@ -28,7 +28,7 @@ import javax.ws.rs.core.Response; @API(name = "DeviceManagementAdmin", version = "1.0.0", context = "/devicemgt_admin/applications", tags = {"devicemgt_admin"}) -@Path("/devices") +@Path("/admin/devices") @Api(value = "Device Management Administrative Service", description = "This an API intended to be used by " + "'internal' components to log in as an admin user and do a selected number of operations. " + "Further, this is strictly restricted to admin users only ") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java index f730dd5720..1143447c39 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/GroupManagementAdminService.java @@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Date; -@Path("/groups") +@Path("/admin/groups") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Api(value = "Group Management Administrative Service", description = "This an API intended to be used by " + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java index 4b156e0d6e..7dd351734b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/admin/UserManagementAdminService.java @@ -26,7 +26,7 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -@Path("/users") +@Path("/admin/users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Api(value = "User Management Administrative Service", description = "This an API intended to be used by " + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java index e16a92e6d0..c5f2fb728c 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/ActivityProviderServiceImpl.java @@ -23,7 +23,10 @@ import org.apache.commons.logging.LogFactory; import org.wso2.carbon.device.mgt.common.operation.mgt.Activity; import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; import org.wso2.carbon.device.mgt.jaxrs.service.api.ActivityInfoProviderService; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.UnexpectedServerErrorException; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; import javax.ws.rs.*; @@ -44,23 +47,30 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService public Response getActivity( @PathParam("id") String id, @HeaderParam("If-Modified-Since") String ifModifiedSince) { - Activity operation = null; + Activity activity; DeviceManagementProviderService dmService; try { + RequestValidationUtil.validateActivityId(id); + dmService = DeviceMgtAPIUtils.getDeviceManagementService(); - operation = dmService.getOperationByActivityId(id); + activity = dmService.getOperationByActivityId(id); + if (activity == null) { + return Response.status(Response.Status.NOT_FOUND).entity("No activity can be found upon the provided " + + "activity id '" + id + "'").build(); + } } catch (OperationManagementException e) { String msg = "ErrorResponse occurred while fetching the activity for the supplied id."; log.error(msg, e); - Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()); } - return Response.status(Response.Status.OK).entity(operation).build(); + return Response.status(Response.Status.OK).entity(activity).build(); } @GET @Override public Response getActivities( - @QueryParam("timestamp") String timestamp, + @QueryParam("timestamp") long timestamp, @HeaderParam("If-Modified-Since") String ifModifiedSince, @QueryParam("offset") int offset, @QueryParam("limit") int limit) { @@ -68,11 +78,13 @@ public class ActivityProviderServiceImpl implements ActivityInfoProviderService DeviceManagementProviderService dmService; try { dmService = DeviceMgtAPIUtils.getDeviceManagementService(); - activities = dmService.getActivitiesUpdatedAfter(Long.parseLong(timestamp)); + activities = dmService.getActivitiesUpdatedAfter(timestamp); + } catch (OperationManagementException e) { String msg = "ErrorResponse occurred while fetching the activities updated after given time stamp."; log.error(msg, e); - Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build(); + throw new UnexpectedServerErrorException( + new ErrorResponse.ErrorResponseBuilder().setCode(500l).setMessage(msg).build()); } return Response.status(Response.Status.OK).entity(activities).build(); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java index 2b5be724e9..51d17a9770 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/ApplicationManagementAdminServiceImpl.java @@ -40,7 +40,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -@Path("/applications") +@Path("/admin/applications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class ApplicationManagementAdminServiceImpl implements ApplicationManagementAdminService { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java index 8709c0875e..9a07245cd2 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/DeviceManagementAdminServiceImpl.java @@ -30,7 +30,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; -@Path("/devices") +@Path("/admin/devices") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class DeviceManagementAdminServiceImpl implements DeviceManagementAdminService { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java index bc22e7b955..7fe91394f4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/GroupManagementAdminServiceImpl.java @@ -31,7 +31,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.Date; -@Path("/groups") +@Path("/admin/groups") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class GroupManagementAdminServiceImpl implements GroupManagementAdminService { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java index fa004d5cb8..fc30afea17 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/admin/UserManagementAdminServiceImpl.java @@ -26,7 +26,7 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -@Path("/users") +@Path("/admin/users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public class UserManagementAdminServiceImpl implements UserManagementAdminService { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java index 9622abde7c..53da08ff52 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java @@ -168,4 +168,43 @@ public class RequestValidationUtil { "cannot be null").build()); } } + + public static void validateTimestamp(String timestamp) { + if (timestamp == null || timestamp.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Timestamp value " + + "cannot be null or empty").build()); + } + try { + Long.parseLong(timestamp); + } catch (NumberFormatException e) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Invalid timestamp value").build()); + } + } + + public static void validateActivityId(String activityId) { + if (activityId == null || activityId.isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Activity Id " + + "cannot be null or empty. It should be in the form of " + + "'[ACTIVITY][_][any-positive-integer]' instead").build()); + } + String[] splits = activityId.split("_"); + if (splits == null || splits[0] == null || splits[0].isEmpty() || !"ACTIVITY".equals(splits[0]) || + splits[1] == null || splits[0].isEmpty()) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Activity Id should be in the form of '[ACTIVITY][_][any-positive-integer]'").build()); + } + try { + Long.parseLong(splits[1]); + } catch (NumberFormatException e) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage( + "Activity Id should be in the form of '[ACTIVITY][_][any-positive-integer]'").build()); + } + } + } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java new file mode 100644 index 0000000000..b327104241 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/util/UnexpectedServerErrorException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. 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.util; + +import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +public class UnexpectedServerErrorException extends WebApplicationException { + + private static final long serialVersionUID = 147943579458906890L; + + public UnexpectedServerErrorException(ErrorResponse error) { + super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build()); + } + +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/Activity.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/Activity.java index deee7cbe6d..d5febd6217 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/Activity.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/Activity.java @@ -19,6 +19,7 @@ package org.wso2.carbon.device.mgt.common.operation.mgt; +import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -36,27 +37,36 @@ public class Activity { name = "activityId", value = "Activity identifier", required = true) + @JsonProperty("activityId") private String activityId; + @ApiModelProperty( name = "code", value = "Activity code", required = true) + @JsonProperty("code") private String code; + @ApiModelProperty( name = "type", value = "Activity type", required = true, allowableValues = "CONFIG, MESSAGE, INFO, COMMAND, PROFILE, POLICY") + @JsonProperty("type") private Type type; + @ApiModelProperty( name = "createdTimeStamp", value = "Timestamp recorded when the activity took place", required = true) + @JsonProperty("createdTimestamp") private String createdTimeStamp; + @ApiModelProperty( name = "activityStatuses", value = "Collection of statuses corresponding to the activity", required = true) + @JsonProperty("activityStatuses") private List activityStatus; public String getActivityId() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java index d530e94a48..c706ee7a71 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.common/src/main/java/org/wso2/carbon/device/mgt/common/operation/mgt/ActivityStatus.java @@ -19,6 +19,7 @@ package org.wso2.carbon.device.mgt.common.operation.mgt; +import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import org.wso2.carbon.device.mgt.common.DeviceIdentifier; @@ -31,25 +32,33 @@ public class ActivityStatus { public enum Status { IN_PROGRESS, PENDING, COMPLETED, ERROR, REPEATED } + @ApiModelProperty( name = "deviceIdentifier", value = "Device identifier of the device.", required = true) + @JsonProperty("deviceIdentifier") private DeviceIdentifier deviceIdentifier; + @ApiModelProperty( name = "status", value = "Status of the activity performed.", required = true) + @JsonProperty("status") private Status status; + @ApiModelProperty( name = "responses", value = "Responses received from devices.", required = true) + @JsonProperty("responses") private List responses; + @ApiModelProperty( name = "updatedTimestamp ", value = "Last updated time of the activity.", required = true) + @JsonProperty("updatedTimestamp") private String updatedTimestamp; public DeviceIdentifier getDeviceIdentifier() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java index 821276398f..c4bb97bc22 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/OperationManagerImpl.java @@ -757,13 +757,13 @@ public class OperationManagerImpl implements OperationManager { // This parses the operation id from activity id (ex : ACTIVITY_23) and converts to the integer. int operationId = Integer.parseInt( activity.replace(DeviceManagementConstants.OperationAttributes.ACTIVITY, "")); - if(operationId == 0){ + if (operationId == 0){ throw new IllegalArgumentException("Operation ID cannot be null or zero (0)."); } try { OperationManagementDAOFactory.openConnection(); Activity act = operationDAO.getActivity(operationId); - act.setActivityId(activity); +// act.setActivityId(activity); return act; } catch (SQLException e) { throw new OperationManagementException("Error occurred while opening a connection to the data source.", e); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java index 332bfe842e..e7fa8bdd62 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.core/src/main/java/org/wso2/carbon/device/mgt/core/operation/mgt/dao/impl/GenericOperationDAOImpl.java @@ -52,7 +52,7 @@ public class GenericOperationDAOImpl implements OperationDAO { Connection connection = OperationManagementDAOFactory.getConnection(); String sql = "INSERT INTO DM_OPERATION(TYPE, CREATED_TIMESTAMP, RECEIVED_TIMESTAMP, OPERATION_CODE) " + "VALUES (?, ?, ?, ?)"; - stmt = connection.prepareStatement(sql, new String[] {"id"}); + stmt = connection.prepareStatement(sql, new String[]{"id"}); stmt.setString(1, operation.getType().toString()); stmt.setTimestamp(2, new Timestamp(new Date().getTime())); stmt.setTimestamp(3, null); @@ -93,7 +93,7 @@ public class GenericOperationDAOImpl implements OperationDAO { throws OperationManagementDAOException { PreparedStatement stmt = null; try { - long time = System.currentTimeMillis()/1000; + long time = System.currentTimeMillis() / 1000; Connection connection = OperationManagementDAOFactory.getConnection(); stmt = connection.prepareStatement("UPDATE DM_ENROLMENT_OP_MAPPING SET STATUS=?, UPDATED_TIMESTAMP=? " + "WHERE ENROLMENT_ID=? and OPERATION_ID=?"); @@ -128,14 +128,14 @@ public class GenericOperationDAOImpl implements OperationDAO { // This will return only one result always. rs = stmt.executeQuery(); int id = 0; - while (rs.next()){ + while (rs.next()) { id = rs.getInt("ID"); } - if (id != 0){ + if (id != 0) { stmt = connection.prepareStatement("UPDATE DM_ENROLMENT_OP_MAPPING SET STATUS = ?, " + "UPDATED_TIMESTAMP = ? WHERE ID = ?"); stmt.setString(1, newStatus.toString()); - stmt.setLong(2, System.currentTimeMillis()/1000); + stmt.setLong(2, System.currentTimeMillis() / 1000); stmt.setInt(3, id); stmt.executeUpdate(); } @@ -257,7 +257,7 @@ public class GenericOperationDAOImpl implements OperationDAO { PreparedStatement stmt = null; ResultSet rs = null; - Activity activity = new Activity(); + Activity activity = null; List activityStatusList = new ArrayList<>(); try { Connection conn = OperationManagementDAOFactory.getConnection(); @@ -281,8 +281,10 @@ public class GenericOperationDAOImpl implements OperationDAO { int enrolmentId = 0; ActivityStatus activityStatus = null; - while (rs.next()) { - if (enrolmentId == 0){ + + if (rs.next()) { + activity = new Activity(); + if (enrolmentId == 0) { activity.setType(Activity.Type.valueOf(rs.getString("OPERATION_TYPE"))); activity.setCreatedTimeStamp(new java.util.Date(rs.getLong(("CREATED_TIMESTAMP"))).toString()); activity.setCode(rs.getString("OPERATION_CODE")); @@ -306,6 +308,7 @@ public class GenericOperationDAOImpl implements OperationDAO { activityStatusList.add(activityStatus); enrolmentId = rs.getInt("ENROLMENT_ID"); + activity.setActivityStatus(activityStatusList); } else { if (rs.getInt("UPDATED_TIMESTAMP") != 0) { activityStatus.getResponses().add(this.getOperationResponse(rs)); @@ -322,7 +325,6 @@ public class GenericOperationDAOImpl implements OperationDAO { } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } - activity.setActivityStatus(activityStatusList); return activity; } @@ -357,7 +359,7 @@ public class GenericOperationDAOImpl implements OperationDAO { ActivityStatus activityStatus = null; while (rs.next()) { - if(operationId != rs.getInt("OPERATION_ID")) { + if (operationId != rs.getInt("OPERATION_ID")) { activity = new Activity(); activities.add(activity); List statusList = new ArrayList<>(); @@ -388,7 +390,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } - if(operationId == rs.getInt("OPERATION_ID") && enrolmentId != rs.getInt("ENROLMENT_ID")) { + if (operationId == rs.getInt("OPERATION_ID") && enrolmentId != rs.getInt("ENROLMENT_ID")) { activityStatus = new ActivityStatus(); activity.setType(Activity.Type.valueOf(rs.getString("OPERATION_TYPE"))); @@ -403,7 +405,7 @@ public class GenericOperationDAOImpl implements OperationDAO { activityStatus.setStatus(ActivityStatus.Status.valueOf(rs.getString("STATUS"))); List operationResponses = new ArrayList<>(); - if (rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) { + if (rs.getTimestamp("RECEIVED_TIMESTAMP") != (null)) { operationResponses.add(this.getOperationResponse(rs)); } activityStatus.setResponses(operationResponses); @@ -411,7 +413,7 @@ public class GenericOperationDAOImpl implements OperationDAO { enrolmentId = rs.getInt("ENROLMENT_ID"); } else { - if (rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) { + if (rs.getTimestamp("RECEIVED_TIMESTAMP") != (null)) { activityStatus.getResponses().add(this.getOperationResponse(rs)); } } @@ -432,14 +434,14 @@ public class GenericOperationDAOImpl implements OperationDAO { private OperationResponse getOperationResponse(ResultSet rs) throws ClassNotFoundException, IOException, SQLException { OperationResponse response = new OperationResponse(); - if(rs.getTimestamp("RECEIVED_TIMESTAMP") !=(null)) { + if (rs.getTimestamp("RECEIVED_TIMESTAMP") != (null)) { response.setRecievedTimeStamp(rs.getTimestamp("RECEIVED_TIMESTAMP").toString()); } ByteArrayInputStream bais = null; ObjectInputStream ois = null; byte[] contentBytes; try { - if(rs.getBytes("OPERATION_RESPONSE") != null) { + if (rs.getBytes("OPERATION_RESPONSE") != null) { contentBytes = (byte[]) rs.getBytes("OPERATION_RESPONSE"); bais = new ByteArrayInputStream(contentBytes); ois = new ObjectInputStream(bais); @@ -515,7 +517,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } catch (SQLException e) { throw new OperationManagementDAOException("Error occurred while retrieving the operations updated " + - "after a given time" , e); + "after a given time", e); } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } @@ -523,7 +525,6 @@ public class GenericOperationDAOImpl implements OperationDAO { } - @Override public void deleteOperation(int id) throws OperationManagementDAOException { PreparedStatement stmt = null; @@ -603,7 +604,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS"))); @@ -650,7 +651,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); this.setActivityId(operation, rs.getInt("ID")); @@ -696,7 +697,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(status); @@ -714,7 +715,7 @@ public class GenericOperationDAOImpl implements OperationDAO { @Override public List getOperationsByDeviceAndStatus(int enrolmentId, PaginationRequest request, - Operation.Status status) + Operation.Status status) throws OperationManagementDAOException { PreparedStatement stmt = null; ResultSet rs = null; @@ -723,10 +724,10 @@ public class GenericOperationDAOImpl implements OperationDAO { try { Connection conn = OperationManagementDAOFactory.getConnection(); String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, o.OPERATION_CODE, " + - "om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + - "INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + - "WHERE dm.ENROLMENT_ID = ? AND dm.STATUS = ?) om ON o.ID = om.OPERATION_ID ORDER BY " + - "o.CREATED_TIMESTAMP DESC LIMIT ?,?"; + "om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + + "INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + + "WHERE dm.ENROLMENT_ID = ? AND dm.STATUS = ?) om ON o.ID = om.OPERATION_ID ORDER BY " + + "o.CREATED_TIMESTAMP DESC LIMIT ?,?"; stmt = conn.prepareStatement(sql); stmt.setInt(1, enrolmentId); stmt.setString(2, status.toString()); @@ -748,7 +749,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(status); @@ -757,7 +758,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } } catch (SQLException e) { throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " + - "available for the device'" + enrolmentId + "' with status '" + status.toString(), e); + "available for the device'" + enrolmentId + "' with status '" + status.toString(), e); } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } @@ -794,7 +795,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS"))); @@ -820,9 +821,9 @@ public class GenericOperationDAOImpl implements OperationDAO { try { Connection conn = OperationManagementDAOFactory.getConnection(); String sql = "SELECT o.ID, TYPE, o.CREATED_TIMESTAMP, o.RECEIVED_TIMESTAMP, " + - "OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + - "INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + - "WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ?,?"; + "OPERATION_CODE, om.STATUS, om.ID AS OM_MAPPING_ID, om.UPDATED_TIMESTAMP FROM DM_OPERATION o " + + "INNER JOIN (SELECT * FROM DM_ENROLMENT_OP_MAPPING dm " + + "WHERE dm.ENROLMENT_ID = ?) om ON o.ID = om.OPERATION_ID ORDER BY o.CREATED_TIMESTAMP DESC LIMIT ?,?"; stmt = conn.prepareStatement(sql); stmt.setInt(1, enrolmentId); stmt.setInt(2, request.getStartIndex()); @@ -843,7 +844,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(Operation.Status.valueOf(rs.getString("STATUS"))); @@ -852,7 +853,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } } catch (SQLException e) { throw new OperationManagementDAOException("SQL error occurred while retrieving the operation " + - "available for the device'" + enrolmentId + "' with status '", e); + "available for the device'" + enrolmentId + "' with status '", e); } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } @@ -876,7 +877,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } } catch (SQLException e) { throw new OperationManagementDAOException("Error occurred while getting the operations count for enrolment : " - + enrolmentId, e); + + enrolmentId, e); } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } @@ -913,7 +914,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); operation.setStatus(Operation.Status.PENDING); @@ -962,7 +963,7 @@ public class GenericOperationDAOImpl implements OperationDAO { operation.setReceivedTimeStamp(""); } else { operation.setReceivedTimeStamp( - new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP")*1000)).toString()); + new java.sql.Timestamp((rs.getLong("UPDATED_TIMESTAMP") * 1000)).toString()); } operation.setCode(rs.getString("OPERATION_CODE")); this.setActivityId(operation, rs.getInt("ID")); @@ -986,7 +987,7 @@ public class GenericOperationDAOImpl implements OperationDAO { } - private String getActivityId( int operationId) { + private String getActivityId(int operationId) { return DeviceManagementConstants.OperationAttributes.ACTIVITY + operationId; }