Skip to content
Merged
2 changes: 1 addition & 1 deletion .github/workflows/voter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
fetch-depth: 0

- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v2
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: ${{ matrix.java }}
Expand Down
21 changes: 8 additions & 13 deletions src/main/java/io/neonbee/NeonBeeOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static io.neonbee.NeonBeeProfile.parseProfiles;
import static io.neonbee.cluster.ClusterManagerFactory.HAZELCAST_FACTORY;
import static io.neonbee.cluster.ClusterManagerFactory.INFINISPAN_FACTORY;
import static io.neonbee.internal.helper.StringHelper.EMPTY;
import static io.vertx.core.eventbus.EventBusOptions.DEFAULT_CLUSTER_PORT;
import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -226,6 +225,7 @@ default Path getLogDirectory() {
@Name("neonbee")
@Summary("A command line interface for starting and configuring a NeonBee and its associated Vert.x instance")
class Mutable implements NeonBeeOptions {

/**
* The default active profiles.
*/
Expand Down Expand Up @@ -639,8 +639,9 @@ public Mutable setActiveProfiles(Collection<NeonBeeProfile> profiles) {
@DefaultValue(DEFAULT_ACTIVE_PROFILES)
@Description("Set the active deployment profiles")
public Mutable setActiveProfiles(String... activeProfiles) {
return setActiveProfiles(Arrays.stream(activeProfiles).map(NeonBeeProfile::parseProfiles)
.flatMap(Collection::stream).collect(Collectors.toSet()));
return setActiveProfiles(
Arrays.stream(activeProfiles).map(NeonBeeProfile::parseProfiles).flatMap(Collection::stream)
.collect(Collectors.toSet()));
}

/**
Expand Down Expand Up @@ -720,8 +721,9 @@ public Mutable setModuleJarPaths(List<Path> moduleJarPaths) {
@Option(longName = "module-jar-paths", shortName = "mjp")
@Description("A list of path(s) to module JARs to be loaded during startup")
public Mutable setModuleJarPaths(String... moduleJarPaths) {
return this.setModuleJarPaths(Arrays.stream(moduleJarPaths).map(FileSystemHelper::parsePaths)
.flatMap(Collection::stream).toList());
return this.setModuleJarPaths(
Arrays.stream(moduleJarPaths).map(FileSystemHelper::parsePaths).flatMap(Collection::stream)
.toList());
}

@Override
Expand Down Expand Up @@ -755,14 +757,7 @@ public Path fromString(String s) {
class ClusterManagerFactoryConverter implements Converter<ClusterManagerFactory> {
@Override
public ClusterManagerFactory fromString(String s) {
if ("hazelcast".equalsIgnoreCase(s)) {
return HAZELCAST_FACTORY;
} else if ("infinispan".equalsIgnoreCase(s)) {
return INFINISPAN_FACTORY;
} else {
throw new IllegalArgumentException(
"Value for cluster-manager MUST be \"hazelcast\" or \"infinispan\".");
}
return ClusterManagerFactory.getFactory(s);
}
}
}
63 changes: 61 additions & 2 deletions src/main/java/io/neonbee/cluster/ClusterManagerFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;

import org.infinispan.manager.DefaultCacheManager;

Expand All @@ -17,12 +22,14 @@
import com.hazelcast.config.FileSystemXmlConfig;

import io.neonbee.NeonBeeOptions;
import io.neonbee.cluster.spi.ClusterManagerProvider;
import io.vertx.core.Future;
import io.vertx.core.spi.cluster.ClusterManager;
import io.vertx.ext.cluster.infinispan.InfinispanClusterManager;
import io.vertx.spi.cluster.hazelcast.HazelcastClusterManager;

public abstract class ClusterManagerFactory {

/**
* The ClusterManagerFactory for Hazelcast.
*/
Expand Down Expand Up @@ -56,7 +63,7 @@ public Future<ClusterManager> create(NeonBeeOptions neonBeeOptions) {
* check if the file exists on the classpath.
*
* @param effectiveConfigFileName the file name
* @return true if the file exists on the classpath, otherwise flase
* @return true if the file exists on the classpath, otherwise false
*/
private boolean exitsInClasspath(String effectiveConfigFileName) {
try (InputStream inputStream = getSystemClassLoader().getResourceAsStream(effectiveConfigFileName)) {
Expand Down Expand Up @@ -90,6 +97,58 @@ public Future<ClusterManager> create(NeonBeeOptions neonBeeOptions) {
}
};

private static final Map<String, ClusterManagerFactory> PROVIDERS = new HashMap<>();

static {
PROVIDERS.put("hazelcast", HAZELCAST_FACTORY);
PROVIDERS.put("infinispan", INFINISPAN_FACTORY);

ServiceLoader<ClusterManagerProvider> loader = ServiceLoader.load(
ClusterManagerProvider.class);

// add available providers
for (ClusterManagerProvider provider : loader) {
PROVIDERS.put(provider.getType(), new ClusterManagerFactory() {
@Override
protected String getDefaultConfig() {
return provider.getType();
}

@Override
public Future<ClusterManager> create(NeonBeeOptions options) {
return provider.create(options);
}
});
}
Comment thread
ikalachy marked this conversation as resolved.
}
Comment thread
ikalachy marked this conversation as resolved.

/**
* Get a cluster manager factory for the specified type.
*
* @param type the type of cluster manager factory to get
* @return the cluster manager factory
* @throws IllegalArgumentException if no provider is found for the specified type
*/
public static ClusterManagerFactory getFactory(String type) {
ClusterManagerFactory factory = PROVIDERS.get(type);
if (factory == null) {
throw new IllegalArgumentException(
"No cluster manager factory provider found for type: "
+ type
+ String.join(", ", PROVIDERS.keySet()));
}
return factory;
}

/**
* Get all available cluster manager factory types.
*
* @return a set of available cluster manager factory types
*/
public static Set<String> getAvailableTypes() {
return new HashSet<>(PROVIDERS.keySet());
}

/**
* Creates a new {@link ClusterManagerFactory}.
*/
Expand Down Expand Up @@ -131,10 +190,10 @@ static class SelfStoppingDefaultCacheManager extends DefaultCacheManager {
private Object clusterViewListener;

/**
* @see DefaultCacheManager#DefaultCacheManager(String, boolean)
* @param configurationFile name of configuration file to use as a template for all caches created
* @param start if true, the cache manager is started
* @throws java.io.IOException if there is a problem with the configuration file.
* @see DefaultCacheManager#DefaultCacheManager(String, boolean)
*/
SelfStoppingDefaultCacheManager(String configurationFile, boolean start) throws IOException {
super(configurationFile, start);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.neonbee.cluster.spi;

import io.neonbee.NeonBeeOptions;
import io.vertx.core.Future;
import io.vertx.core.spi.cluster.ClusterManager;

/**
* Service provider interface for cluster manager implementations. Implementations of this interface will be discovered
* via Java's ServiceLoader.
*/
public interface ClusterManagerProvider {
/**
* Get the type identifier for this cluster manager.
*
* @return the type identifier.
*/
String getType();

/**
* Create a new cluster manager instance.
*
* @param options The NeonBee options.
* @return a Future holding the created ClusterManager.
*/
Future<ClusterManager> create(NeonBeeOptions options);
}
Loading