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 "Overview" in 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
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.
- Http method: The endpoint with Http method post, get, and so on that creates
@POST when the source file is 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.
- Type: The type of model. For example: string, object.
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:
- Start the user environment.
- Start the transaction.
- Set the user environment on the transaction.
- Set up the request, call the API method on the entity manager class, and manage the response.
- Commit or rollback the transaction.
- (Optional) Perform a rollback when an error occurs.
- 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:
- 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.
- Open the generated Model file from the reference_rest_webservice/build/swagger-code-resourcemodel/src/main/java folder.
- Remove the following lines from the Model
file:
import org.springframework.validation.annotation.Validated; @Validated
- Save the Model file and copy the updated file to the reference_rest_webservice\src\oracle\communications\inventory\rest\model folder.
- 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.
- 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:
- Clean the reference_rest_webservice directory as
follows:
gradlew clean
- If the Model, API, and API imple files are not generated yet, run the following
command:
gradlew build
- 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
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:
- Log in to the WebLogic Server Administration Console.
- In the left panel, under Domain Structure, click Deployments.
The Summary of Deployments page appears.
- In the left panel, under Change Center, click Lock & Edit.
- Select the check box next to the updated EAR file that contains your custom web service.
- Click Update.
The Update Application Assistant page appears.
- Click Change Path and then click Next.
The deployment plan is specified and custom.ear is redeployed.