diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/api/admin/MQTTManagementAdminService.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/api/admin/MQTTManagementAdminService.java new file mode 100644 index 000000000..707e1d757 --- /dev/null +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/api/admin/MQTTManagementAdminService.java @@ -0,0 +1,154 @@ +/* + * 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.andes.extensions.device.mgt.jaxrs.service.api.admin; + +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.Extension; +import io.swagger.annotations.Tag; +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.ResponseHeader; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.apimgt.annotations.api.Scope; +import org.wso2.carbon.apimgt.annotations.api.Scopes; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.util.Constants; +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@SwaggerDefinition( + info = @Info( + version = "1.0.0", + title = "", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = "name", value = "MQTTManagementAdmin"), + @ExtensionProperty(name = "context", value = "/api/mqtt-topics/v1.0/admin/topics"), + }) + } + ), + tags = { + @Tag(name = "device_management", description = "") + } +) +@Path("/admin/topics") +@Api(value = "MQTT Management Administrative Service", description = "This an API intended to be used by " + + "'internal' components to log in as an admin user and view MQTT topics dashboard. " + + "Further, this is strictly restricted to admin users only ") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Scopes( + scopes = { + @Scope( + name = "Getting Details of Topics", + description = "Getting Details of Topics", + key = "perm:admin:topics:view", + permissions = {"/device-mgt/topics/view"} + ) + } +) +public interface MQTTManagementAdminService { + + @GET + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Getting Details of Topics", + notes = "Get the details of a topic by searching via the topic name, and details.", + response = Device.class, + responseContainer = "List", + tags = "MQTT Management Administrative Service", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:admin:topics:view") + }) + } + ) + @ApiResponses(value = { + @ApiResponse(code = 200, message = "OK. \n Successfully fetched the list of topics.", + response = Device.class, + responseContainer = "List", + 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 = 304, + message = "Not Modified. Empty body because the client already has the latest version of the " + + "requested resource.\n"), + @ApiResponse( + code = 401, + message = "Unauthorized.\n The unauthorized access to the requested resource.", + response = ErrorResponse.class), + @ApiResponse( + code = 404, + message = "Not Found.\n The specified device does not exist", + response = ErrorResponse.class), + @ApiResponse( + code = 406, + message = "Not Acceptable.\n The requested media type is not supported"), + @ApiResponse( + code = 500, + message = "Internal Server Error. \n Server error occurred while fetching the device list.", + response = ErrorResponse.class) + }) + Response getFilteredSubscriptions( + + @ApiParam( + name = "tenant-domain", + value = "The name of the tenant.\n" + + "The default tenant domain of WSO2 EMM is carbon.super", + required = true, + defaultValue = "carbon.super") + @QueryParam("tenant-domain") String tenantDomain, + @ApiParam( + name = "If-Modified-Since", + value = "Checks if the requested variant was modified, since the specified date-time. \n" + + "Provide the value in the following format: EEE, d MMM yyyy HH:mm:ss Z. \n" + + "Example: Mon, 05 Jan 2014 15:10:00 +0200", + required = false) + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @ApiParam( + name = "offset", + value = "The starting pagination index for the complete list of qualified items.", + required = false, + defaultValue = "0") + @QueryParam("offset") int offset, + @ApiParam( + name = "limit", + value = "Provide how many activity details you require from the starting pagination index/offset.", + required = false, + defaultValue = "5") + @QueryParam("limit") int limit); +} diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/admin/MQTTManagementAdminServiceImpl.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/admin/MQTTManagementAdminServiceImpl.java new file mode 100644 index 000000000..e37d158dd --- /dev/null +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/admin/MQTTManagementAdminServiceImpl.java @@ -0,0 +1,86 @@ +/* + * 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.andes.extensions.device.mgt.jaxrs.service.impl.admin; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.axis2.transport.http.HttpTransportProperties; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.CarbonConstants; +import org.wso2.carbon.andes.admin.mqtt.internal.xsd.Subscription; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.service.api.admin.MQTTManagementAdminService; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.util.MQTTMgtAPIUtils; +import org.wso2.carbon.andes.mqtt.stub.AndesMQTTAdminServiceBrokerManagerAdminException; +import org.wso2.carbon.andes.mqtt.stub.AndesMQTTAdminServiceStub; +import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.servlet.ServletConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.Map; + +@Path("/admin/topics") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class MQTTManagementAdminServiceImpl implements MQTTManagementAdminService { + + private static final Log log = LogFactory.getLog(MQTTManagementAdminServiceImpl.class); + private + @Context + ServletConfig config; + private + @Context + HttpServletRequest request; + + @Override + @GET + public Response getFilteredSubscriptions( + @QueryParam("tenant-domain") String tenantDomain, + @HeaderParam("If-Modified-Since") String ifModifiedSince, + @QueryParam("offset") int offset, + @QueryParam("limit") int limit) { + RequestValidationUtil.validatePaginationParameters(offset, limit); + try { + int currentTenantId = CarbonContext.getThreadLocalCarbonContext().getTenantId(); + if (MultitenantConstants.SUPER_TENANT_ID != currentTenantId) { + return Response.status(Response.Status.UNAUTHORIZED).entity( + new ErrorResponse.ErrorResponseBuilder().setMessage( + "Current logged in user is not authorized to perform this operation").build()).build(); + } + return null; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + +} diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/InputValidationException.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/InputValidationException.java new file mode 100644 index 000000000..812c30ee6 --- /dev/null +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/InputValidationException.java @@ -0,0 +1,35 @@ +/* + * 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.andes.extensions.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.beans.ErrorResponse; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.core.Response; +import java.io.Serializable; + +public class InputValidationException extends BadRequestException implements Serializable { + + private static final long serialVersionUID = 147843579458906890L; + + public InputValidationException(ErrorResponse error) { + super(Response.status(Response.Status.BAD_REQUEST).entity(error).build()); + } + +} diff --git a/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java new file mode 100644 index 000000000..0f479d984 --- /dev/null +++ b/components/extensions/mb-extensions/org.wso2.carbon.andes.extensions.device.mgt.api/src/main/java/org/wso2/carbon/andes/extensions/device/mgt/jaxrs/service/impl/util/RequestValidationUtil.java @@ -0,0 +1,43 @@ +/* + * 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.andes.extensions.device.mgt.jaxrs.service.impl.util; + +import org.wso2.carbon.andes.extensions.device.mgt.jaxrs.beans.*; + +public class RequestValidationUtil { + public static void validatePaginationParameters(int offset, int limit) { + if (offset < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter offset is s " + + "negative value.").build()); + } + if (limit < 0) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit is a " + + "negative value.").build()); + } + if (limit > 100) { + throw new InputValidationException( + new ErrorResponse.ErrorResponseBuilder().setCode(400l).setMessage("Request parameter limit should" + + " be less than or equal to 100.").build()); + } + + } + +}