CLOVER🍀

That was when it all began.

Infinispan Serverを組み込みでSpring Boot上で動かせるようにしてみた

Spring Bootの勉強を兼ねて、かなり誰特ですがInfinispan Serverの各種モードをSpring Boot上に組み込んで
動かせるようにしてみました。

ソースコードはこちら。
https://github.com/kazuhira-r/infinispan-embedded-server-spring-boot

動かせるプロトコルは、

で、動かせないのは

  • WebSocket

です。

有効化すると、アプリケーション内部でInfinispan Serverを起動します。この時、サーバーはNetty 4で
動くことになります。

使い方

インストールして

$ git clone https://github.com/kazuhira-r/infinispan-embedded-server-spring-boot.git
$ cd infinispan-embedded-server-spring-boot
$ mvn install -DskipTests=true

BOMを読み込んで

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.littlewings</groupId>
                <artifactId>infinispan-embedded-server-spring-boot-dependencies</artifactId>
                <version>0.1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

使いたいプロトコルに応じて、以下のいずれかを依存関係に加えます。

Hot Rod

        <dependency>
            <groupId>org.littlewings</groupId>
            <artifactId>infinispan-embedded-server-spring-boot-starter-hotrod</artifactId>
        </dependency>

Memcached

        <dependency>
            <groupId>org.littlewings</groupId>
            <artifactId>infinispan-embedded-server-spring-boot-starter-memcached</artifactId>
        </dependency>

Rest

        <dependency>
            <groupId>org.littlewings</groupId>
            <artifactId>infinispan-embedded-server-spring-boot-starter-rest</artifactId>
        </dependency>

追加したプロトコルに応じて、@Enable〜アノテーションを記述します。

Hot Rod

@EnableInfinispanEmbeddedHotRodServer
@SpringBootApplication
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }
}

Memcached

@EnableInfinispanEmbeddedMemcachedServer
@SpringBootApplication
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }
}

Rest

@EnableInfinispanEmbeddedRestServer
@SpringBootApplication
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }
}

全部合わせて使うこともできますが、EmbeddedCacheManagerは自分でBean定義する必要があります。
定義されたEmbeddedCacheManagerは、各サーバーに共有されます。
※以下のように書かなくても、別に設定ファイルを読み込ませる形でDefaultCacheManagerを作ってあげてもいいです

@EnableInfinispanEmbeddedHotRodServer
@EnableInfinispanEmbeddedMemcachedServer
@EnableInfinispanEmbeddedRestServer
@SpringBootApplication
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }

    @Bean
    public EmbeddedCacheManager embeddedCacheManager(InfinispanEmbeddedHotRodServerProperties hotRodServerProperties,
                                                     InfinispanEmbeddedMemcachedServerProperties memcachedServerProperties,
                                                     InfinispanEmbeddedRestServerProperties restServerProperties) {
        EmbeddedCacheManager cacheManager = new DefaultCacheManager(new ConfigurationBuilder().build());

        Set<String> cacheNames =
                Arrays
                        .asList(hotRodServerProperties.getCacheNames(),
                                memcachedServerProperties.getCacheNames(),
                                restServerProperties.getCacheNames())
                        .stream()
                        .filter(c -> c != null)
                        .flatMap(c -> c.stream())
                        .collect(Collectors.toSet());

        cacheNames.forEach(cacheName -> cacheManager.defineConfiguration(cacheName, new ConfigurationBuilder().build()));

        return cacheManager;
    }
}

この場合Nettyサーバープロトコル別に起動します。

一応、設定もほどほどにできるようになっています。SSLや認証以外は、ProtocolServerConfigurationBuilderで設定できるものが
ほぼ設定可能です。

infinispan.embedded.server.hotrod.default-cache-name=
infinispan.embedded.server.hotrod.port=
...

infinispan.embedded.server.memcached.default-cache-name=
infinispan.embedded.server.memcached.port=
...

infinispan.embedded.server.rest.cache-names=
infinispan.embedded.server.rest.port=
...

Infinispan Serverの起動/停止

SmartLifecycleというインターフェースを実装することで、実現しています。このあたりは、Spring Cloud Netflix
Eureka Serverの使い方を参考にしました。

あとは、@ConditionalOnMissingBeanなどを使いつつ、Infinispan Serverをある程度自動で組み上げて実行するようにしています。

なお、使っているInfinispanのバージョンは、クラスの階層関係の都合上しれっと9.0.0.CR1を使っています…。

まとめ

実は、はじめはAutoConfigurationを作るつもりだったのですが、途中で@Enable〜なアノテーションをつける形にするように
気が変わったので、こんな感じになりました。

いろいろ勉強になりました。けっこう面白かったです。