Uploaded image for project: 'OpenIDM'
  1. OpenIDM
  2. OPENIDM-13222

Backport OPENIDM-13162: ManagedObject UPSERT contract creates orphan meta object on update via PUT

    Details

      Description

      The CREST UPSERT implementation first attempts to create the object, and if it fails with PreconditionFailed (412), retries the request as an UPDATE. When a managed object is configured with _meta (as it is out-of-the-box), an attempt to update the object using PUT creates an additional, orphaned meta object prior to the failed create.

      Steps to reproduce:

      1. Validate no users:

      $ curl -s -u openidm-admin:openidm-admin -X GET http://localhost:8080/openidm/managed/user?_queryFilter=true | jq .
      {
        "result": [],
        "resultCount": 0,
        "pagedResultsCookie": null,
        "totalPagedResultsPolicy": "NONE",
        "totalPagedResults": -1,
        "remainingPagedResults": -1
      }
      

      2. Validate no usermeta:

      $ curl -s -u openidm-admin:openidm-admin -X GET http://localhost:8080/openidm/internal/usermeta?_queryFilter=true | jq .
      {
        "result": [],
        "resultCount": 0,
        "pagedResultsCookie": null,
        "totalPagedResultsPolicy": "NONE",
        "totalPagedResults": -1,
        "remainingPagedResults": -1
      }
      

      3. Create user via PUT:

      $ curl -s -u openidm-admin:openidm-admin -X PUT -H "Content-type: application/json" "http://localhost:8080/openidm/managed/user/test?_fields=*,_meta/*" -d '{ "userName": "test", "password": "Test1234", "mail": "test@gmail.com", "sn": "foo", "givenName": "bar"}' | jq .
      {
        "_id": "test",
        "_rev": "000000002b7ed594",
        "userName": "test",
        "mail": "test@gmail.com",
        "sn": "foo",
        "givenName": "bar",
        "accountStatus": "active",
        "effectiveRoles": [],
        "effectiveAssignments": [],
        "_meta": {
          "_ref": "internal/usermeta/faac870f-cebd-4396-89c5-8101e8a5c17e",
          "_refResourceCollection": "internal/usermeta",
          "_refResourceId": "faac870f-cebd-4396-89c5-8101e8a5c17e",
          "_refProperties": {
            "_id": "d5bcd0e5-4966-4731-8034-06736628a90b",
            "_rev": "000000001dc39c2e"
          },
          "createDate": "2019-05-06T22:07:38.433Z",
          "lastChanged": {
            "date": "2019-05-06T22:07:38.433Z"
          },
          "loginCount": 0,
          "_rev": "00000000d9f25e49",
          "_id": "faac870f-cebd-4396-89c5-8101e8a5c17e"
        }
      }
      

      Observe _meta _ref} is {{internal/usermeta/faac870f-cebd-4396-89c5-8101e8a5c17e
      4. Update user via PUT:

      $ curl -s -u openidm-admin:openidm-admin -X PUT -H "Content-type: application/json" "http://localhost:8080/openidm/managed/user/test?_fields=*,_meta/*" -d '{ "userName": "test", "password": "Test1234", "mail": "test@gmail.com", "sn": "foo", "givenName": "baz"}' | jq .
      {
        "_id": "test",
        "_rev": "00000000f4e1e302",
        "userName": "test",
        "mail": "test@gmail.com",
        "sn": "foo",
        "givenName": "baz",
        "effectiveRoles": [],
        "effectiveAssignments": [],
        "_meta": {
          "_ref": "internal/usermeta/faac870f-cebd-4396-89c5-8101e8a5c17e",
          "_refResourceCollection": "internal/usermeta",
          "_refResourceId": "faac870f-cebd-4396-89c5-8101e8a5c17e",
          "_refProperties": {
            "_id": "d5bcd0e5-4966-4731-8034-06736628a90b",
            "_rev": "000000001dc39c2e"
          },
          "createDate": "2019-05-06T22:07:38.433Z",
          "lastChanged": {
            "date": "2019-05-06T22:07:44.808Z"
          },
          "loginCount": 0,
          "_rev": "000000001902748d",
          "_id": "faac870f-cebd-4396-89c5-8101e8a5c17e"
        }
      }
      

      _meta _ref is still internal/usermeta/faac870f-cebd-4396-89c5-8101e8a5c17e and lastChanged/data has been updated.
      5. Query users:

      $ curl -s -u openidm-admin:openidm-admin -X GET http://localhost:8080/openidm/managed/user?_queryFilter=true | jq .
      {
        "result": [
          {
            "_id": "test",
            "_rev": "00000000f4e1e302",
            "userName": "test",
            "mail": "test@gmail.com",
            "sn": "foo",
            "givenName": "baz",
            "effectiveRoles": [],
            "effectiveAssignments": []
          }
        ],
        "resultCount": 1,
        "pagedResultsCookie": null,
        "totalPagedResultsPolicy": "NONE",
        "totalPagedResults": -1,
        "remainingPagedResults": -1
      }
      

      6. Query internal/usermeta:

      $ curl -s -u openidm-admin:openidm-admin -X GET http://localhost:8080/openidm/internal/usermeta?_queryFilter=true | jq .
      {
        "result": [
          {
            "_id": "faac870f-cebd-4396-89c5-8101e8a5c17e",
            "_rev": "000000001902748d",
            "createDate": "2019-05-06T22:07:38.433Z",
            "lastChanged": {
              "date": "2019-05-06T22:07:44.808Z"
            },
            "loginCount": 0
          },
          {
            "_id": "dade82c8-d41e-4ae5-a635-9c4a53588701",
            "_rev": "00000000d9ea5f4d",
            "createDate": "2019-05-06T22:07:44.752Z",
            "lastChanged": {
              "date": "2019-05-06T22:07:44.752Z"
            },
            "loginCount": 0
          }
        ],
        "resultCount": 2,
        "pagedResultsCookie": null,
        "totalPagedResultsPolicy": "NONE",
        "totalPagedResults": -1,
        "remainingPagedResults": -1
      }
      

      Note the extra record not attached to any user. It's lastChanged/date is after the original create, but before the update on the original meta record.

      This happens because we create the usermeta before attempting to create the user (which will fail).

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                naren.koganti Naren Koganti
                Reporter:
                mark.offutt Mark Offutt [X] (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: