The code you added seems unneeded.
The problem here is that we must agree on how the Server will invoke your Metadata Adapter.
When I said that "
you should rely on the Server to call notifySessionCloseand a new notifyNewSession to your Adapter", we were talking about what happens after you throw a
ConflictingSessionException. So, I mean that you should expect the Server code to behave like this:
try {
String newSessionID = createRandomString();
yourMetadataAdapter.notifyNewSession(user, newSessionId, sessionInfo);
} catch (ConflictingSessionException e) {
String existingSessionID = e.getConflictingSessionID();
yourMetadataAdapter.notifySessionClose(existingSessionID);
String differentSessionID = createRandomString();
yourMetadataAdapter.notifyNewSession(user, differentSessionId, sessionInfo);
}
As you can see, if you throw a
ConflictingSessionException, you will receive an invocation of
notifySessionClosefor the existing session to be closed and then a brand new invocation of
notifyNewSession .
Moreover, you should never expect
notifyNewSession to be invoked with a session ID already used, even in case of page refresh.
So, please stick to the original form:
assert (! sessions.containsKey(sessionID));
uniquelyIdentifyClient(sessionInfo);
if (userinfo.containsKey(user)) {
throw new ConflictingSessionException(-8, "Previous session termination", null, userinfo.get(user));
} else {
userinfo.put(user, sessionID);
sessions.put(sessionID, sessionInfo);
}
and focus now on
notifySessionClose. How do you implement it currently?
As I said previously, you should ensure that it undoes exactly all that was done in
notifyNewSession, which means removing the session line from both the "userinfo" and the "sessions" Map.