AM node script nodeState.putShared can't change the value set initially

I am using nodeState.putShared(“counter”, 1) in first scripted node and in second scripted node I get the value and increment it and put it back in nodeState.putShared(“counter”, 2).

However, I am expecting the last value set that is 2 when i do nodeState.get(“counter”) in any subsequent node but I get the initial value that is 1.

Tried to remove the variable from nodeState.remove(“counter”) but still does not help, it returns the first value set.

How to override/update the value set in nodeState.putShared() ?

1 Like

hi @vdl
As a workaround, you can replace nodeState.putShared(“counter”, 1) by sharedState.put(“counter”, 1).
regards,
Steph

3 Likes

FYI: IDCloud is to deprecate the bindings sharedState and transientState per OPENAM-17666.

Also, I would suggest printing out the value to logs to inspect what is going on. I do expect the counter to be updated. Also, please note, the get(key) method retrieves the state for the key from the NodeState in the following order: transient, secure, shared. So, if you have the same key in the transient state, the method returns the value from the transient state first.

2 Likes

Unfortunately, this looks like a bug. I also expected the counter would be updated, but using t.he putShared method seems to only work if the key is not already set

  • This is OPENAM-17868
  • But either see nodeState.remove(“…”) helps
  • Due to too much dependencies and already customization written, it is hard to fix w/o bounding the unknown impact of all enduser scripts. So in due cause the solution is to move slowly away from this deprecate usage.
1 Like

I’ve just been bitten by this. The LinkedHashMap that is stored in sharedState is a different object from the LinkedHashMap that is stored in the nodeState.sharedState.object:

var fr = JavaImporter(java.lang.System);

logger.message('sharedState: ' + sharedState.getClass().toString() + ":" + fr.System.identityHashCode(sharedState) );
// --> sharedState: class java.util.LinkedHashMap:1893723134

logger.message('nodeState: ' + nodeState.getClass().toString() );
// --> nodeState: class org.forgerock.openam.auth.node.api.NodeState

logger.message('nodeState.keys: ' + nodeState.keys().toString() );
// --> nodeState.keys: [oneTimePasswordTimestamp, oneTimePasswordAttempts, password, pageNodeCallbacks, maskedMobileNumber, forgeRock.device.profile, realm, authLevel, oneTimePassword, username]

logger.message('sharedState.keys: ' + sharedState.keySet().toString() );
// --> sharedState.keys: [realm, authLevel, pageNodeCallbacks, username, password, forgeRock.device.profile, oneTimePasswordAttempts]

var privateSharedStateField = nodeState.getClass().getDeclaredField("sharedState"); 
privateSharedStateField.setAccessible(true); 

var privateSharedState = privateSharedStateField.get(nodeState); 
logger.message('nodeState.sharedState: ' + privateSharedState.getClass().toString() );
// --> nodeState.sharedState: class org.forgerock.json.JsonValue

var jsonObjectField = privateSharedState.getClass().getDeclaredField("object");
jsonObjectField.setAccessible(true);
var jsonObject = jsonObjectField.get(privateSharedState)

logger.message('nodeState.sharedState.object: ' + jsonObject.getClass().toString() + ":" + fr.System.identityHashCode(jsonObject) );
// --> nodeState.sharedState.object: class java.util.LinkedHashMap:1960862013

logger.message('nodeState.sharedState.object.keys: ' + jsonObject.keySet().toString());
// --> nodeState.sharedState.object.keys: [realm, authLevel, pageNodeCallbacks, username, password, forgeRock.device.profile, oneTimePasswordAttempts]

When I try and update oneTimePasswordAttempts via nodeState.putShared('oneTimePasswordAttempts', newValue) it does not stick.