From d08afda1e206f0b2c5c981b804620507da493ef9 Mon Sep 17 00:00:00 2001 From: Ruwan Yatawara Date: Mon, 12 Mar 2018 11:25:57 +0530 Subject: [PATCH] Ballerina file generation --- .../api/DeviceTypeManagementService.java | 138 ++++++++++++++++++ .../impl/DeviceTypeManagementServiceImpl.java | 97 ++++++++++++ .../mgt/jaxrs/util/DeviceMgtAPIUtils.java | 117 ++++++++++++++- 3 files changed, 347 insertions(+), 5 deletions(-) diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java index 390bb2dca46..fdb62c19dbd 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/api/DeviceTypeManagementService.java @@ -207,6 +207,144 @@ public interface DeviceTypeManagementService { @HeaderParam("If-Modified-Since") String ifModifiedSince); + @GET + @Path("/{type}") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get Feature Details of a Device Type", + notes = "The features in WSO2 EMM enables you to carry out many operations on a given device platform. " + + "Using this REST API you can get the features that can be carried out on a preferred device type," + + " such as iOS, Android or Windows.", + tags = "Device Type Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:features") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of supported features.", + response = DeviceTypeList.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 = 304, + message = + "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource.\n"), + @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 " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getDeviceTypeDefinition( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @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); + + @GET + @Path("/{type}/ballerina") + @ApiOperation( + produces = MediaType.APPLICATION_JSON, + httpMethod = "GET", + value = "Get Feature Details of a Device Type", + notes = "The features in WSO2 EMM enables you to carry out many operations on a given device platform. " + + "Using this REST API you can get the features that can be carried out on a preferred device type," + + " such as iOS, Android or Windows.", + tags = "Device Type Management", + extensions = { + @Extension(properties = { + @ExtensionProperty(name = Constants.SCOPE, value = "perm:device-types:features") + }) + } + ) + @ApiResponses( + value = { + @ApiResponse( + code = 200, + message = "OK. \n Successfully fetched the list of supported features.", + response = DeviceTypeList.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 = 304, + message = + "Not Modified. \n Empty body because the client already has the latest version " + + "of the requested resource.\n"), + @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 " + + "list of supported device types.", + response = ErrorResponse.class) + } + ) + Response getBallerinaImplementation( + @ApiParam( + name = "type", + value = "The device type name, such as ios, android, windows or fire-alarm.", + required = true) + @PathParam("type") + @Size(max = 45) + String type, + @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); + @GET @Path("/all/{type}") @ApiOperation( diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java index 5fdc06a5015..b7ebbf5865a 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/service/impl/DeviceTypeManagementServiceImpl.java @@ -18,8 +18,12 @@ */ package org.wso2.carbon.device.mgt.jaxrs.service.impl; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.Stub; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.Feature; import org.wso2.carbon.device.mgt.common.FeatureManager; @@ -29,9 +33,20 @@ import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.DeviceTypeList; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.*; import org.wso2.carbon.device.mgt.jaxrs.service.api.DeviceTypeManagementService; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.RequestValidationUtil; +import org.wso2.carbon.device.mgt.jaxrs.service.response.DeviceTypeResponse; +import org.wso2.carbon.device.mgt.jaxrs.util.Constants; import org.wso2.carbon.device.mgt.jaxrs.util.DeviceMgtAPIUtils; +import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.types.EventReceiverConfigurationDto; +import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.user.api.UserStoreException; +import org.wso2.carbon.utils.CarbonUtils; import javax.validation.constraints.Size; import javax.ws.rs.GET; @@ -40,6 +55,8 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; +import java.io.*; +import java.rmi.RemoteException; import java.util.ArrayList; import java.util.List; @@ -91,6 +108,86 @@ public class DeviceTypeManagementServiceImpl implements DeviceTypeManagementServ return Response.status(Response.Status.OK).entity(features).build(); } + @GET + @Override + @Path("/{type}") + public Response getDeviceTypeDefinition(@PathParam("type") @Size(max = 45) String type, @HeaderParam("If-Modified-Since") String ifModifiedSince) { + DeviceTypeResponse deviceType = null; + try { + if (type == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + deviceType = DeviceMgtAPIUtils.getDeviceTypeDefinition(type); + } catch (DeviceManagementException e) { + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build(); + } + return Response.status(Response.Status.OK).entity(deviceType).build(); + } + + @GET + @Override + @Path("/{type}/ballerina") + public Response getBallerinaImplementation(@PathParam("type") @Size(max = 45) String type, @HeaderParam("If-Modified-Since") String ifModifiedSince) { + String AGENT_BASE_PATH = CarbonUtils.getCarbonHome() + File.separator + "repository" + + File.separator + "resources" + File.separator + "ballerina-agents"+ File.separator; + String AGENT_TEMPLATE_PATH = CarbonUtils.getCarbonHome() + File.separator + "conf" + File.separator + "agent-template" + File.separator + "ballerina"; + + DeviceTypeResponse deviceType = null; + try { + if (type == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + return Response.status(Response.Status.BAD_REQUEST).build(); + } + deviceType = DeviceMgtAPIUtils.getDeviceTypeDefinition(type); + } catch (DeviceManagementException e) { + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build(); + } + + DeviceTypeEvent deviceTypeEvent = deviceType.getDeviceTypeEvent(); + File[] listOfFiles =new File(AGENT_TEMPLATE_PATH).listFiles(); + String s = null; + + JSONObject jsonEvent = new JSONObject(); + List attributes = deviceTypeEvent.getEventAttributeList().getList(); + for(Attribute attribute : attributes){ + jsonEvent.put(attribute.getName(),attribute.getType()); + } + + for(File file : listOfFiles){ + if (file.isFile() && file.getName().endsWith(".bal")) { + BufferedReader br= null; + BufferedWriter bw= null; + String packageExt = ""; + try { + File outputFile = new File(AGENT_BASE_PATH + type + "/org/wso2/iot/" + type+ "/agent/" + file.getName()); + outputFile.getParentFile().mkdirs(); + bw = new BufferedWriter(new FileWriter(outputFile)); + br = new BufferedReader(new FileReader(file)); + while ((s=br.readLine())!=null){ + s = s.replace("${package}", "org.wso2.iot."+type); + s = s.replace("${deviceType.eventDef}", jsonEvent.toString()); + bw.write(s + "\n"); + } + br.close(); + bw.close(); + } catch (IOException e) { + return Response.serverError().entity( + new ErrorResponse.ErrorResponseBuilder().setMessage("Error while accessing template for ballerina artifact generation.").build()).build(); + } + } + } + return Response.status(Response.Status.OK).build(); + } + + + @Override @GET @Path("/config") diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java index 02f8ce62a97..cb45a57c4c1 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java +++ b/components/device-mgt/org.wso2.carbon.device.mgt.api/src/main/java/org/wso2/carbon/device/mgt/jaxrs/util/DeviceMgtAPIUtils.java @@ -20,6 +20,7 @@ package org.wso2.carbon.device.mgt.jaxrs.util; import org.apache.axis2.AxisFault; import org.apache.axis2.client.Options; +import org.apache.axis2.client.Stub; import org.apache.axis2.java.security.SSLProtocolSocketFactory; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.commons.codec.binary.Base64; @@ -36,10 +37,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.device.mgt.analytics.data.publisher.service.EventsPublisherService; -import org.wso2.carbon.device.mgt.common.Device; -import org.wso2.carbon.device.mgt.common.DeviceIdentifier; -import org.wso2.carbon.device.mgt.common.DeviceManagementException; -import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.*; import org.wso2.carbon.device.mgt.common.authorization.DeviceAccessAuthorizationService; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration; @@ -47,17 +45,23 @@ import org.wso2.carbon.device.mgt.common.configuration.mgt.PlatformConfiguration import org.wso2.carbon.device.mgt.common.geo.service.GeoLocationProviderService; import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementService; import org.wso2.carbon.device.mgt.common.spi.DeviceTypeGeneratorService; +import org.wso2.carbon.device.mgt.common.type.mgt.DeviceTypeMetaDefinition; import org.wso2.carbon.device.mgt.core.app.mgt.ApplicationManagementProviderService; import org.wso2.carbon.device.mgt.core.device.details.mgt.DeviceInformationManager; +import org.wso2.carbon.device.mgt.core.dto.DeviceType; import org.wso2.carbon.device.mgt.core.search.mgt.SearchManagerService; import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService; import org.wso2.carbon.device.mgt.jaxrs.beans.ErrorResponse; -import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.EventAttributeList; +import org.wso2.carbon.device.mgt.jaxrs.beans.analytics.*; import org.wso2.carbon.device.mgt.jaxrs.service.impl.util.InputValidationException; +import org.wso2.carbon.device.mgt.jaxrs.service.response.DeviceTypeResponse; import org.wso2.carbon.event.publisher.stub.EventPublisherAdminServiceStub; import org.wso2.carbon.event.receiver.stub.EventReceiverAdminServiceStub; +import org.wso2.carbon.event.receiver.stub.types.EventReceiverConfigurationDto; import org.wso2.carbon.event.stream.stub.EventStreamAdminServiceStub; +import org.wso2.carbon.event.stream.stub.types.EventStreamAttributeDto; +import org.wso2.carbon.event.stream.stub.types.EventStreamDefinitionDto; import org.wso2.carbon.identity.jwt.client.extension.JWTClient; import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; @@ -84,9 +88,11 @@ import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.rmi.RemoteException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; @@ -150,6 +156,107 @@ public class DeviceMgtAPIUtils { } } + public static DeviceTypeResponse getDeviceTypeDefinition(String type) throws DeviceManagementException { + List features; + DeviceTypeEvent deviceTypeEvent; + List properties; + + //Get Event Stream + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + EventStreamAdminServiceStub eventStreamAdminServiceStub = null; + EventReceiverAdminServiceStub eventReceiverAdminServiceStub = null; + try { + if (type == null || + !DeviceMgtAPIUtils.getDeviceManagementService().getAvailableDeviceTypes().contains(type)) { + String errorMessage = "Invalid device type"; + log.error(errorMessage); + throw new DeviceManagementException(errorMessage); + } + String streamName = DeviceMgtAPIUtils.getStreamDefinition(type, tenantDomain); + eventStreamAdminServiceStub = DeviceMgtAPIUtils.getEventStreamAdminServiceStub(); + EventStreamDefinitionDto eventStreamDefinitionDto = eventStreamAdminServiceStub.getStreamDefinitionDto( + streamName + ":" + Constants.DEFAULT_STREAM_VERSION); + if (eventStreamDefinitionDto == null) { + throw new DeviceManagementException("Event stream definition is empty."); + } + + EventStreamAttributeDto[] eventStreamAttributeDtos = eventStreamDefinitionDto.getPayloadData(); + EventAttributeList eventAttributeList = new EventAttributeList(); + List attributes = new ArrayList<>(); + for (EventStreamAttributeDto eventStreamAttributeDto : eventStreamAttributeDtos) { + attributes.add(new Attribute(eventStreamAttributeDto.getAttributeName() + , AttributeType.valueOf(eventStreamAttributeDto.getAttributeType().toUpperCase()))); + } + eventAttributeList.setList(attributes); + + deviceTypeEvent = new DeviceTypeEvent(); + deviceTypeEvent.setEventAttributeList(eventAttributeList); + deviceTypeEvent.setTransportType(TransportType.HTTP); + eventReceiverAdminServiceStub = DeviceMgtAPIUtils.getEventReceiverAdminServiceStub(); + EventReceiverConfigurationDto eventReceiverConfigurationDto = eventReceiverAdminServiceStub + .getActiveEventReceiverConfiguration(getReceiverName(type, tenantDomain, TransportType.MQTT)); + if (eventReceiverConfigurationDto != null) { + deviceTypeEvent.setTransportType(TransportType.MQTT); + } + + } catch (AxisFault e) { + String msg = "Failed to retrieve event definitions for tenantDomain:" + tenantDomain; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (RemoteException e) { + String msg = "Failed to connect with the remote services:" + tenantDomain; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (JWTClientException e) { + String msg = "Failed to generate jwt token for tenantDomain:" + tenantDomain; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } catch (UserStoreException e) { + String msg = "Failed to connect with the user store, tenantDomain: " + tenantDomain; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } finally { + cleanup(eventStreamAdminServiceStub); + cleanup(eventReceiverAdminServiceStub); + } + + //Get Device Type Meta Information + try { + DeviceType deviceType = DeviceMgtAPIUtils.getDeviceManagementService().getDeviceType(type); + DeviceTypeMetaDefinition metaInfo = deviceType.getDeviceTypeMetaDefinition(); + properties = metaInfo.getProperties(); + features = metaInfo.getFeatures(); + + } catch (DeviceManagementException e) { + String msg = "Error occurred while retrieving the list of meta-information for '" + type + "' device type"; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + + DeviceTypeResponse deviceType = new DeviceTypeResponse(); + deviceType.setDeviceType(type); + deviceType.setDeviceTypeEvent(deviceTypeEvent); + deviceType.setFeatures(features); + deviceType.setAttributes(properties); + + return deviceType; + } + + private static String getReceiverName(String deviceType, String tenantDomain, TransportType transportType) { + return deviceType.replace(" ", "_").trim() + "-" + tenantDomain + "-" + transportType.toString() + "-receiver"; + } + + + private static void cleanup(Stub stub) { + if (stub != null) { + try { + stub.cleanup(); + } catch (AxisFault axisFault) { + log.warn("Failed to clean the stub " + stub.getClass()); + } + } + } + public static int getNotifierFrequency(PlatformConfiguration tenantConfiguration) { List configEntryList = tenantConfiguration.getConfiguration(); if (configEntryList != null && !configEntryList.isEmpty()) {