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

Infinite loop while attempting to create default config/sync object from within mappingDetails endpoint

    Details

      Description

      With the latest 4.0.0-SNAPSHOT build I can repeatedly reproduce a infinite loop within the RepoPersistenceManager while attempting to create the default config/sync object.

      Steps to reproduce the problem:

      1. Unzip a fresh installation of 4.0.0-SNAPSHOT
      2. Execute the ./startup.sh script to start the instance
      3. Within a Chrome incognito window, navigate to: https://localhost:8443/admin
      4. Log into the Admin console
      5. Immediately navigate from the Dashboard page to the 'Managed -> User' page
      6. Monitor the CPU usage on the machine. When the issue reproduces, you will quickly see the CPU usage for the JVM spike to >100%

      NOTE: The issue seems to be aggravated by timing. Therefore it may be necessary to attempt to reproduce the issue multiple times. Navigating quickly from the Dashboard page to the Managed -> User page also seems to be necessary.

      Thread dumps from the JVM when the issues occurs reveals that the problem is a result of the following loop within the RepoPersistenceManager.store() method:

                              boolean retry;
                              do {
                                  retry = false;
                                  try {
                                      UpdateRequest r = Requests.newUpdateRequest(id, new JsonValue(obj));
                                      r.setRevision(rev);
                                      repo.update(r);
                                  } catch (PreconditionFailedException ex) {
                                      logger.debug("Concurrent change during update, retrying {} {}", pid, rev);
                                      ReadRequest readRequest = Requests.newReadRequest(id);
                                      existing = repo.read(readRequest).getContent().asMap();
                                      retry = true;
                                  }
                              } while (retry);
      

      A PreConditionFailedException is being thrown while attempting to create the default config/sync object within the repository. The config/object is creating by the mappingDetails endpoint if it does not already exist.

      See the following thread from the dump:

      ame: qtp1230260295-95
      State: RUNNABLE
      Total blocked: 4,018  Total waited: 40
      
      Stack trace: 
      java.lang.Throwable.fillInStackTrace(Native Method)
      java.lang.Throwable.fillInStackTrace(Throwable.java:783)
         - locked com.orientechnologies.orient.core.exception.OConcurrentModificationException@3ec257f8
      java.lang.Throwable.<init>(Throwable.java:250)
      java.lang.Exception.<init>(Exception.java:54)
      java.lang.RuntimeException.<init>(RuntimeException.java:51)
      com.orientechnologies.common.exception.OException.<init>(OException.java:7)
      com.orientechnologies.common.concur.ONeedRetryException.<init>(ONeedRetryException.java:31)
      com.orientechnologies.orient.core.exception.OConcurrentModificationException.<init>(OConcurrentModificationException.java:73)
      com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage.updateRecord(OLocalPaginatedStorage.java:804)
      com.orientechnologies.orient.core.db.raw.ODatabaseRaw.save(ODatabaseRaw.java:277)
      com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.executeSaveRecord(ODatabaseRecordAbstract.java:1121)
      com.orientechnologies.orient.core.tx.OTransactionNoTx.saveRecord(OTransactionNoTx.java:84)
      com.orientechnologies.orient.core.db.record.ODatabaseRecordTx.save(ODatabaseRecordTx.java:322)
      com.orientechnologies.orient.core.db.record.ODatabaseRecordTx.save(ODatabaseRecordTx.java:40)
      com.orientechnologies.orient.core.record.ORecordAbstract.save(ORecordAbstract.java:335)
      com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:1439)
      com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:1428)
      com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:1417)
      org.forgerock.openidm.repo.orientdb.impl.OrientDBRepoService.update(OrientDBRepoService.java:358)
      org.forgerock.openidm.config.persistence.RepoPersistenceManager.store(RepoPersistenceManager.java:367)
      org.apache.felix.cm.impl.CachingPersistenceManagerProxy.store(CachingPersistenceManagerProxy.java:173)
      org.apache.felix.cm.impl.ConfigurationImpl.update(ConfigurationImpl.java:381)
      org.apache.felix.cm.impl.ConfigurationAdapter.update(ConfigurationAdapter.java:131)
      org.forgerock.openidm.config.manage.ConfigObjectService.create(ConfigObjectService.java:347)
      org.forgerock.openidm.config.manage.ConfigObjectService.handleCreate(ConfigObjectService.java:268)
      org.forgerock.json.resource.Router.handleCreate(Router.java:255)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:69)
      org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:62)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:62)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.openidm.servlet.internal.ScriptedFilter$2.apply(ScriptedFilter.java:96)
      org.forgerock.openidm.servlet.internal.ScriptedFilter$2.apply(ScriptedFilter.java:93)
      org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:200)
      org.forgerock.util.promise.Promises$CompletedPromise.thenAsync(Promises.java:184)
      org.forgerock.openidm.servlet.internal.ScriptedFilter.filterResourceResponseRequest(ScriptedFilter.java:167)
      org.forgerock.openidm.servlet.internal.ScriptedFilter.filterCreate(ScriptedFilter.java:92)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.openidm.audit.filter.AuditFilter.filterCreate(AuditFilter.java:110)
      org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:60)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.openidm.servlet.internal.ServletConnectionFactory$5.filterCreate(ServletConnectionFactory.java:494)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.openidm.maintenance.impl.PassthroughFilter.filterCreate(PassthroughFilter.java:48)
      org.forgerock.openidm.maintenance.impl.MaintenanceService.filterCreate(MaintenanceService.java:229)
      org.forgerock.json.resource.Filters$ConditionalFilter.filterCreate(Filters.java:60)
      org.forgerock.json.resource.FilterChain$Cursor.handleCreate(FilterChain.java:67)
      org.forgerock.json.resource.FilterChain.handleCreate(FilterChain.java:213)
      org.forgerock.json.resource.InternalConnection.createAsync(InternalConnection.java:44)
      org.forgerock.json.resource.AbstractAsynchronousConnection.create(AbstractAsynchronousConnection.java:44)
      org.forgerock.json.resource.AbstractConnectionWrapper.create(AbstractConnectionWrapper.java:96)
      org.forgerock.openidm.servlet.internal.ServletConnectionFactory$1$1.create(ServletConnectionFactory.java:175)
      org.forgerock.json.resource.AbstractConnectionWrapper.create(AbstractConnectionWrapper.java:96)
      org.forgerock.openidm.script.ResourceFunctions$CreateFunction.create(ResourceFunctions.java:185)
      org.forgerock.openidm.script.ResourceFunctions$CreateFunction.call(ResourceFunctions.java:169)
      org.forgerock.openidm.script.ResourceFunctions$CreateFunction.call(ResourceFunctions.java:83)
      org.forgerock.script.javascript.ScriptableFunction.call(ScriptableFunction.java:118)
      org.mozilla.javascript.optimizer.OptRuntime.callN(OptRuntime.java:52)
      org.mozilla.javascript.gen._Users_cgdrake_Projects_openidm_openidm_zip_target_openidm_bin_defaults_script_ui_mappingDetails_js_23._c_anonymous_1(/Users/cgdrake/Projects/openidm/openidm-zip/target/openidm/bin/defaults/script/ui/mappingDetails.js:31)
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                cgdrake Chris Drake
                Reporter:
                cgdrake Chris Drake
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: