5 Developing Custom REST Web Services

This chapter provides information about integrating Oracle Communications Unified Inventory Management (UIM) with external systems by developing custom REST web services. It describes the approach to developing web services and the guidelines you should follow.

About the UIM REST Reference Web Services

This chapter uses the UIM Reference Web Service as an example that you can extend.

The UIM Reference Web Service is part of the UIM Software Developer's Kit (SDK). The UIM SDK provides the resources required to build an Inventory cartridge in Design Studio. For more information about the UIM SDK, see UIM Developer's Guide.

This chapter assumes you are using Design Studio to develop custom rest web services. If you use an integrated development environment (IDE) other than Design Studio, you can ignore the .classpath and .project files in the reference_rest_webservice.zip file.

You can view the contents of reference_rest _webservice.zip file in Oracle Communications Service Catalog and Design – Design Studio by importing the archive ZIP file into Design Studio. The ZIP file contains several types of files including the following:

  • YAML Files:

    The UIMSample1_0.yaml file defines a sample web service operation. The YAML file also defines the paths that defines individual API endpoints and HTTP methods (GET, POST, PATCH, DELETE), components, parameters and payload of operation. See "About the YAML File" for more information about the UIMSample1_0.yaml file.

  • Java Source Files :

    The Java source files provide the web service operation code. For example, these source files provide the following:

    • Model files generated out of components mentioned in yaml
    • An API manager to call UIM core for the operation
    • Transaction management for the operation with the commit or rollback results

    See "Developing the REST Web Service" for more information about the Java source files that includes the list and descriptions for each type of the class files, and information about the files that need to be created or modified.

  • Gradle Build File:

    The build.gradle file defines Gradle targets that you can run to build a custom REST web service. Gradle targets are a set of executable tasks defined in the build.gradle file. See "About the Gradle Build File" for more information.

Prerequisites for Customizing REST Web Services

You require the following prerequisites for customizing REST web services:

  • Install Gradle. See “Installing Gradle” for more information.
  • Set up a proxy. See “Setting Up Proxy” for more information.
  • Update the properties file from reference_rest_webservice/etc/<COMPUTERNAME>.properties

Installing Gradle

To install Gradle:

  1. Open the command prompt.
  2. Run the gradlew command.

    The system installs Gradle from wrapper properties.

Setting Up Proxy

After you install Gradle, the corresponding jar files are pulled from the Maven repository. You can set up proxy by updating the reference_rest_webservice/gradle.properties file.

About the YAML File

The Reference REST web service operation is defined by the UIMSample1_0.yaml file. The YAML file is located at UIM_SDK_Home/webservices/reference_rest_webservice.zip\yaml, where UIM_SDK_Home is the local directory for UIM SDK.

The YAML file defines the REST web service operation. The operation defines a requestBody, parameters, and all possible server responses. For example, the YAML file defines the following for the createInventoryGroup operation with HTTP method POST:

The request contains all possible responses where each response defines a JSON structure that is defined in the supporting schemas.

The following example shows the path definition, operation, and the input request message within a Sample YAML file:

paths:
  /inventoryGroup:
    post:
      operationId: createInventoryGroup
      summary: Create Ig
      description: |
        Creates a inventory group with the given details
      tags:
        - Sample Inventory Group
      requestBody:
        description: The ig to create.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InventoryGroup'
      responses:
        '201':
          description: The ig were created successfully.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/InventoryGroup'
        '400':
          description: The request isn't valid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: You aren't authorized to make this request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The request is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: An internal server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
.
.
.
components:
  schemas:
    InventoryGroup:
      type: object
      description: A inventoryGroup to associate with the resource.
      properties:
        id:
          type: string
          description: The ID of the ig.
          readOnly: true
        href:
          type: string
          format: uri
          description: The URI for the ig.
        name:
          type: string
          description: The name of the resource.
        description:
          type: string
          description: A free-text description for the resource. 
        igSpecification:
          $ref: 'Combined.yaml#/components/schemas/Specification'
        startDate:
          type: string
          description: The date and time when the time period starts.
          format: date-time
        endDate:
          type: string
          description: The date and time when the time period ends.
          format: date-time
        place:
          type: array
          items:
            $ref: 'Combined.yaml#/components/schemas/PlaceRef'
          description: The list of associated geographic places.
        parentGroupRef:
          type: array
          items:
            $ref: '#/components/schemas/GroupRef'
        inventoryGroupItems:
          type: array
          items:
            $ref: '#/components/schemas/GroupItemRef'
          description: The list of associated inventory group items.

The above example shows a model schema for InventoryGroup which is the used as the request body with Content-Type : application/json. For the response, with SUCCESS (20x), the same schema of InventoryGroup appears. The error model mentioned in the example is for the error codes.

For more details on OpenApi structure, see https://swagger.io/docs/specification/about/

About the Gradle Build File

The build.gradle file defines Gradle targets that you can run to build a custom web service. These build targets are a set of executable tasks that help in building a web service.

Table 5-1 describes the Gradle targets defined in the build.gradle file. See "Developing Custom REST Web Services" for information about when to run these Gradle targets, the Gradle commands that you should run, and the project to be imported to Design Studio.

Table 5-1 build.gradle and gradleTargets

Target Description
Clean Deletes the generated, temporary, and deliverable files and directories.
Build Builds the entire source code using Swagger Code Generator in build/libs.
copyResources Copies the properties files that store localized error messages to the appropriate UIM deployment directory. These properties files are located in a ZIP file in the config/resources/logging directory and are copied to the UIM_Home/config/resources/logging directory.
War Generates a war file with the name mentioned in WAR_NAME in COMPUTERNAME.properties file.
extractCustomEar Extracts the application.xml file from the EAR file specified by the EAR_PATH parameter defined in the COMPUTERNAME.properties file into the reference_rest_webservice _home/META-INF directory, where reference_rest_webservice_home is the location of the extracted reference_rest_webservice.zip file. You must edit the application.xml file manually so that the EAR file can be updated for proper deployment of the web services.
copyLibs Copies all the Gradle-pulled jars into reference_rest_webservice\lib, which can be used as CART\lib for Design Studio .classpath reference.

Note: Run this target after the build.

copyModelToSource, copyApiToSource, copyApiImplToSource These targets are not for use, if you run these will replace the model, api, impl with the generate source losing the manual changes.

For more information on Gradle, see https://docs.gradle.org/current/userguide/userguide.html

Guidelines for Developing Custom REST Web Services

This section describes the guidelines for developing a REST web service. It explains class diagrams that represent the UIM Reference REST Web Service development classes.

You use the Design-First approach to develop custom REST web services.



The Design-first approach is as follows:

  • Define YAML with paths and components. Write the YAML to define the operations and data.
  • Yaml-to-Java generation: Use the build.gradle Gradle targets provided by the Reference REST web service to generate Java source files, based on the YAML.
  • Develop a Java web service interface implementation: Use the web service development environment and tools provided by the Reference REST web service to implement the web service interface by creating new Java source files and changing the existing files.

For example, the UIM Reference Rest Web Service module is designed using the Design-first approach. This means that:

  • The InventoryGroupApiServiceImpl, InventoryGroupApiService, and InventoryGroupType Java source files are generated based on the YAML (Swagger Code generator). This generation results in the YAML operation being defined in the Java source file, but with no coding details as a sample template.
  • The build generates model, api, impl Java sources.

About Class Diagrams

In the Reference REST web service, a sample POST method createInventoryGroup operation is available. You use the createInventoryGroup sample as a template while creating the custom REST web services.

Consider the following recommendations:

  • Follow the naming convention of <HTTP method definition><EntityName appended with sample> for consistency on new operations.
    • <HTTP method definition>: POST means create, GET means retrieve, DELETE means delete, PATCH means update.
    • < EntityName appended with sample>: Do not use duplicate schema names with product REST, similar to LogicalDevice in custom webservice where you use LogicalDeviceSample.
  • Follow the sample template code for the user environment and transaction management. See "Transaction Guidelines for Rest" for more information on transaction management.
  • Run UIM core functionality by invoking the API manager methods.

The following figure shows the recommended class design for the implementation class. The UIMSample1_0 .yaml file is used to generate the InventoryGroupApiServiceImpl, InventoryGroupApiService, and InventoryGroupType source files. The InventoryGroupApiServiceImpl.java example file provides a template class that implements the interface in the InventoryGroupApiService.java and the InventoryRootService .java source file within UIM.



The UIMSample1_0.yaml file has a sample structure of OpenApiSpecification.

The Open API Object contains:

  • openapi: The version of OAS
  • info: Contains general information about API like title, description, version, and so on
  • tags: Used to grouping the API resources
  • paths: Defines the endpoints of API
  • components: Used to define data model (schemas)

A web service operation signature contains the following:

  • Paths: Defines the URL endpoint (/inventoryGroup) with baseuri from RestCustomUtils.java to form @Path("/customInventoryManagement/v3/inventoryGroup").
    • Http method: The endpoint with Http method post, get, and so on that creates @POST when the source file is generated.
      • OperationId: The operation to be performed for the endpoint with the corresponding HTTP method is defined here.
      • Parameters: The required set of parameters to be passed during runtime to the endpoint. For example: '/inventoryGroup/{id}' where parameter id is required.
      • requestBody: The schema (model) that is provided in the code generating @Consumes({ "application/json" }), which customizes the request to have content-type. If no content-type is mentioned, an HTTP “415 Unsupported Media Type” error occurs.
      • Responses: All possible server responses along with content-type to customize the response @Produces({ "application/json" }) are generated.
  • Components: The data models that describe your API inputs and outputs in schema section
  • Schemas: Defines all models used in paths. For example: InventoryGroup which will be generated as InventoryGroupType
    • Type: The type of model. For example: string, object.

      Note:

      The Object types further contain properties to define the model variables.
    • Properties: A variety of properties that can be defined with along with its type and description. You can reuse the models using $ref.

The following operations are run as per the UIMSample1_0.yaml file:

  • POST (create): createInventoryGroup
  • DELETE (delete): deleteSampleIG
  • GET (retrieve): retrieveSampleIg
  • PATCH(update): updateInventoryGroup

Transaction Guidelines for the REST Web Services

The Reference web service performs transaction actions in a specific order while managing operation transactions.

Note:

You must follow the steps in the following order. Otherwise, transaction errors may occur.

To manage the transaction, you write code that performs the following steps:

  1. Start the user environment.
  2. Start the transaction.
  3. Set the user environment on the transaction.
  4. Set up the request, call the API method on the entity manager class, and manage the response.
  5. Commit or rollback the transaction.
  6. (Optional) Perform a rollback when an error occurs.
  7. Ensure the user environment is ended with a call to the endUserEnvironment method on success or failure.

The sample from InventoryGroupApiServiceImpl.java is as follows:

UserEnvironment userEnvironment = null;
          InventoryTransactionValue transValue = null;
          InventoryGroupManager lgManager = PersistenceHelper.makeInventoryGroupManager();
		  InventoryGroup result = null;
		  InventoryGroupType resource = null;
          try {
              userEnvironment = startUserEnvironment(restUtils.getHttpRequest());
              transValue = startTransaction();
              transValue.setUserEnvironment(userEnvironment);
            ……….
             result = lgManager.createInventoryGroup(ig);
           …………………
finally {
            commitOrRollback(transValue);

Developing the REST Web Services

Developing a new web service involves generating new model file, new API file, new API impl file, and creating new Java source files. After you create these files, you should copy model file, API file, and API impl file to the corresponding paths within the reference_rest_webservice directory.

This section provides information about creating and copying these files.

Generating and Copying Model, API, and API impl Files

To generate and copy model, API, and API impl files:

  1. Navigate to the reference_rest_webservice directory and run the following command:
    gradlew build

    The above command generates Model, API, and API impl files within the reference_rest_webservice directory.

  2. Open the generated Model file from the reference_rest_webservice/build/swagger-code-resourcemodel/src/main/java folder.
  3. Remove the following lines from the Model file:
    import org.springframework.validation.annotation.Validated;
    @Validated
    
  4. Save the Model file and copy the updated file to the reference_rest_webservice\src\oracle\communications\inventory\rest\model folder.
  5. Copy the API file from the reference_rest_webservice\build\swagger-code-resourceapi\src\gen\java\oracle\communications\inventory\rest\api folder to the reference_rest_webservice\src\oracle\communications\inventory\rest\model\api folder.
  6. Copy the API impl file from the reference_rest_webservice\build\swagger-code-resourceapi\src\main\java\oracle\communications\inventory\rest\api\impl folder to the reference_rest_webservice\src\oracle\communications\inventory\rest\api\impl folder.

Creating Java Source Files

Update the content in <Entity Name appended with sample>Impl.java as per the requirements.

You can refer to the InventoryGroupApiServiceImpl.java , IpSubnetSampleApiServiceImpl.java, LogicalDeviceSampleApiServiceImpl.java files.

Use the adapter information from uim-webservices-rest-adapter.jar that delivered as a part of UIM_LIB (<DOMAIN_HOME>/UIM/lib) for associating any existing entities from the product.

Note:

A sample REST SDK testing payload is available at reference_rest _webservice.zip/doc/SamplePayload.txt.

Generating Java Source Based on the YAML File

To generate Java source from YAML using the Gradle build file:

  1. Clean the reference_rest_webservice directory as follows:
    gradlew clean
  2. If the Model, API, and API imple files are not generated yet, run the following command:
    gradlew build
  3. Copy any properties files that store localized error messages to the corresponding UIM deployment directory UIM_Home/config/resources/logging as follows:
    gradlew copyResources

    Note:

    The properties files are located within a ZIP file in the config/resources/logging directory.

Creating a WAR File

A WAR file contains the compiled classes from the developed custom web service.

Before creating a WAR file, copy all JAR files that are pulled by Gradle into the reference_rest_webservice\lib folder, which can be used as CART\lib, as follows:

gradlew copyLibs

To create a WAR file with Model, API, and API impl, run the following command:

gradlew war

You can customize the name for the WAR file by updating the COMPUTERNAME.properties file. The generated WAR file resides in the reference_rest_webservice/build/libs directory.

Packaging the WAR File in EAR File

The Reference REST Web Service WAR file is not packaged in the inventory.ear file and is therefore not automatically deployed into UIM. Rather, you must manually import the provided WAR file into an EAR file to deploy.

In UIM traditional deployments, when developing custom web services, you have the option of packaging the custom web service WAR file into:

  • The custom.ear file: If you develop a single custom web service, Oracle recommends you use the provided custom.ear file.
  • Any custom EAR files: If you develop multiple custom web services, Oracle recommends you use a separate custom EAR for each web service. This approach involves additional development work as you must create and configure your message queue and corresponding listener class. It is suitable for multiple custom web services and provides a better performance.

Extracting and Updating the EAR File

To include the corresponding custom REST web service WAR file name, extract and update the corresponding EAR file. The provided custom EAR file contains an application.xml file that you can manually extract, use as a starting point, and modify as needed.

To extract the EAR file, run the following command:

gradlew extractCustomEar

Copying application.xml and the WAR File into the EAR Folder

To copy the application.xml and WAR files into the corresponding EAR folders: reference_rest_webservice\META-INF\application.xml and reference_rest_webservice\build\libs\ReferenceRestUim.war

Redeploying custom.ear

If you have placed your custom REST web service in the custom.ear file, or in any custom EAR file, you must specify a deployment plan for the updated EAR file.

To specify a deployment plan:

  1. Log in to the WebLogic Server Administration Console.
  2. In the left panel, under Domain Structure, click Deployments.

    The Summary of Deployments page appears.

  3. In the left panel, under Change Center, click Lock & Edit.
  4. Select the check box next to the updated EAR file that contains your custom web service.
  5. Click Update.

    The Update Application Assistant page appears.

  6. Click Change Path and then click Next.

    The deployment plan is specified and custom.ear is redeployed.