keycloak
公開メンバ関数 | 静的公開変数類 | 限定公開メンバ関数 | 限定公開変数類 | 非公開メンバ関数 | 非公開変数類 | 全メンバ一覧
org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity > クラステンプレート
org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity > の継承関係図
Inheritance graph
org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity > 連携図
Collaboration graph

公開メンバ関数

 InfinispanChangelogBasedTransaction (KeycloakSession kcSession, Cache< K, SessionEntityWrapper< V >> cache, RemoteCacheInvoker remoteCacheInvoker)
 
void addTask (K key, SessionUpdateTask< V > task)
 
void addTask (K key, SessionUpdateTask< V > task, V entity)
 
void reloadEntityInCurrentTransaction (RealmModel realm, K key, SessionEntityWrapper< V > entity)
 
SessionEntityWrapper< V > get (K key)
 
void begin ()
 
void commit ()
 
void rollback ()
 
void setRollbackOnly ()
 
boolean getRollbackOnly ()
 
boolean isActive ()
 
TransactionState getState ()
 

静的公開変数類

static final Logger logger = Logger.getLogger(InfinispanChangelogBasedTransaction.class)
 

限定公開メンバ関数

void commitImpl ()
 
void rollbackImpl ()
 

限定公開変数類

TransactionState state = TransactionState.NOT_STARTED
 

非公開メンバ関数

void runOperationInCluster (K key, MergedUpdate< V > task, SessionEntityWrapper< V > sessionWrapper)
 
void replace (K key, MergedUpdate< V > task, SessionEntityWrapper< V > oldVersionEntity)
 
SessionEntityWrapper< V > generateNewVersionAndWrapEntity (V entity, Map< String, String > localMetadata)
 

非公開変数類

final KeycloakSession kcSession
 
final String cacheName
 
final Cache< K, SessionEntityWrapper< V > > cache
 
final RemoteCacheInvoker remoteCacheInvoker
 
final Map< K, SessionUpdatesList< V > > updates = new HashMap<>()
 

詳解

著者
Marek Posolda

構築子と解体子

◆ InfinispanChangelogBasedTransaction()

49  {
50  this.kcSession = kcSession;
51  this.cacheName = cache.getName();
52  this.cache = cache;
54  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
final RemoteCacheInvoker remoteCacheInvoker
Definition: InfinispanChangelogBasedTransaction.java:45
final KeycloakSession kcSession
Definition: InfinispanChangelogBasedTransaction.java:42
final String cacheName
Definition: InfinispanChangelogBasedTransaction.java:43

関数詳解

◆ addTask() [1/2]

57  {
58  SessionUpdatesList<V> myUpdates = updates.get(key);
59  if (myUpdates == null) {
60  // Lookup entity from cache
61  SessionEntityWrapper<V> wrappedEntity = cache.get(key);
62  if (wrappedEntity == null) {
63  logger.warnf("Not present cache item for key %s", key);
64  return;
65  }
66 
67  RealmModel realm = kcSession.realms().getRealm(wrappedEntity.getEntity().getRealmId());
68 
69  myUpdates = new SessionUpdatesList<>(realm, wrappedEntity);
70  updates.put(key, myUpdates);
71  }
72 
73  // Run the update now, so reader in same transaction can see it (TODO: Rollback may not work correctly. See if it's an issue..)
74  task.runUpdate(myUpdates.getEntityWrapper().getEntity());
75  myUpdates.add(task);
76  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
static final Logger logger
Definition: InfinispanChangelogBasedTransaction.java:40
final KeycloakSession kcSession
Definition: InfinispanChangelogBasedTransaction.java:42
RealmModel getRealm(String id)
final Map< K, SessionUpdatesList< V > > updates
Definition: InfinispanChangelogBasedTransaction.java:47

◆ addTask() [2/2]

void org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.addTask ( key,
SessionUpdateTask< V >  task,
entity 
)
inline
80  {
81  if (entity == null) {
82  throw new IllegalArgumentException("Null entity not allowed");
83  }
84 
85  RealmModel realm = kcSession.realms().getRealm(entity.getRealmId());
86  SessionEntityWrapper<V> wrappedEntity = new SessionEntityWrapper<>(entity);
87  SessionUpdatesList<V> myUpdates = new SessionUpdatesList<>(realm, wrappedEntity);
88  updates.put(key, myUpdates);
89 
90  // Run the update now, so reader in same transaction can see it
91  task.runUpdate(entity);
92  myUpdates.add(task);
93  }
final KeycloakSession kcSession
Definition: InfinispanChangelogBasedTransaction.java:42
RealmModel getRealm(String id)
final Map< K, SessionUpdatesList< V > > updates
Definition: InfinispanChangelogBasedTransaction.java:47

◆ begin()

void org.keycloak.models.AbstractKeycloakTransaction.begin ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

34  {
35  if (state != TransactionState.NOT_STARTED) {
36  throw new IllegalStateException("Transaction already started");
37  }
38 
39  state = TransactionState.STARTED;
40  }
STARTED
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31
NOT_STARTED
Definition: AbstractKeycloakTransaction.java:84

◆ commit()

void org.keycloak.models.AbstractKeycloakTransaction.commit ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

43  {
44  if (state != TransactionState.STARTED) {
45  throw new IllegalStateException("Transaction in illegal state for commit: " + state);
46  }
47 
48  commitImpl();
49 
50  state = TransactionState.FINISHED;
51  }
STARTED
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31
FINISHED
Definition: AbstractKeycloakTransaction.java:84

◆ commitImpl()

147  {
148  for (Map.Entry<K, SessionUpdatesList<V>> entry : updates.entrySet()) {
149  SessionUpdatesList<V> sessionUpdates = entry.getValue();
150  SessionEntityWrapper<V> sessionWrapper = sessionUpdates.getEntityWrapper();
151 
152  RealmModel realm = sessionUpdates.getRealm();
153 
154  MergedUpdate<V> merged = MergedUpdate.computeUpdate(sessionUpdates.getUpdateTasks(), sessionWrapper);
155 
156  if (merged != null) {
157  // Now run the operation in our cluster
158  runOperationInCluster(entry.getKey(), merged, sessionWrapper);
159 
160  // Check if we need to send message to second DC
161  remoteCacheInvoker.runTask(kcSession, realm, cacheName, entry.getKey(), merged, sessionWrapper);
162  }
163  }
164  }
public< K, V extends SessionEntity > void runTask(KeycloakSession kcSession, RealmModel realm, String cacheName, K key, SessionUpdateTask< V > task, SessionEntityWrapper< V > sessionWrapper)
Definition: RemoteCacheInvoker.java:60
final RemoteCacheInvoker remoteCacheInvoker
Definition: InfinispanChangelogBasedTransaction.java:45
final KeycloakSession kcSession
Definition: InfinispanChangelogBasedTransaction.java:42
final String cacheName
Definition: InfinispanChangelogBasedTransaction.java:43
final Map< K, SessionUpdatesList< V > > updates
Definition: InfinispanChangelogBasedTransaction.java:47
void runOperationInCluster(K key, MergedUpdate< V > task, SessionEntityWrapper< V > sessionWrapper)
Definition: InfinispanChangelogBasedTransaction.java:167

◆ generateNewVersionAndWrapEntity()

SessionEntityWrapper<V> org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.generateNewVersionAndWrapEntity ( entity,
Map< String, String >  localMetadata 
)
inlineprivate
254  {
255  return new SessionEntityWrapper<>(localMetadata, entity);
256  }

◆ get()

117  {
118  SessionUpdatesList<V> myUpdates = updates.get(key);
119  if (myUpdates == null) {
120  SessionEntityWrapper<V> wrappedEntity = cache.get(key);
121  if (wrappedEntity == null) {
122  return null;
123  }
124 
125  RealmModel realm = kcSession.realms().getRealm(wrappedEntity.getEntity().getRealmId());
126 
127  myUpdates = new SessionUpdatesList<>(realm, wrappedEntity);
128  updates.put(key, myUpdates);
129 
130  return wrappedEntity;
131  } else {
132  V entity = myUpdates.getEntityWrapper().getEntity();
133 
134  // If entity is scheduled for remove, we don't return it.
135  boolean scheduledForRemove = myUpdates.getUpdateTasks().stream().filter((SessionUpdateTask task) -> {
136 
137  return task.getOperation(entity) == SessionUpdateTask.CacheOperation.REMOVE;
138 
139  }).findFirst().isPresent();
140 
141  return scheduledForRemove ? null : myUpdates.getEntityWrapper();
142  }
143  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
final KeycloakSession kcSession
Definition: InfinispanChangelogBasedTransaction.java:42
RealmModel getRealm(String id)
final Map< K, SessionUpdatesList< V > > updates
Definition: InfinispanChangelogBasedTransaction.java:47

◆ getRollbackOnly()

boolean org.keycloak.models.AbstractKeycloakTransaction.getRollbackOnly ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

70  {
71  return state == TransactionState.ROLLBACK_ONLY;
72  }
ROLLBACK_ONLY
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31

◆ getState()

TransactionState org.keycloak.models.AbstractKeycloakTransaction.getState ( )
inlineinherited
79  {
80  return state;
81  }
TransactionState state
Definition: AbstractKeycloakTransaction.java:31

◆ isActive()

boolean org.keycloak.models.AbstractKeycloakTransaction.isActive ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

75  {
76  return state == TransactionState.STARTED || state == TransactionState.ROLLBACK_ONLY;
77  }
STARTED
Definition: AbstractKeycloakTransaction.java:84
ROLLBACK_ONLY
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31

◆ reloadEntityInCurrentTransaction()

void org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.reloadEntityInCurrentTransaction ( RealmModel  realm,
key,
SessionEntityWrapper< V >  entity 
)
inline
96  {
97  if (entity == null) {
98  throw new IllegalArgumentException("Null entity not allowed");
99  }
100 
101  SessionEntityWrapper<V> latestEntity = cache.get(key);
102  if (latestEntity == null) {
103  return;
104  }
105 
106  SessionUpdatesList<V> newUpdates = new SessionUpdatesList<>(realm, latestEntity);
107 
108  SessionUpdatesList<V> existingUpdates = updates.get(key);
109  if (existingUpdates != null) {
110  newUpdates.setUpdateTasks(existingUpdates.getUpdateTasks());
111  }
112 
113  updates.put(key, newUpdates);
114  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
final Map< K, SessionUpdatesList< V > > updates
Definition: InfinispanChangelogBasedTransaction.java:47

◆ replace()

void org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.replace ( key,
MergedUpdate< V >  task,
SessionEntityWrapper< V >  oldVersionEntity 
)
inlineprivate
207  {
208  boolean replaced = false;
209  int iteration = 0;
210  V session = oldVersionEntity.getEntity();
211 
212  while (!replaced && iteration < InfinispanUtil.MAXIMUM_REPLACE_RETRIES) {
213  iteration++;
214 
215  SessionEntityWrapper<V> newVersionEntity = generateNewVersionAndWrapEntity(session, oldVersionEntity.getLocalMetadata());
216 
217  // Atomic cluster-aware replace
218  replaced = CacheDecorators.skipCacheStore(cache).replace(key, oldVersionEntity, newVersionEntity);
219 
220  // Replace fail. Need to load latest entity from cache, apply updates again and try to replace in cache again
221  if (!replaced) {
222  if (logger.isDebugEnabled()) {
223  logger.debugf("Replace failed for entity: %s, old version %s, new version %s. Will try again", key, oldVersionEntity.getVersion(), newVersionEntity.getVersion());
224  }
225 
226  oldVersionEntity = cache.get(key);
227 
228  if (oldVersionEntity == null) {
229  logger.debugf("Entity %s not found. Maybe removed in the meantime. Replace task will be ignored", key);
230  return;
231  }
232 
233  session = oldVersionEntity.getEntity();
234 
235  task.runUpdate(session);
236  } else {
237  if (logger.isTraceEnabled()) {
238  logger.tracef("Replace SUCCESS for entity: %s . old version: %d, new version: %d", key, oldVersionEntity.getVersion(), newVersionEntity.getVersion());
239  }
240  }
241  }
242 
243  if (!replaced) {
244  logger.warnf("Failed to replace entity '%s' in cache '%s'", key, cache.getName());
245  }
246 
247  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
static final Logger logger
Definition: InfinispanChangelogBasedTransaction.java:40
SessionEntityWrapper< V > generateNewVersionAndWrapEntity(V entity, Map< String, String > localMetadata)
Definition: InfinispanChangelogBasedTransaction.java:254

◆ rollback()

void org.keycloak.models.AbstractKeycloakTransaction.rollback ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

54  {
55  if (state != TransactionState.STARTED && state != TransactionState.ROLLBACK_ONLY) {
56  throw new IllegalStateException("Transaction in illegal state for rollback: " + state);
57  }
58 
59  rollbackImpl();
60 
61  state = TransactionState.FINISHED;
62  }
STARTED
Definition: AbstractKeycloakTransaction.java:84
ROLLBACK_ONLY
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31
FINISHED
Definition: AbstractKeycloakTransaction.java:84

◆ rollbackImpl()

251  {
252  }

◆ runOperationInCluster()

void org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.runOperationInCluster ( key,
MergedUpdate< V >  task,
SessionEntityWrapper< V >  sessionWrapper 
)
inlineprivate
167  {
168  V session = sessionWrapper.getEntity();
169  SessionUpdateTask.CacheOperation operation = task.getOperation(session);
170 
171  // Don't need to run update of underlying entity. Local updates were already run
172  //task.runUpdate(session);
173 
174  switch (operation) {
175  case REMOVE:
176  // Just remove it
177  CacheDecorators.skipCacheStore(cache)
178  .getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES)
179  .remove(key);
180  break;
181  case ADD:
182  CacheDecorators.skipCacheStore(cache)
183  .getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES)
184  .put(key, sessionWrapper, task.getLifespanMs(), TimeUnit.MILLISECONDS);
185  break;
186  case ADD_IF_ABSENT:
187  SessionEntityWrapper<V> existing = CacheDecorators.skipCacheStore(cache).putIfAbsent(key, sessionWrapper);
188  if (existing != null) {
189  logger.debugf("Existing entity in cache for key: %s . Will update it", key);
190 
191  // Apply updates on the existing entity and replace it
192  task.runUpdate(existing.getEntity());
193 
194  replace(key, task, existing);
195  }
196  break;
197  case REPLACE:
198  replace(key, task, sessionWrapper);
199  break;
200  default:
201  throw new IllegalStateException("Unsupported state " + operation);
202  }
203 
204  }
final Cache< K, SessionEntityWrapper< V > > cache
Definition: InfinispanChangelogBasedTransaction.java:44
static final Logger logger
Definition: InfinispanChangelogBasedTransaction.java:40
void replace(K key, MergedUpdate< V > task, SessionEntityWrapper< V > oldVersionEntity)
Definition: InfinispanChangelogBasedTransaction.java:207

◆ setRollbackOnly()

void org.keycloak.models.AbstractKeycloakTransaction.setRollbackOnly ( )
inlineinherited

org.keycloak.models.KeycloakTransactionを実装しています。

65  {
66  state = TransactionState.ROLLBACK_ONLY;
67  }
ROLLBACK_ONLY
Definition: AbstractKeycloakTransaction.java:84
TransactionState state
Definition: AbstractKeycloakTransaction.java:31

メンバ詳解

◆ cache

◆ cacheName

◆ kcSession

◆ logger

final Logger org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction< K, V extends SessionEntity >.logger = Logger.getLogger(InfinispanChangelogBasedTransaction.class)
static

◆ remoteCacheInvoker

◆ state

TransactionState org.keycloak.models.AbstractKeycloakTransaction.state = TransactionState.NOT_STARTED
protectedinherited

◆ updates


このクラス詳解は次のファイルから抽出されました: