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

Backport OPENIDM-9966: NullPointerException returned when creating a relationship using the source managed object's attribute within the URI and specifying a _fields parameter

    Details

      Description

      When creating a relationship directly against a managed object's attribute and specifying a _fields parameter, a NullPointerException is returned in the response payload.

      Re-production:

      • OpenIDM 5.0.0 or 5.5.0
      • Add the following to managed.json:
              {
                  "name" : "Group",
                  "schema" : {
                      "$schema" : "http://forgerock.org/json-schema#",
                      "type" : "object",
                      "title" : "Group",
                      "description" : "User Group",
                      "icon" : "fa-group",
                      "properties" : {
                          "name" : {
                              "description" : "Group Name",
                              "title" : "Name",
                              "viewable" : true,
                              "searchable" : true,
                              "userEditable" : true,
                              "policies" : [
                                  {
                                      "policyId" : "unique",
                                      "params" : { }
                                  }
                              ],
                              "returnByDefault" : true,
                              "minLength" : null,
                              "pattern" : "",
                              "type" : "string"
                          },
                          "groupMembers" : {
                              "description" : "List of groups, which are members of the owning (this) group",
                              "title" : "Group Members",
                              "viewable" : true,
                              "searchable" : false,
                              "userEditable" : false,
                              "policies" : [ ],
                              "returnByDefault" : true,
                              "minLength" : null,
                              "pattern" : "",
                              "type" : "array",
                              "items" : {
                                  "type" : "relationship",
                                  "reverseRelationship" : true,
                                  "reversePropertyName" : "groupMembership",
                                  "validate" : true,
                                  "properties" : {
                                      "_ref" : {
                                          "type" : "string"
                                      },
                                      "_refProperties" : {
                                          "type" : "object",
                                          "properties" : {
                                              "_id" : {
                                                  "type" : "string",
                                                  "label" : ""
                                              },
                                              "status" : {
                                                  "type" : "string",
                                                  "label" : "Status"
                                              },
                                              "lastModifiedBy" : {
                                                  "type" : "string",
                                                  "label" : "Last Modified By"
                                              }
                                          }
                                      }
                                  },
                                  "resourceCollection" : [
                                      {
                                          "path" : "managed/Group",
                                          "label" : "Group",
                                          "query" : {
                                              "queryFilter" : "",
                                              "fields" : [
                                                  "name"
                                              ],
                                              "sortKeys" : [
                                                  "name"
                                              ]
                                          }
                                      }
                                  ]
                              }
                          },
                          "groupMembership" : {
                              "description" : "List of groups, in which the owning (this) group is member of",
                              "title" : "Member in Groups",
                              "viewable" : true,
                              "searchable" : false,
                              "userEditable" : false,
                              "policies" : [ ],
                              "returnByDefault" : true,
                              "minLength" : null,
                              "pattern" : "",
                              "type" : "array",
                              "items" : {
                                  "type" : "relationship",
                                  "reverseRelationship" : true,
                                  "reversePropertyName" : "groupMembers",
                                  "validate" : true,
                                  "properties" : {
                                      "_ref" : {
                                          "type" : "string"
                                      },
                                      "_refProperties" : {
                                          "type" : "object",
                                          "properties" : {
                                              "_id" : {
                                                  "type" : "string",
                                                  "label" : ""
                                              },
                                              "status" : {
                                                  "type" : "string",
                                                  "label" : "Status"
                                              },
                                              "lastModifiedBy" : {
                                                  "type" : "string",
                                                  "label" : "Last Modified By"
                                              }
                                          }
                                      }
                                  },
                                  "resourceCollection" : [
                                      {
                                          "path" : "managed/Group",
                                          "label" : "Group",
                                          "query" : {
                                              "queryFilter" : "",
                                              "fields" : [
                                                  "name"
                                              ],
                                              "sortKeys" : [
                                                  "name"
                                              ]
                                          }
                                      }
                                  ]
                              }
                          }
                      },
                      "required" : [ ],
                      "order" : [
                          "name",
                          "groupMembers",
                          "groupMembership"
                        ]
                  },
                  "iconClass" : "fa fa-database",
                  "type" : "Managed Object"
              }
      
      • Start OpenIDM (No Samples, Any Repo)
      • Create two new groups, 'firstGroup' and 'secondGroup'
      • Perform the following REST request and substitute the _id value for the firstGroup in to the URI and secondGroup in to the payload:
      POST http://localhost:8080/openidm/managed/Group/4eca496b-3499-4faf-b550-ab37683bf64a/groupMembers?_action=create&_fields=_ref
      
      {"_ref":"managed/Group/6a13ff26-65cf-4903-a10b-e081ca15e488"}
      
      {"code":500,"reason":"Internal Server Error","message":"Internal Server Error"}
      
      org.forgerock.openidm.servlet.internal.ServletConnectionFactory$3 handleException
      WARNING: Resource exception: 500 Internal Server Error: "Internal Server Error"
      org.forgerock.json.resource.InternalServerErrorException: Internal Server Error
      	at org.forgerock.openidm.managed.RelationshipProvider.createInstance(RelationshipProvider.java:433)
      	at org.forgerock.json.resource.InterfaceCollectionHandler.handleCreate(InterfaceCollectionHandler.java:32)
      	at org.forgerock.json.resource.Router.handleCreate(Router.java:264)
      	at org.forgerock.json.resource.Router.handleCreate(Router.java:264)
      	at org.forgerock.openidm.managed.ManagedObjectService$ManagedObjectSetRequestHandler.handleCreate(ManagedObjectService.java:177)
      	at org.forgerock.json.resource.Router.handleCreate(Router.java:264)
      	at org.forgerock.openidm.managed.ManagedObjectService.handleCreate(ManagedObjectService.java:300)
      	at org.forgerock.json.resource.Router.handleCreate(Router.java:264)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:65)
      	at org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:54)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.filter.ScriptedFilter$2.apply(ScriptedFilter.java:96)
      	at org.forgerock.openidm.filter.ScriptedFilter$2.apply(ScriptedFilter.java:93)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:247)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:236)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:215)
      	at org.forgerock.openidm.filter.ScriptedFilter.filterRequest(ScriptedFilter.java:182)
      	at org.forgerock.openidm.filter.ScriptedFilter.filterCreate(ScriptedFilter.java:92)
      	at org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:52)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.filter.ScriptedFilter$2.apply(ScriptedFilter.java:96)
      	at org.forgerock.openidm.filter.ScriptedFilter$2.apply(ScriptedFilter.java:93)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:247)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:236)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:215)
      	at org.forgerock.openidm.filter.ScriptedFilter.filterRequest(ScriptedFilter.java:182)
      	at org.forgerock.openidm.filter.ScriptedFilter.filterCreate(ScriptedFilter.java:92)
      	at org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:52)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.audit.filter.AuditFilter$2.apply(AuditFilter.java:142)
      	at org.forgerock.openidm.audit.filter.AuditFilter$2.apply(AuditFilter.java:139)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:247)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:236)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:215)
      	at org.forgerock.openidm.audit.filter.AuditFilter.logAuditAccessEntry(AuditFilter.java:247)
      	at org.forgerock.openidm.audit.filter.AuditFilter.filterCreate(AuditFilter.java:138)
      	at org.forgerock.openidm.filter.MutableFilterDecorator.filterCreate(MutableFilterDecorator.java:72)
      	at org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:52)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.servlet.internal.ServletConnectionFactory$4.filterCreate(ServletConnectionFactory.java:441)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.filter.PassthroughFilter.filterCreate(PassthroughFilter.java:48)
      	at org.forgerock.openidm.filter.MutableFilterDecorator.filterCreate(MutableFilterDecorator.java:72)
      	at org.forgerock.openidm.filter.MutableFilterDecorator.filterCreate(MutableFilterDecorator.java:72)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.openidm.filter.PassthroughFilter.filterCreate(PassthroughFilter.java:48)
      	at org.forgerock.openidm.filter.MutableFilterDecorator.filterCreate(MutableFilterDecorator.java:72)
      	at org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:63)
      	at org.forgerock.json.resource.FilterChain.handleCreate(FilterChain.java:228)
      	at org.forgerock.json.resource.InternalConnection.createAsync(InternalConnection.java:40)
      	at org.forgerock.json.resource.AbstractConnectionWrapper.createAsync(AbstractConnectionWrapper.java:101)
      	at org.forgerock.openidm.servlet.internal.ServletConnectionFactory$1$1.createAsync(ServletConnectionFactory.java:224)
      	at org.forgerock.json.resource.http.RequestRunner.visitCreateRequest(RequestRunner.java:175)
      	at org.forgerock.json.resource.http.RequestRunner.visitCreateRequest(RequestRunner.java:87)
      	at org.forgerock.json.resource.Requests$CreateRequestImpl.accept(Requests.java:250)
      	at org.forgerock.json.resource.http.RequestRunner.handleResult(RequestRunner.java:133)
      	at org.forgerock.json.resource.http.HttpAdapter$1.apply(HttpAdapter.java:717)
      	at org.forgerock.json.resource.http.HttpAdapter$1.apply(HttpAdapter.java:714)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:247)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:236)
      	at org.forgerock.json.resource.http.HttpAdapter.doRequest(HttpAdapter.java:713)
      	at org.forgerock.json.resource.http.HttpAdapter.doCreate(HttpAdapter.java:546)
      	at org.forgerock.json.resource.http.HttpAdapter.handle(HttpAdapter.java:273)
      	at org.forgerock.http.handler.Handlers$HandlerDescribableAsDescribableHandler.handle(Handlers.java:146)
      	at org.forgerock.http.filter.OptionsFilter.filter(OptionsFilter.java:69)
      	at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
      	at org.forgerock.http.swagger.OpenApiRequestFilter.filter(OpenApiRequestFilter.java:62)
      	at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework.grantAccess(AuthenticationFramework.java:193)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework.access$200(AuthenticationFramework.java:56)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework$2.apply(AuthenticationFramework.java:185)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework$2.apply(AuthenticationFramework.java:178)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:247)
      	at org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:236)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework.validateRequest(AuthenticationFramework.java:141)
      	at org.forgerock.caf.authentication.framework.AuthenticationFramework.processMessage(AuthenticationFramework.java:133)
      	at org.forgerock.caf.authentication.framework.AuthenticationFilter.filter(AuthenticationFilter.java:84)
      	at org.forgerock.openidm.auth.AuthFilterWrapper.filter(AuthFilterWrapper.java:82)
      	at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
      	at org.forgerock.http.filter.TransactionIdInboundFilter.filter(TransactionIdInboundFilter.java:52)
      	at org.forgerock.http.handler.Handlers$1.handle(Handlers.java:53)
      	at org.forgerock.http.servlet.HttpFrameworkServlet.service(HttpFrameworkServlet.java:236)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
      	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
      	at org.eclipse.jetty.servlets.CrossOriginFilter.handle(CrossOriginFilter.java:257)
      	at org.eclipse.jetty.servlets.CrossOriginFilter.doFilter(CrossOriginFilter.java:220)
      	at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.forgerock.openidm.servletregistration.impl.ServletRegistrationSingleton$FilterProxy.invoke(ServletRegistrationSingleton.java:283)
      	at com.sun.proxy.$Proxy35.doFilter(Unknown Source)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
      	at org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83)
      	at org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:301)
      	at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at org.forgerock.openidm.servletregistration.impl.ServletRegistrationSingleton$FilterProxy.invoke(ServletRegistrationSingleton.java:283)
      	at com.sun.proxy.$Proxy35.doFilter(Unknown Source)
      	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
      	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
      	at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
      	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
      	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
      	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
      	at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:276)
      	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
      	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
      	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
      	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
      	at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)
      	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
      	at org.eclipse.jetty.server.Server.handle(Server.java:499)
      	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
      	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
      	at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
      	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
      	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
      	at java.lang.Thread.run(Thread.java:748)
      Caused by: java.lang.NullPointerException
      	at org.forgerock.openidm.managed.RelationshipProvider$2.apply(RelationshipProvider.java:207)
      	at org.forgerock.openidm.managed.RelationshipProvider$2.apply(RelationshipProvider.java:194)
      	at org.forgerock.openidm.managed.RelationshipProvider$1.apply(RelationshipProvider.java:155)
      	at org.forgerock.openidm.managed.RelationshipProvider$1.apply(RelationshipProvider.java:152)
      	at org.forgerock.util.promise.Promises$CompletedPromise.then(Promises.java:182)
      	at org.forgerock.util.promise.Promises$CompletedPromise.then(Promises.java:171)
      	at org.forgerock.util.promise.Promises$CompletedPromise.then(Promises.java:152)
      	at org.forgerock.openidm.managed.RelationshipProvider.createInstance(RelationshipProvider.java:418)
      	... 120 more
      
      • Confirm that the relationship has been created:
      {
          "result": [
              {
                  "_id": "4eca496b-3499-4faf-b550-ab37683bf64a",
                  "_rev": "0",
                  "name": "firstGroup",
                  "groupMembers": [
                      {
                          "_ref": "managed/Group/6a13ff26-65cf-4903-a10b-e081ca15e488",
                          "_refProperties": {
                              "_id": "9ad74a20-b376-4625-b108-6d1f90c96a1f",
                              "_rev": "0"
                          }
                      }
                  ],
                  "groupMembership": []
              },
              {
                  "_id": "6a13ff26-65cf-4903-a10b-e081ca15e488",
                  "_rev": "0",
                  "name": "secondGroup",
                  "groupMembers": [],
                  "groupMembership": [
                      {
                          "_ref": "managed/Group/4eca496b-3499-4faf-b550-ab37683bf64a",
                          "_refProperties": {
                              "_id": "9ad74a20-b376-4625-b108-6d1f90c96a1f",
                              "_rev": "0"
                          }
                      }
                  ]
              }
          ],
          "resultCount": 2,
          "pagedResultsCookie": null,
          "totalPagedResultsPolicy": "NONE",
          "totalPagedResults": -1,
          "remainingPagedResults": -1
      }
      

      The same request without specifying a _fields parameter in the URI completes as expected:

      POST http://localhost:8080/openidm/managed/Group/4eca496b-3499-4faf-b550-ab37683bf64a/groupMembers?_action=create
      
      {"_ref":"managed/Group/6a13ff26-65cf-4903-a10b-e081ca15e488"}
      
      {
        "_ref": "managed/Group/6a13ff26-65cf-4903-a10b-e081ca15e488",
        "_refProperties": {
          "_id": "264400bf-1f0f-49eb-876c-abd43e52c11d",
          "_rev": "0"
        }
      }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                mark.offutt Mark Offutt
                Reporter:
                mark.offutt Mark Offutt
                QA Assignee:
                Jakub Janoska
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: