OSLC
Developer Guide
OSLCDeveloper Guide
  • One level up
  • Developer Guide
  • eclipse environment setup
  • The toolchain model
  • Generating the server code
  • Exploring the generated code
  • https and SSL support
  • Authentication
  • Creating the rootservices document
  • Connecting Servers
  • Artifact Container Associations
  • Updating generated dialogs
  • Implementing a Domain Class
  • Implementing a TRS Provider
  • JUnit Tests

Implementing a Domain Class

Implementing a Domain Class

There are a number of steps required to implement each OSLC domain classes. These all follow the pattern implemented and verified for DeviceType.

Implement the resource specific methods

These are the changes to the generated resource class in package com.ibm.oslc.adaptor.iotp.resources.

Make sure to add any imports in the Implement a constructor to convert from JSON to the Java class instance

This resource class constructor converts from the JSON accessed by the adaptor manager CRUD methods into an instance of the associated Java class. This should call super() to set any OSLC properties in the superclass. Then its gets the JSON members and uses them to set the properties of the Java object.

See class IotDeviceType for a typical implementation.

Implement the resource toJson() method

This method converts the Java class to a JSON object as defined by the IoT Platform REST APIs.

See class IotDeviceType for a typical implementation.

Update the Resource toString() method

Update the resource’s toString(boolean) method to return getTitle(). This provides a useful representation of the resource in various lists in a selection dialog, etc.

        // Start of user code toString_finalize
        if (getTitle() != null) result = getTitle();
        // End of user code
    
        return result;

This ensures that Links to resources (which might not have the title set) will also display properly.

Implement the Connector Manager CRUD methods

The adaptor manager CE4IoTConnectorManager is the key class generated by the code generator that supports HTTP methods on the resource. All the CRUD methods for all the domain resources are generated as static methods in this class. User code needs to be added to implement these methods.

Implement the Connector Manager create method

Implement the CE4IoTConnectorManager.create<resource)() method to create a new resource instance. This method uses the constructor to actually create the resource.

This method is typically called when an OSLC application requests a creation dialog, the user fills in the fields and presses the submit button. The IotPlatformService class provides the JAX-RS methods that dispatch to these connector manager creation methods.

Heres' a typical implementation:

        // Start of user code createDeviceType
                try {
                        IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        IoTPClient client = (IoTPClient)httpServletRequest.getSession().getAttribute(IoTPClient.IOTPCLIENT_ATTRIBUTE);
                        String uri = "device/types";
                        // Create the JSon Element representing the device.
                        JsonObject json = aResource.toJson().getAsJsonObject();
                        // Remove any properties that can't be assigned in case they were copied from another resource
                        json.remove("createdDateTime");
                        json.remove("updatedDateTime");

                        // Convert the result back
                        JsonElement result = client.createIoTResource(info.name, uri, json);
                        // we do not create any logical and physical interfaces here
                        if (result != null) newResource = new DeviceType(info, aResource.getIdentifier(), result, null, null);
                } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                }
        // End of user code

The ServiceProviderInfo is obtained from the IoT Platform organization id (since organizations are containers of resources and are therefore treated as OSLC ServiceProvider instances). The info contains the information needed to formulate the IoT Platform URI for the resource including the HTTP protocol, platform base, and API version.

The IoTPClient is obtained from the session and is an instance of the client for a particular logged in (or authenticated) IoT Platform user.

The Java representation of the OSLC resources is then converted to JSON using its toJson() instance method (see below). A few JSON attributes that the IoT Platform REST APIs do not allow in the POST method are removed. Then the IoTPClient is used to create the IoT Platform device based on the service provider information, the resource identifier, and the JSON object.

Implement the Manager read method

Implement the CE4IoTConnectorManager.get() method to get a resource with a given id. The read method access the IoT Platform resource using the REST APIs, and converts the returned JSON object into the Java representation of the OSLC resource. This method is used in many places by the server, including to provide information for the small and large resource preview dialogs.

Here's a typical implementation:

        // Start of user code getDeviceType
                try {
                        if (deviceTypeId == null) {
                                throw new Exception("Device ID must not be null");
                        }
                        final IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        IoTPClient client = (IoTPClient)httpServletRequest.getSession().getAttribute(IoTPClient.IOTPCLIENT_ATTRIBUTE);
                        String uri = "device/types/" + deviceTypeId;
                        JsonElement deviceType = client.readIoTResource(info.name, uri);
                        if (deviceType == null) return aResource;
                        // Also get the draft serviceInterface and logicalInterfaces
                        JsonElement physicalInterface = client.readIoTResource(info.name, "draft/"+uri+"/physicalinterface");
                        JsonElement logicalInterfaces = client.readIoTResource(info.name, "draft/"+uri+"/logicalinterfaces");
                        aResource = new DeviceType(info, deviceTypeId, deviceType, physicalInterface, logicalInterfaces);
                } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                }
        // End of user code

Again, each of these CRUD methods access the ServiceProviderInfo for the IoT Platform organization in order to get the details required to form the IoT Platform URI for the resource.

As in all the CRUD methods, the IoTPClient instance for the particular user is obtained from the HTTP session information.

The IoTPClient is then used to read the resource which is then converted to the proper Java class using a constructor created for the purpose (see below).

Implement the Manager query method

Implement the CE4IoTConnectorManager.querys() method to return all the instances of the resource. These methods get all the instances of a resource and are typical used to implement OSLC query as well as to provide information for selection dialogs.

Here's a typical implementation:

        // Start of user code queryDeviceTypes
                try {
                        IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        IoTPClient client = (IoTPClient)httpServletRequest.getSession().getAttribute(IoTPClient.IOTPCLIENT_ATTRIBUTE);
                        String uri = "device/types";
                        JsonObject result = client.readIoTResource(info.name, uri).getAsJsonObject();
                        JsonArray results = result.getAsJsonArray("results");
                        resources = new ArrayList<DeviceType>(results.size());
                        for (int i = 0; i < results.size(); i++) {
                                JsonObject obj = results.get(i).getAsJsonObject();

                                // TODO: query doesn't include logical and physical interfaces
                                DeviceType deviceType = new DeviceType(info, obj.get("id").getAsString(),  obj, null, null);
                                // Note: toString() methods are used to display the resource in the selection dialog, so we use that here.
                                // This will generally be the dcterms:label
                                // Handle dangling meta char '*' for user convenience
                                if (where == null || where.equals("") || where.equals("*")) where = ".*";
                                if (deviceType.toString().matches(where)) resources.add(deviceType);
                        }
                } catch (PatternSyntaxException e) { 
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                } 
        // End of user code

The IoTPClient is used to read the IoT Platform resource, in this case using a URI that returns a JSON object that contains a list of object instances. This is then converted into an ArrayList of the corresponding OSLC Java objects using the same constructors used in the read method.

Implement the Manager update method

Implement the CE4IoTConnectorManager.update() method to update a resource with a given id. This method has to json.remove any OSLC properties that are not settable through the IoT Platform REST APIs.

Here's a typical implementation:

        // Start of user code updateDeviceType
                try {
                        // RQM attempts to set the backlink without a properly constructed resource, ignore this since we can't store any links
                        if (aResource.getIdentifier() == null) return aResource;
                        IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        IoTPClient client = (IoTPClient)httpServletRequest.getSession().getAttribute(IoTPClient.IOTPCLIENT_ATTRIBUTE);
                        String uri = "device/types/" + deviceTypeId;
                        JsonObject json = aResource.toJson().getAsJsonObject();
                        // Remove the properties that can't be updated
                        json.remove("id");
                        json.remove("classId");
                        json.remove("createdDateTime");
                        json.remove("updatedDateTime");
                        JsonElement result = client.updateIoTResource(info.name, uri, json);
                        // logical and physical interfaces are updated directly, not through the device type
                        if (result != null) updatedResource = new DeviceType(info, aResource.getIdentifier(), result, null, null);
                } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                }
        // End of user code

The OSLC Java representation of the resource is converted to its JSON representation using its toJson() method. Then the JSON attributes that cannot be updated are removed from the object. Finally the IoTPClient is used to update the IoT Platform resource given the service provider information, resource identifier, and its JSON representation.

Implement the Manager delete method

Implement the CE4IoTConnectorManager.delete{resource}() method to delete a resource with a given id.

Here's a typical implementation:

        // Start of user code deleteDeviceType
                try {
                        IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        IoTPClient client = (IoTPClient)httpServletRequest.getSession().getAttribute(IoTPClient.IOTPCLIENT_ATTRIBUTE);
                        String uri = "device/types/" + deviceTypeId;
                        deleted = client.deleteIoTResource(info.name, uri);
                } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                }
        // End of user code

Add the resource instances to the selection dialog

Implement the CE4IoTConnectorManager.DeviceTypeAndRuleAndThingTypeSelector() method to include the resources in the selection dialog as needed. This uses the query methods implemented above. This method is used to access all instances of all resources of any type that are members of an organization (or service provider). It is often used for generic selection dialogs to enable selection of any organization resource. More specific IoT Platform resource browsers may use the more specific query methods directly to fill in content for a particular IoT Platform hierarchical resource browser.

The initial implementation to include the IoT Platform DeviceType resources is:

        // Start of user code DeviceTypeAndRuleAndThingTypeSelector
        // TODO: edit this method to have only top-level resources when the selection dialog navigator is implemented 
        // These resources are displayed in the IoT Platform tree view browser in the selection dialog
                try {
                        IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                        resources = new ArrayList<AbstractResource>();
                        resources.addAll(queryDeviceTypes(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(queryPhysicalInterfaces(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(queryLogicalInterfaces(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(queryEventTypes(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(querySchemas(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(queryThingTypes(httpServletRequest, info.iotId, terms, 1, 10000));
                        resources.addAll(queryRules(httpServletRequest, info.iotId, terms, 1, 10000));
                } catch (Exception e) {
                        e.printStackTrace();
                        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
                }
        // End of user code

A resources.addAll line needs to be added for each new IoT Platform Domain resource.

Here's the implementation for the NodREDAppSelector() method that returns the Bluemix resources that should be include in the selection dialog:

        // Start of user code NodeREDAppSelector
        List<NodeREDApp> apps = queryNodeREDApps(httpServletRequest, bmxId, terms, 1, 1000);
        resources = new ArrayList<NodeREDApp>(apps.size());
        resources.addAll(apps);
        // End of user code
        return resources;

Implement the Resource ETag method

Implement the CE4IoTConnectorManager.getETagFrom{resource}() method to identify a particular version of a resource. This is needed to ensure a resource hasn’t changed between a GETn and subsequent PUT.

Here's a typical implementation:

        // Start of user code getETagFromIotDeviceType
        // TODO Implement code to return an ETag for a particular resource
        // End of user code

Update Creation Dialog Creator Method

Update IotPlatformService.createResourceAndChangeRequestAndRequirement to use the type parameter to determine which IoT Platform resource to create, and calls the appropriate CE4IoTConnectorManager.create method

The creation dialogs are in src/main/webapp/creators/.jsp. Any parameters that need to be added to the creation dialog are included here.

Redirect text/html to the IoT Platform dashboard UI

In the IoTPlatformService and BluemixServices classes, in each get{resource}asHtml() method, add this code in the _setAttributes user code area:

            // Start of user code getDeviceTypeAsHtml_setAttributes
            // Redirect to the Watson IoT Platform dashboard as best you can for the resource
            try {
                IotpServiceProviderInfo info = IoTAPIImplementation.getIotpServiceProviderInfo(httpServletRequest, iotId);
                String iotDashboardURI = "https://"+ iotId + "."+info.platformBase + "/dashboard/#/devices/deviceTypes-v2";
                httpServletResponse.sendRedirect(iotDashboardURI);
                return Response.ok().build();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // End of user code

The iotDashboardURI currently opens the IoT Platform Dashboard to show the defined DeviceTypes. That is currently as close as we can get to the logical and physical interfaces, event types and schemas. We also don't know that the URI would be for thing types and rules since they are not implemented yet. As the IoT Platform Dashboard evolves, these redirect URIs may need to change in order to get the user closer to the actual resource in the IoT Platform dashboard.

As of RELM 6.0.6, Thing, ThingType and RUL have no platform UI. These links should not be redirected until there is supported platform UI to redirect to.

Resource Preview

Update the {resource}smallpreview.jsp and largepreview.jsp files to remove any properties that don't need to be included in the small preview, and provide any formatting or style guides desired. Note that the generated content is created inside the protected user code, so any changes you make here will be preserved when the code is generated.

Note that the src/main/webapp/com/ibm/oslc/adaptor/iotp/{resource-name}.jsp generated by the Lyo Designer is used for the large preview.

Content licensed under Creative Commons Attribution 3.0 US | Edit this page | Report an issue | Open Services for Lifecycle Collaboration