Bulk Load data using REST API

Introduction

As Maximo developers, we all must be really familiar with creating, updating and deleting data using REST APIs in Maximo. The usual scenario is doing the operation per record.What if we need to do the operation in batches?. What if there is a requirement to load thousands and thousands of data?. It will not be practical to call the end points for each single operation. That is where the capability of Bulk loading comes into picture.

Bulk loading in Maximo through REST APIs is a powerful mechanism for efficiently managing large volumes of data. Whether you’re migrating data into Maximo for the first time or performing periodic updates, understanding how to leverage bulk loading capabilities can significantly streamline your integration processes.

Understanding Bulk Load in Maximo:

Bulk loading in Maximo is like having a handy tool to effortlessly handle loads of data. It’s the behind-the-scenes capability that simplifies the process of transferring a large amount of information. Whether you’re introducing Maximo to your system or managing regular data updates, bulk loading becomes your perfect tool.

Instead of moving data piece by piece, think of bulk loading as a streamlined way to transport the entire set of information. It’s the method that transforms the complexity of data management into a more straightforward task. Imagine the difference between manually carrying buckets of water to fill a pool and having a pipeline efficiently channel the water where it needs to go – that’s bulk loading.

Understanding bulk loading is essential for orchestrating a smooth data movement in Maximo. It ensures your data flows seamlessly into Maximo, ready to be used for insights and actions. As we dive into the specifics – the REST API endpoints, data formats, and best practices – we uncover the details that make bulk loading an effective and reliable part of Maximo’s capabilities.

REST API Post endpoints

REST API creation is a very simple process in Maximo Framework compared to other systems.

Steps to create a generic REST API end point

  1. Goto Object structures application
  2. Create a new object structure record, lets consider the usecase is to loading PM workorders in bulk
  3. Add main object as WORKORDER and add child objects like meter readings,wplabor etc if required.(Lets name the object structure as WORKORDER_LOAD)
  4. Now expose all the required fields from the more action menu.
  5. Once done, save the record
  6. Now the API end point for above Object structure will look like below
  7. You can use this endpoint to connect to the maximo from any Api testing tool or external systems to consume the Api

Sample post call for single load

Payload
{
    "assetnum": "PIPE-32-T-5443",
    "worktype": "PM",
    "pmnum": "3442211",
    "status": "WAPPR",
    "reportedby": "SALAH",
    "targstartdate": "2022-08-14T20:40:56+00:00",
    "targcompdate": "2022-08-17T04:59:59+00:00",
    "siteid": "BEDFORD"
}

Headers
[
    {"key":"x-method-override","value":"SYNC","type":"text"},
    {"key":"patchtype","value":"MERGE","type":"text"},
    {"key":"properties","value":"*","type":"text"}
]

Sample post call for Bulk load

Payload
[
    {
        "_data": {
            "assetnum": "PIPE-32-T-5443",
            "worktype": "PM",
            "pmnum": "3442211",
            "status": "WAPPR",
            "reportedby": "SALAH",
            "targstartdate": "2022-08-14T20:40:56+00:00",
            "targcompdate": "2022-08-17T04:59:59+00:00",
            "siteid": "BEDFORD"
        }
    },
    {
        "_data": {
            "assetnum": "PIPE-32-T-5444",
            "worktype": "PM",
            "pmnum": "3442211",
            "status": "WAPPR",
            "reportedby": "SALAH",
            "targstartdate": "2022-08-14T20:40:56+00:00",
            "targcompdate": "2022-08-17T04:59:59+00:00",
            "siteid": "BEDFORD"
        }
    }
]

Headers
[
    {"key":"x-method-override","value":"BULK","type":"text"},
    {"key":"patchtype","value":"MERGE","type":"text"},
    {"key":"properties","value":"*","type":"text"}
]

Explanation

In the above payloads, we can see that in the single load payload, the data is directly put inside the curly braces and we need not specifically mention that the component is data section as its for a single record. Whereas in Bulk load, we can see that each individual payloads for each records need to be mentioned as _data for maximo to identify that each of those sections indicates the data fields required to form an object/related objects as per the specific object structure.

An important point is to note the "x-method-override" header. In single load post call, we used to pass value as SYNC. But for Bulk post calls, we need to pass the value as BULK, so maximo can understand that the payload is for BULK LOAD.

Error Handling

Here if an error happens to an individual payload, maybe failure due to a defined validation, just that individual payload fails and passes back the error message whereas rest passes through. If all payloads fail, then the related error messages will be pass individually same as the payload as below.
[
    {
        "_responsedata": {
            "Error": {
                "extendedError": {
                    "moreInfo": {
                        "href": http://localhost/maximo/api/error/messages/BMXZZ9000E”
                    }
                },
                "reasonCode": "BMXZZ9000E",
                "message": "BMXZZ9000E - Please provide a Valid Asset Number for Creating the Work order.",
                "statusCode": "400"
            }
        },
        "_responsemeta": {
            "status": "400"
        }
    },
    {
        "_responsedata": {
            "Error": {
                "extendedError": {
                    "moreInfo": {
                        "href": "http://localhost/maximo/api/error/messages/BMXZZ9000E”
                    }
                },
                "reasonCode": "BMXZZ9000E",
                "message": "BMXZZ9000E - Please provide a Valid Asset Number for Creating the Work order.",
                "statusCode": "400"
            }
        },
        "_responsemeta": {
            "status": "400"
        }
    }
]

One short coming for this payload is that the consumer will not be able to identify which response belongs to which payload unless we are passing the identifier in the error message. This is not practical as any message can trigger for any payload, and adding identified into each error message is a bad practice.
For this we can introduce a new field into the payload as discussed in the next section. 

Bulk Load Id

In order to identify or match the response obtained with the individual payloads, we can link them by providing a unique id using _bulkid field. We will obtain this bulkid back in the response tied inside the meta data for individual response data.
The payload will look as below:
[
    {
        "_data": {
            "assetnum": "PIPE-32-T-5443",
            "worktype": "PM",
            "pmnum": "3442211",
            "status": "WAPPR",
            "reportedby": "SALAH",
            "targstartdate": "2022-08-14T20:40:56+00:00",
            "targcompdate": "2022-08-17T04:59:59+00:00",
            "siteid": "BEDFORD",
            "_bulkid": "93890eurv4rt4"
        }
    },
    {
        "_data": {
            "assetnum": "PIPE-32-T-5444",
            "worktype": "PM",
            "pmnum": "3442211",
            "status": "WAPPR",
            "reportedby": "SALAH",
            "targstartdate": "2022-08-14T20:40:56+00:00",
            "targcompdate": "2022-08-17T04:59:59+00:00",
            "siteid": "BEDFORD",
            "_bulkid": "63890DDhv4rtRR5"
        }
    }
]


Response will be as below:

[
    {
        "_responsedata": {
            "Error": {
                "extendedError": {
                    "moreInfo": {
                        "href": "http://localhost/maximo/api/error/messages/BMXZZ9000E”
                    }
                },
                "reasonCode": "BMXZZ9000E",
                "message": "BMXZZ9000E - Please provide a Valid Asset Number for Creating the Workorder.",
                "statusCode": "400"
            }
        },
        "_responsemeta": {
            "_bulkid": "93890eurv4rt4",
            "status": "400"
        }
    },
    {
        "_responsedata": {
            "Error": {
                "extendedError": {
                    "moreInfo": {
                        "href": "http://localhost/maximo/api/error/messages/BMXZZ9000E”
                    }
                },
                "reasonCode": "BMXZZ9000E",
                "message": "BMXZZ9000E - Please provide a Valid Asset Number for Creating the Workorder.",
                "statusCode": "400"
            }
        },
        "_responsemeta": {
            "_bulkid": "63890DDhv4rtRR5",
            "status": "400"
        }
    }
]

Update/Delete records in Bulk

For Update/Delete bulk operation, we can use the metadata part to pass the methods.

Update :

[
    {
        "_data": {
            "wonum": "1110303320",
            "status": "APPR",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "5673yEidnn88"
        },
        "_meta": {
            "method": "PATCH",
            "patchtype": "MERGE"
        }
    },
    {
        "_data": {
            "wonum": "1110303321",
            "status": "APPR",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "65YeiienI388"
        },
        "_meta": {
            "method": "PATCH",
            "patchtype": "MERGE"
        }
    }
]

Delete :

[
    {
        "_data": {
            "wonum": "1110303320",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "5473yEidnn88"
        },
        "_meta": {
            "method": "DELETE"
        }
    },
    {
        "_data": {
            "wonum": "1110303321",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "315uUIenI388"
        },
        "_meta": {
            "method": "DELETE"
        }
    }
]

Multiple operations in a single request and _action

By making use of the bulk load capability we can do multiple operations together. We can create a record, update a record and even delete a record in a single payload.
Further more After Maximo Asset Management 7.6.0.8, the JSON structures for bulk requests are made easier. For example, _action at the data level is supported now, whereas the _meta and _data can be replaced by the _action itself.
Look at the below payload, where we are using _action to do multiple operations.

[
    {
        "_data": {
            "assetnum": "PIPE-32-T-5443",
            "worktype": "PM",
            "pmnum": "3442211",
            "status": "WAPPR",
            "reportedby": "SALAH",
            "targstartdate": "2022-08-14T20:40:56+00:00",
            "targcompdate": "2022-08-17T04:59:59+00:00",
            "siteid": "BEDFORD",
            "_bulkid": "93890eurv4rt4",
            "_action": "Add"
        }
    },
    {
        "_data": {
            "wonum": "1110303321",
            "status": "APPR",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "65YeiienI388",
            "_action": "Change"
        }
    },
    {
        "_data": {
            "wonum": "1110303320",
            "changeby": "SALAH",
            "siteid": "BEDFORD",
            "_bulkid": "5473yEidnn88",
            "_action": "Delete"
        }
    }
]



Summary

  • Bulk Loading can be enabled by passing BULK as value for x-method-override
  • _bulkid can be used to link individual payloads with their responses
  • _action can be used instead of passing the methods in metadata
 
OperationData Object
CREATE
"{"_data":{"record_id": "xxxx",
"siteid":"xxxx"}}"
UPDATE
"{"_data":{"record_id": "xxxx",
"siteid":"xxxx"},"_meta":{"method":"PATCH","patchtype":"MERGE"}}"
DELETE
"{"_data":{"record_id": "xxxx",
"siteid":"xxxx"},"_meta":{"method":"DELETE"}}"


JSON collection


Comments

  1. Hi, I am not able to update multiple records using BULK option. Geeting error message BMXAA4129E - A record already exists for site=XXX, work order=WO15904. Make sure that the key value for the specified record is unique. I tried passing workordervid in the request but same error.

    ReplyDelete
    Replies
    1. [
      {
      "_data": {
      "wonum": "WO15904",
      "workorderid": "17113",
      "siteid": "XXX",
      "description": "TEST WO Updated to Bulk 1",
      "_bulkid": "17113"
      }
      },
      {
      "_data": {
      "wonum": "WO15585",
      "workorderid":"16511",
      "siteid": "XXX",
      "description": "TEST WO Updated to bulk 2",
      "_bulkid": "16511"
      }
      }
      ]

      Delete
  2. Hi, Salah here . That is because you are passing it without any metadata or action to specify you are trying to update the records.Maximo is trying to create a record from this payload. You can pass either like this : {"_data":{"record_id": "xxxx",
    "siteid":"xxxx"},"_meta":{"method":"PATCH","patchtype":"MERGE"}}
    or just try passing "_action": "Change"

    ReplyDelete

Post a Comment

Popular Posts