/** * Initializes a {@link JpaTokenStore} as specified through this Builder. * * @return a {@link JpaTokenStore} as specified through this Builder */ public JpaTokenStore build() { return new JpaTokenStore(this); }
/** * Instantiate a Builder to be able to create a {@link JpaTokenStore}. * <p> * The {@code claimTimeout} to a 10 seconds duration, and {@code nodeId} is defaulted to the name of the managed * bean for the runtime system of the Java virtual machine. The {@link EntityManagerProvider} and {@link Serializer} * are a <b>hard requirements</b> and as such should be provided. * * @return a Builder to be able to create a {@link JpaTokenStore} */ public static Builder builder() { return new Builder(); }
/** * Sets the {@code nodeId} to identify ownership of the tokens. Defaults to the name of the managed bean for * the runtime system of the Java virtual machine * * @param nodeId the id as a {@link String} to identify ownership of the tokens * @return the current Builder instance, for fluent interfacing */ public Builder nodeId(String nodeId) { assertNodeId(nodeId, "The nodeId may not be null or empty"); this.nodeId = nodeId; return this; }
/** * Loads an existing {@link TokenEntry} or creates a new one using the given {@code entityManager} for given {@code * processorName} and {@code segment}. * * @param processorName the name of the event processor * @param segment the segment of the event processor * @param entityManager the entity manager instance to use for the query * @return the token entry for the given processor name and segment * @throws UnableToClaimTokenException if there is a token for given {@code processorName} and {@code segment}, but * it is claimed by another process. */ protected TokenEntry loadOrCreateToken(String processorName, int segment, EntityManager entityManager) { TokenEntry token = entityManager .find(TokenEntry.class, new TokenEntry.PK(processorName, segment), loadingLockMode); if (token == null) { token = new TokenEntry(processorName, segment, null, serializer); token.claim(nodeId, claimTimeout); entityManager.persist(token); // hibernate complains about updates in different transactions if this isn't flushed entityManager.flush(); } else if (!token.claim(nodeId, claimTimeout)) { throw new UnableToClaimTokenException( format("Unable to claim token '%s[%s]'. It is owned by '%s'", token.getProcessorName(), token.getSegment(), token.getOwner())); } return token; }
@ConditionalOnMissingBean @Bean public TokenStore tokenStore(Serializer serializer, EntityManagerProvider entityManagerProvider) { return JpaTokenStore.builder() .entityManagerProvider(entityManagerProvider) .serializer(serializer) .build(); }
@Override public TrackingToken fetchToken(String processorName, int segment) { EntityManager entityManager = entityManagerProvider.getEntityManager(); return loadOrCreateToken(processorName, segment, entityManager).getToken(serializer); }
@Override public void storeToken(TrackingToken token, String processorName, int segment) { EntityManager entityManager = entityManagerProvider.getEntityManager(); TokenEntry tokenEntry = loadOrCreateToken(processorName, segment, entityManager); tokenEntry.updateToken(token, serializer); }
@Override public void initializeTokenSegments(String processorName, int segmentCount, TrackingToken initialToken) throws UnableToClaimTokenException { EntityManager entityManager = entityManagerProvider.getEntityManager(); if (fetchSegments(processorName).length > 0) { throw new UnableToClaimTokenException("Could not initialize segments. Some segments were already present."); } for (int segment = 0; segment < segmentCount; segment++) { TokenEntry token = new TokenEntry(processorName, segment, initialToken, serializer); entityManager.persist(token); } entityManager.flush(); }
@Override public void updateToken(TrackingToken token, Serializer serializer) { updateToken(token, serializer, byte[].class); }
@Override public void initializeTokenSegments(String processorName, int segmentCount) throws UnableToClaimTokenException { initializeTokenSegments(processorName, segmentCount, null); }
/** * Instantiate a {@link JpaTokenStore} based on the fields contained in the {@link Builder}. * <p> * Will assert that the {@link EntityManager}, {@link Serializer}, {@code claimTimeout} and {@code nodeId} are not * {@code null}, and will throw an {@link AxonConfigurationException} if any of them is {@code null}. * * @param builder the {@link Builder} used to instantiate a {@link JpaTokenStore} instance */ protected JpaTokenStore(Builder builder) { builder.validate(); this.entityManagerProvider = builder.entityManagerProvider; this.serializer = builder.serializer; this.claimTimeout = builder.claimTimeout; this.nodeId = builder.nodeId; this.loadingLockMode = builder.loadingLockMode; }
c -> JpaTokenStore.builder() .entityManagerProvider(c.getComponent(EntityManagerProvider.class)) .serializer(c.serializer()) .build()) .registerComponent(SagaStore.class, c -> JpaSagaStore.builder()
@Override public TrackingToken fetchToken(String processorName, int segment) { EntityManager entityManager = entityManagerProvider.getEntityManager(); return loadOrCreateToken(processorName, segment, entityManager).getToken(serializer); }
@Override public void storeToken(TrackingToken token, String processorName, int segment) { EntityManager entityManager = entityManagerProvider.getEntityManager(); TokenEntry tokenEntry = loadOrCreateToken(processorName, segment, entityManager); tokenEntry.updateToken(token, serializer); }
/** * Initializes a {@link JpaTokenStore} as specified through this Builder. * * @return a {@link JpaTokenStore} as specified through this Builder */ public JpaTokenStore build() { return new JpaTokenStore(this); }
@Override public void updateToken(TrackingToken token, Serializer serializer) { updateToken(token, serializer, byte[].class); }
/** * Validates whether the fields contained in this Builder are set accordingly. * * @throws AxonConfigurationException if one field is asserted to be incorrect according to the Builder's * specifications */ protected void validate() throws AxonConfigurationException { assertNonNull(entityManagerProvider, "The EntityManagerProvider is a hard requirement and should be provided"); assertNonNull(serializer, "The Serializer is a hard requirement and should be provided"); assertNodeId(nodeId, "The nodeId is a hard requirement and should be provided"); }
/** * Instantiate a Builder to be able to create a {@link JpaTokenStore}. * <p> * The {@code claimTimeout} to a 10 seconds duration, and {@code nodeId} is defaulted to the name of the managed * bean for the runtime system of the Java virtual machine. The {@link EntityManagerProvider} and {@link Serializer} * are a <b>hard requirements</b> and as such should be provided. * * @return a Builder to be able to create a {@link JpaTokenStore} */ public static Builder builder() { return new Builder(); }
@Override public TrackingToken fetchToken(String processorName, int segment) { EntityManager entityManager = entityManagerProvider.getEntityManager(); return loadOrCreateToken(processorName, segment, entityManager).getToken(serializer); }
/** * Sets the {@code nodeId} to identify ownership of the tokens. Defaults to the name of the managed bean for * the runtime system of the Java virtual machine * * @param nodeId the id as a {@link String} to identify ownership of the tokens * @return the current Builder instance, for fluent interfacing */ public Builder nodeId(String nodeId) { assertNodeId(nodeId, "The nodeId may not be null or empty"); this.nodeId = nodeId; return this; }