Blueriq provides IExternalFlowStore interface which can be used to interact with a generic datastore. A default implementation is already provided in the Blueriq External Flow Component. If other datastore implementation is desired the following have to be done:
- Add the
blueriq-component-api
to the project dependencies.
<project ...>
...
<dependencies>
...
<dependency>
<groupId>com.blueriq</groupId>
<artifactId>blueriq-component-api</artifactId>
<version>${blueriq.version}</version>
</dependency>
...
</dependencies>
...
</project>
- Define the custom implementation like below:
package ...;
import com.blueriq.component.api.store.externalflow.IExternalFlowStore;
// other imports ...
@Component
public class CustomExternalFlowStore implements IExternalFlowStore {
@Override
public void delete(String key)
throws ExternalFlowStoreException, IllegalArgumentException {
// add implementation here
}
@Override
public <T extends Serializable> T get(String key, Class<T> valueType)
throws ExternalFlowStoreException, IllegalArgumentException {
// add implementation here
return null;
}
@Override
public boolean hasKey(String key)
throws ExternalFlowStoreException, IllegalArgumentException {
// add implementation here
return false;
}
@Override
public void set(String key, Serializable value)
throws ExternalFlowStoreException, IllegalArgumentException {
// add implementation here
}
}
Example Hazelcast Datastore
Here is a example Hazelcast implementation of the datastore.
Adding the dependencies
The following dependencies are required in the pom.xml
<project ...>
...
<dependencies>
...
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-all</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.blueriq</groupId>
<artifactId>blueriq-component-api</artifactId>
<version>${blueriq.version}</version>
</dependency>
...
<dependencies>
...
</project>
Implementing the IExternalFlowStore Interface
package ...;
import com.blueriq.component.api.store.externalflow.IExternalFlowStore;
// other imports ...
@Component
public class HazelcastExternalFlowStore implements IExternalFlowStore {
private final IMap<String, Serializable> map;
public HazelcastExternalFlowStore() {
ClientConfig config = new ClientConfig();
// configure Hazelcast properties here
HazelcastInstance hazelcastInstance
= HazelcastClient.newHazelcastClient(config);
map = hazelcastInstance.getMap("blueriq");
}
@Override
public void delete(String key)
throws ExternalFlowStoreException, IllegalArgumentException {
if (isInvalid(key)) {
throw new IllegalArgumentException("Invalid key.");
}
try {
map.delete(key);
} catch (Exception e) {
throw new ExternalFlowStoreException("Something went wrong", e);
}
}
@Override
public <T extends Serializable> T get(String key, Class<T> valueType)
throws ExternalFlowStoreException, IllegalArgumentException {
if (isInvalid(key)) {
throw new IllegalArgumentException("Invalid key.");
}
try {
Serializable storedValue = map.get(key);
if (storedValue == null) {
return null;
}
if (valueType.isInstance(storedValue)) {
return valueType.cast(storedValue);
}
throw new IllegalArgumentException(
String.format("Cannot cast from %s to %s.",
storedValue.getClass(), valueType));
} catch (Exception e) {
throw new ExternalFlowStoreException("Something went wrong", e);
}
}
@Override
public boolean hasKey(String key)
throws ExternalFlowStoreException, IllegalArgumentException {
if (isInvalid(key)) {
throw new IllegalArgumentException("Invalid key.");
}
try {
return map.get(key) != null;
} catch (Exception e) {
throw new ExternalFlowStoreException("Something went wrong", e);
}
}
@Override
public void set(String key, Serializable value)
throws ExternalFlowStoreException, IllegalArgumentException {
if (isInvalid(key)) {
throw new IllegalArgumentException("Invalid key.");
}
try {
map.set(key, value, 1, TimeUnit.MINUTES);
} catch (Exception e) {
throw new ExternalFlowStoreException("Something went wrong", e);
}
}
private boolean isInvalid(String key) {
// define what an invalid key means
return false;
}
}