ããã¯ããªã«ãããããŠæžãããã®ïŒ
å æ¥ãInfinispan 14.0.0.FinalããªãªãŒã¹ãããŸããã
æŽæ°å 容ã®äžã«ãæ°ããHot Rod Clientãå«ãŸããŠãããšããã®ã§è©ŠããŠã¿ãŸããã
çµè«ããèšããšãçŸæç¹ã§ã¯åŸæ¥ã®Hot Rod Clientã䜿ã£ãŠããæ¹ãè¯ãããã§ãã
Infinispan 14.0.0.Finalã®æç¹ã§ãã®ããŒãžãèŠã人ã¯ãèªãã®ã¯ãããŸã§ã«ããŠãããæ¹ãç¡é£ããã§ããã
ãšã³ããªãŒèªäœãæžãã®ããããŠãããã£ãã®ã§ããããœãŒã¹ã³ãŒããããããèŠãã®ã§ãã£ãããªã®ã§æžãæ®ããŠãããŠä»åŸã®
ã¢ããããŒãæã«èŠè¿ããããªãšæããŸããŠã
ä¹
ãã¶ãã«Infinispanã®å€§ããã®æ°æ©èœã觊ã£ãŠããããããèžã¿æãããªãŒããšããæ°åã«ãªããŸãããåãã¡ããã¡ããèžãã§ããã®ã§ã
ããæãããæãã
æ°ããHot Rod Client
ãã¡ãã®ããã°ã«ã¯ãæ°ããHot Rod Clientã«ã€ããŠä»¥äžã®ããã«çŽ¹ä»ãããŠããŸãã
- å®å šã«åèšèšããæ°ããHot Rod Client
- ããã°ã©ãã³ã°ã¢ãã«ã¯ãåæãéåæãMutinyã®APIã®äžããéžæãã
ãµã³ãã«ã³ãŒãã¯ä»¥äžã®ããã«çŽ¹ä»ãããŠããŸãã
â»ééã£ãŠãããšããåããªããšããããããããã§ããâŠ
try (SyncContainer infinispan = Infinispan.create("hotrod://localhost")) { // Sync SyncCache<String, String> mycache = infinispan.sync().caches().get("mycache"); mycache.set("key", "value"); String value = mycache.get("key"); // set with options mycache.set("key", "anothervalue", writeOptions().lifespan(Duration.ofHours(1)).timeout(Duration.ofMillis(500)).build()); // Async infinispan.async().caches() .get("mycache").thenApply(c -> c.set("key", "value").thenApply(ignore -> c.get("key").thenApply(value -> c.set("key", "anothervalue", writeOptions().lifespan(Duration.ofHours(1)).timeout(Duration.ofMillis(500)).build())) )); // Mutiny infinispan.mutiny().caches() .get("mycache").map(c -> c.query("age > :age").param("age", 80).skip(5).limit(10).find()) .subscribe().with(System.out::println); }
æ°ããAPIã«ã€ããŠã¯ã14.0.0.Dev03ã®ãªãªãŒã¹æã«å°ã玹ä»ããããŸããã
ä»åã®Hot Rod Clientã«é¢ä¿ãããããªç¯å²ã¯ã以äžã§ããã
çŸæç¹ã§ã¯Hot Rod Clientåãã®å®è£
ã®ã¿ãåºãŠããŸããããã®ãã¡Embeddedã®æ¹ãæäŸããããã§ãããEmbeddedã¯Infinispan 15ã§ã®
ãªãªãŒã¹ãç®æšã«ããŠããããã§ãããã©ãã§ãããã
Infinispan 14.0ã®ããã¥ã¡ã³ãã®äžèŠ§ã¯ãã¡ããªã®ã§ãããæ°ããHot Rod Clientã«é¢ããæ å ±ã¯ãããŸããã
Infinispan 14.0 documentation index
Hot Rod Java Clientã®ããã¥ã¡ã³ãã¯ããããŸã§æ¢åã®Client APIã«é¢ãã説æã«ãªããŸãã
ãšããããã§ãä»åã¯å®è£ ãšããã°ã®å 容ãèŠã€ã€è©ŠããŠã¿ãããšæããŸãããªãããªãã¯æåã«æžããŸããã
æ°ããHot Rod Clientã®ã¢ãžã¥ãŒã«ã¯ãã¡ãã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/client/hotrod
ãã¹ãã³ãŒãã¯éåæçã®ã¿ããããŸãã
åŸæ¥ã®Hot Rod Clientã¯ãã¡ãã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/client/hotrod-client
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã
$ java --version openjdk 17.0.4 2022-07-19 OpenJDK Runtime Environment (build 17.0.4+8-Ubuntu-120.04) OpenJDK 64-Bit Server VM (build 17.0.4+8-Ubuntu-120.04, mixed mode, sharing) $ mvn --version Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 17.0.4, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-126-generic", arch: "amd64", family: "unix"
Infinispan Serverã¯ã172.17.0.2ã§åäœããŠãããã®ãšããŸãã
$ java --version openjdk 17.0.4.1 2022-08-12 OpenJDK Runtime Environment Temurin-17.0.4.1+1 (build 17.0.4.1+1) OpenJDK 64-Bit Server VM Temurin-17.0.4.1+1 (build 17.0.4.1+1, mixed mode, sharing) $ bin/server.sh --version Infinispan Server 14.0.0.Final (Flying Saucer) Copyright (C) Red Hat Inc. and/or its affiliates and other contributors License Apache License, v. 2.0. http://www.apache.org/licenses/LICENSE-2.0
èµ·åã¯ã以äžã®ã³ãã³ãã§ã
$ bin/server.sh \ -b 0.0.0.0 \ -Djgroups.tcp.address=`hostname -i`
æºå
ãŸãã¯ãInfinispan Serverã®æºåãè¡ããŸãããŠãŒã¶ãŒãšCacheãå®çŸ©ããŸãããã
管çCLIã§ã管çãŠãŒã¶ãŒãšã¢ããªã±ãŒã·ã§ã³ãŠãŒã¶ãŒãäœæã
$ bin/cli.sh user create -g admin -p password ispn-admin $ bin/cli.sh user create -g application -p password ispn-user
管çCLIã§ãã°ã€ã³ã
$ bin/cli.sh -c- Username: ispn-admin Password: [e6c550bca326-45515@cluster//containers/default]>
Distributed Cacheã2ã€äœæããŸãã
create cache --template=org.infinispan.DIST_SYNC simpleCache create cache --template=org.infinispan.DIST_SYNC bookCache
å®çŸ©ã®ç¢ºèªã
describe caches/simpleCache { "simpleCache" : { "distributed-cache" : { "mode" : "SYNC", "remote-timeout" : "17500", "statistics" : true, "locking" : { "concurrency-level" : "1000", "acquire-timeout" : "15000", "striping" : false }, "state-transfer" : { "timeout" : "60000" } } } } describe caches/bookCache { "bookCache" : { "distributed-cache" : { "mode" : "SYNC", "remote-timeout" : "17500", "statistics" : true, "locking" : { "concurrency-level" : "1000", "acquire-timeout" : "15000", "striping" : false }, "state-transfer" : { "timeout" : "60000" } } } }
ãã¡ãã䜿ãããã«ãã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
ãã¹ãã³ãŒãã®æºå
確èªã¯ããã¹ãã³ãŒãã§è¡ãããšã«ããŸãã
MavenäŸåé¢ä¿çã
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-bom</artifactId> <version>14.0.0.Final</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-bom</artifactId> <version>8.0.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.junit</groupId> <artifactId>junit-bom</artifactId> <version>5.9.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-hotrod</artifactId> </dependency> <dependency> <groupId>jakarta.transaction</groupId> <artifactId>jakarta.transaction-api</artifactId> </dependency> <dependency> <groupId>org.infinispan.protostream</groupId> <artifactId>protostream-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.23.1</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.2</version> </plugin> </plugins> </build>
ãã£ãããªã®ã§ãProtoStreamã䜿ãããšã«ããŸãã
ãšã³ãã£ãã£ã¯ã©ã¹ã
src/main/java/org/littlewings/infinispan/remote/newclient/Book.java
package org.littlewings.infinispan.remote.newclient; import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; import org.infinispan.protostream.descriptors.Type; public class Book { @ProtoField(number = 1) String isbn; @ProtoField(number = 2) String title; @ProtoField(number = 3, type = Type.INT32, defaultValue = "0") int price; @ProtoFactory public static Book create(String isbn, String title, int price) { Book book = new Book(); book.setIsbn(isbn); book.setTitle(title); book.setPrice(price); return book; } // getterïŒsettterã¯çç¥ }
Marshallerããã³Protocol Buffersã®IDLãçæããããã®SerializationContextInitializer
ã€ã³ã¿ãŒãã§ãŒã¹ã®ãµãã€ã³ã¿ãŒãã§ãŒã¹ãäœæããŸãã
ä»ã¯ãã®ãµãã€ã³ã¿ãŒãã§ãŒã¹ã§ããGeneratedSchema
ã€ã³ã¿ãŒãã§ãŒã¹ãç¶æ¿ããã®ãè¯ãããã§ããã
src/main/java/org/littlewings/infinispan/remote/newclient/EntitiesInitializer.java
package org.littlewings.infinispan.remote.newclient; import org.infinispan.protostream.GeneratedSchema; import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; @AutoProtoSchemaBuilder( includeClasses = { Book.class }, schemaFileName = "entities.proto", schemaFilePath = "proto/", schemaPackageName = "remote_newclient") public interface EntitiesInitializer extends GeneratedSchema { }
ãã¹ãã³ãŒãã®é圢ã
src/test/java/org/littlewings/infinispan/remote/newclient/HotRodNewClientTest.java
package org.littlewings.infinispan.remote.newclient; import java.net.URI; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.stream.IntStream; import org.infinispan.api.Infinispan; import org.infinispan.api.async.AsyncCache; import org.infinispan.api.async.AsyncContainer; import org.infinispan.api.mutiny.MutinyContainer; import org.infinispan.api.sync.SyncCache; import org.infinispan.api.sync.SyncContainer; import org.infinispan.api.sync.events.cache.SyncCacheContinuousQueryListener; import org.infinispan.hotrod.configuration.HotRodConfiguration; import org.infinispan.hotrod.configuration.HotRodConfigurationBuilder; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class HotRodNewClientTest { // ããã«ããã¹ããæžãïŒ }
ã§ã¯ããã¹ããæžããŠãããŸãããã
Infinispan Serverã«æ¥ç¶ãã
ãŸãã¯Infinispan Serverã«æ¥ç¶ããå¿ èŠããããŸãã以äžã®ãããªãœãŒã¹ã³ãŒãã«ãªããŸãïŒCacheã¯åæCacheã䜿ã£ãŠããŸãïŒã
@Test public void connectInfinispanServerUsingURI() { String uriString = "hotrod://ispn-user:password@172.17.0.2:11222"; URI uri = URI.create(uriString); try (Infinispan infinispan = Infinispan.create(uri); // ãŸã㯠// try (Infinispan infinispan = Infinispan.create(uriString)) { SyncContainer container = infinispan.sync()) { SyncCache<String, String> cache = container .caches() .get("simpleCache"); cache.clear(); } }
Infinispan#create
ã«æ¥ç¶URIãString
ãŸãã¯java.net.URI
ãšããŠæž¡ããšãInfinispan
ã®ã€ã³ã¹ã¿ã³ã¹ãè¿ã£ãŠããŸãã
try (Infinispan infinispan = Infinispan.create(uri); // ãŸã㯠// try (Infinispan infinispan = Infinispan.create(uriString)) {
ããããã䜿ãããAPIã®çš®é¡ã«å¿ããŠã¡ãœãããåŒã³åºããã³ã³ãããååŸããŸããã¡ãœããã¯ãåæãªãsync
ãéåæãªãasync
ã
Mutinyãªãmutiny
ã§ãã
ä»åã¯ãåæAPIã䜿ã£ãŠããŸãã
SyncContainer container = infinispan.sync()) {
Infinispan
ã®ã€ã³ã¹ã¿ã³ã¹ããã³ã³ã³ããã®ã€ã³ã¹ã¿ã³ã¹ã¯ãçµäºæã«close
ããŸãã
ã³ã³ããããåŒã³åºããã¡ãœããã«å¿ããŠSyncContainer
ãAsyncContainer
ãMutinyContainer
ã®3çš®é¡ã®ãããããè¿ã£ãŠããŸãã
ãŸããæ¥ç¶URI以å€ã«ãConfiguration
ã®ã€ã³ã¹ã¿ã³ã¹ãæž¡ãããšã§ãInfinispan Serverãžæ¥ç¶ã§ããŸãã
@Test public void connectInfinispanServerUsingConfiguration() { HotRodConfiguration configuration = new HotRodConfigurationBuilder() .addServers("172.17.0.2:11222") .security() .authentication() .username("ispn-user") .password("password".toCharArray()) .build(); try (Infinispan infinispan = Infinispan.create(configuration); SyncContainer container = infinispan.sync()) { SyncCache<String, String> cache = container .caches() .get("simpleCache"); cache.clear(); } }
åæAPIã䜿ã
Infinispan Serverãžã®æ¥ç¶æ¹æ³ãããã£ããšããã§ãAPIã䜿ã£ãŠãã£ãŠã¿ãŸãããããŸãã¯åæAPIããã
@Test public void simpleSyncCache() { URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222"); try (Infinispan infinispan = Infinispan.create(uri); SyncContainer container = infinispan.sync()) { SyncCache<String, String> cache = container .caches() .get("simpleCache"); IntStream .rangeClosed(1, 100) .forEach(i -> cache.set("key" + i, "value" + i)); assertThat(cache.get("key1")).isEqualTo("value1"); assertThat(cache.get("key50")).isEqualTo("value50"); assertThat(cache.get("key100")).isEqualTo("value100"); cache.clear(); assertThat(cache.get("key1")).isNull(); assertThat(cache.get("key50")).isNull(); assertThat(cache.get("key100")).isNull(); } }
æ¥ç¶æ¹æ³ã玹ä»ããæã«å°ãåºãŠããŠããŸããããSyncContainer#caches
ããSyncCaches#get
ã§SyncCache
ãååŸããŸãã
SyncCache<String, String> cache =
container
.caches()
.get("simpleCache");
次ã«ãèªåã§äœæãããšã³ãã£ãã£ã䜿ã£ãŠã¿ãŸãã
@Test public void bookSyncCache() { // URIã§ã¯Propertiesã®éšåã¯èªãŸãªã //URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222?context-initializers=org.littlewings.infinispan.remote.newclient.EntitiesInitializerImpl"); HotRodConfiguration configuration = new HotRodConfigurationBuilder() .addServers("172.17.0.2:11222") .addContextInitializer("org.littlewings.infinispan.remote.newclient.EntitiesInitializerImpl") .security() .authentication() .username("ispn-user") .password("password".toCharArray()) .build(); try (Infinispan infinispan = Infinispan.create(configuration); SyncContainer container = infinispan.sync()) { SyncCache<String, Book> cache = container .caches() .get("bookCache"); List<Book> books = List.of( Book.create("978-1782169970", "Infinispan Data Grid Platform Definitive Guide", 5344), Book.create("978-1785285332", "Getting Started with Hazelcast - Second Edition", 5484), Book.create("978-0359439379", "The Apache Ignite Book", 9964), Book.create("978-1783988181", "Mastering Redis", 8719), Book.create("978-1492080510", "High Performance MySQL", 6428) ); books.forEach(b -> cache.set(b.getIsbn(), b)); assertThat(cache.get("978-1782169970").getTitle()) .isEqualTo("Infinispan Data Grid Platform Definitive Guide"); assertThat(cache.get("978-1782169970").getPrice()) .isEqualTo(5344); assertThat(cache.get("978-0359439379").getTitle()) .isEqualTo("The Apache Ignite Book"); assertThat(cache.get("978-0359439379").getPrice()) .isEqualTo(9964); cache.clear(); assertThat(cache.get("978-1782169970")).isNull(); assertThat(cache.get("978-1782169970")).isNull(); } }
é©ãããšã«ããã¡ãã¯æ¥ç¶URIã§ã¯ãªãConfiguration
ã®ã€ã³ã¹ã¿ã³ã¹ã䜿ããªããšããŸãåäœããŸããâŠã
APIã®çŽ¹ä»ããããŸãåããªãã£ããšããã¯æåŸã«ãŸãšããŠæžããŸããã
éåæAPI
次ã¯ãéåæAPIã
@Test public void simpleAsyncCache() { URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222"); try (Infinispan infinispan = Infinispan.create(uri); AsyncContainer container = infinispan.async()) { AsyncCache<String, String> cache = container .caches() .<String, String>get("simpleCache") .toCompletableFuture() .join(); IntStream .rangeClosed(1, 100) .<CompletionStage<?>>mapToObj(i -> cache.set("key" + i, "value" + i)) .map(CompletionStage::toCompletableFuture) .forEach(CompletableFuture::join); cache .get("key1") .thenAccept(value -> assertThat(value).isEqualTo("value1")) .thenCompose(v -> cache.get("key50")) .thenAccept(value -> assertThat(value).isEqualTo("value50")) .thenCompose(v -> cache.get("key100")) .thenAccept(value -> assertThat(value).isEqualTo("value100")) .toCompletableFuture() .join(); cache.clear().toCompletableFuture().join(); cache .get("key1") .thenAccept(value -> assertThat(value).isNull()) .thenCompose(v -> cache.get("key50")) .thenAccept(value -> assertThat(value).isNull()) .thenCompose(v -> cache.get("key100")) .thenAccept(value -> assertThat(value).isNull()) .toCompletableFuture() .join(); } }
ãã¡ãã¯ãInfinispan#async
ã䜿çšããŠAsyncContainer
ãååŸããŸãã
AsyncContainer container = infinispan.async()) { AsyncCache<String, String> cache = container .caches() .<String, String>get("simpleCache") .toCompletableFuture() .join();
ããšã¯ãåæäœã®æ»ãå€ãCompletionStage
ãšãªã£ãŠããç¹ã«æ³šæãã€ã€ïŒentries
ãªã©ã®ãŸãšãŸã£ãŠæäœãè¡ãã¡ãœããã¯Flow.Publisher
ã«
ãªã£ãŠãããã®ããããŸãïŒãæäœãè¡ããŸãã
ãšã³ãã£ãã£ã䜿ã£ãäŸã
@Test public void bookAsyncCache() { HotRodConfiguration configuration = new HotRodConfigurationBuilder() .addServers("172.17.0.2:11222") .addContextInitializer("org.littlewings.infinispan.remote.newclient.EntitiesInitializerImpl") .security() .authentication() .username("ispn-user") .password("password".toCharArray()) .build(); try (Infinispan infinispan = Infinispan.create(configuration); AsyncContainer container = infinispan.async()) { AsyncCache<String, Book> cache = container .caches() .<String, Book>get("bookCache") .toCompletableFuture() .join(); List<Book> books = List.of( Book.create("978-1782169970", "Infinispan Data Grid Platform Definitive Guide", 5344), Book.create("978-1785285332", "Getting Started with Hazelcast - Second Edition", 5484), Book.create("978-0359439379", "The Apache Ignite Book", 9964), Book.create("978-1783988181", "Mastering Redis", 8719), Book.create("978-1492080510", "High Performance MySQL", 6428) ); books .stream() .map(b -> cache.set(b.getIsbn(), b).toCompletableFuture()) .forEach(CompletableFuture::join); cache .get("978-1782169970") .thenAccept(b -> { assertThat(b.getTitle()).isEqualTo("Infinispan Data Grid Platform Definitive Guide"); assertThat(b.getPrice()).isEqualTo(5344); }) .thenCompose(v -> cache.get("978-0359439379")) .thenAccept(b -> { assertThat(b.getTitle()).isEqualTo("The Apache Ignite Book"); assertThat(b.getPrice()).isEqualTo(9964); }) .toCompletableFuture() .join(); cache.clear().toCompletableFuture().join(); cache .get("978-1782169970") .thenAccept(b -> assertThat(b).isNull()) .thenCompose(v -> cache.get("978-0359439379")) .thenAccept(b -> assertThat(b).isNull()) .toCompletableFuture() .join(); } }
Mutiny API
æåŸã¯MutinyâŠæ£ç¢ºã«ã¯SmallRye Mutinyã§ããããã¡ãã¯ä»¥äžã«ãªããŸãã
@Test public void simpleMutinyCache() { URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222"); try (Infinispan infinispan = Infinispan.create(uri); MutinyContainer container = infinispan.mutiny()) { assertThatThrownBy(() -> container .caches() .<String, String>get("simpleCache") .await() .indefinitely() ) .isInstanceOf(ClassCastException.class) .hasMessage("class java.util.concurrent.CompletableFuture cannot be cast to class org.infinispan.hotrod.impl.cache.RemoteCache (java.util.concurrent.CompletableFuture is in module java.base of loader 'bootstrap'; org.infinispan.hotrod.impl.cache.RemoteCache is in unnamed module of loader 'app')"); } }
æ®å¿µã§ãããçŸæç¹ã§ã¯MutinyCache
ãååŸããéã«å€±æããŸãã
è¿œèšïŒ Infinispan 14.0.4.Finalã§ä¿®æ£ãããã®ã§ãè¿œå ã®ãšã³ããªãŒãæžããŸãã
Infinispan 14.0の新しいHot Rod Client APIのMutiny版を試す - CLOVER🍀
æ°ããAPIã«ã€ããŠ
ããããã¯ãæ°ããAPIã«ã€ããŠããããæžããŠãããããšæããŸãã
infinispan-apiã¢ãžã¥ãŒã«
ä»åãInfinispanã«é¢ããimport
æã®ã»ãšãã©ã¯org.infinispan.api
ã®ãã®ã§ããã
import org.infinispan.api.Infinispan; import org.infinispan.api.async.AsyncCache; import org.infinispan.api.async.AsyncContainer; import org.infinispan.api.mutiny.MutinyContainer; import org.infinispan.api.sync.SyncCache; import org.infinispan.api.sync.SyncContainer; import org.infinispan.api.sync.events.cache.SyncCacheContinuousQueryListener; import org.infinispan.hotrod.configuration.HotRodConfiguration; import org.infinispan.hotrod.configuration.HotRodConfigurationBuilder;
ããã¯ãinfinispan-api
ãšããã¢ãžã¥ãŒã«ã§ãã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/api
README.adoc
ãèŠããšãã©ããäœæéäžã§ããããšãšãå®éšçã§Infinispan 10ã§å€æŽãããå¯èœæ§ãããæšãæžãããŠããŸãã
https://github.com/infinispan/infinispan/blob/14.0.0.Final/api/README.adoc
Infinispan 10ã®æç¹ã§ããã®ã¢ãžã¥ãŒã«ã¯ãã£ããã§ãããã
https://github.com/infinispan/infinispan/tree/10.0.0.Final/api
ãããInfinispan 10ã®æã«1床äœæãããæ°ããAPIãå床圢ãå€ãããã®ãªæ°ãããŸããã
API 2.0ãšããæ±ãã®ããã§ãïŒä»¥åã®ãã®ãã±ããã®ã¿ã€ãã«ã¯ãNew Reactive APIãã§ããïŒã
[ISPN-9893] API 2.0 - Red Hat Issue Tracker
ãããŠãInfinispan 10æç¹ã®æ°ããAPIã®ã¢ãžã¥ãŒã«ã¯ç©ºã£ãœã«ãªã£ãŠããŸãã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/client/infinispan-key-value-store-hotrod
ãšããããã§ãä»åã®ã¢ãžã¥ãŒã«ã¯éå»ã®APIã¢ãžã¥ãŒã«ãåæ§ç¯ããããã®ã§ããããšããããã§ãã
Infinispan#create
ä»åã®APIã¯ãInfinispan#create
ã«URIãConfiguration
ãæž¡ããšãå®äœãããŒããããããã«ãªã£ãŠããŸãã
try (Infinispan infinispan = Infinispan.create(uri); // ãŸã㯠try (Infinispan infinispan = Infinispan.create(configuration);
ããã¯ãService Loaderã®ä»çµã¿ã§å®çŸããŠããããã§ãã
JDBCãã©ã€ããŒããããšåãã§ããã
æ§æ
Infinispan#sync
ãInfinispan#async
ãInfinispan#mutiny
ãåŒã³åºããšãåŒã³åºããã¡ãœããã«å¿ããContainer
ãååŸã§ããŸãã
/** * Returns a synchronous version of the Infinispan API * * @return */ SyncContainer sync(); /** * Returns an asynchronous version of the Infinispan API * * @return */ AsyncContainer async(); /** * Returns a mutiny version of the Infinispan API * * @return */ MutinyContainer mutiny();
åContainer
ããã¯Cache
ãMultiMap
ãStrongCounter
ãWeakCounter
ãLock
ãšãã£ãæ§ã
ãªããŒã¿æ§é ãååŸããããšãã§ãã
ãšã³ããªãŒãã€ã³ãã«ãªã£ãŠãããšèšããŸãã
SyncContainer
public interface SyncContainer extends Infinispan { SyncCaches caches(); SyncMultiMaps multiMaps(); SyncStrongCounters strongCounters(); SyncWeakCounters weakCounters(); SyncLocks locks(); void listen(SyncContainerListener listener, ContainerListenerEventType... types); <T> T batch(Function<SyncContainer, T> function); }
AsyncContainer
public interface AsyncContainer extends Infinispan { AsyncCaches caches(); AsyncMultiMaps multiMaps(); AsyncStrongCounters strongCounters(); AsyncWeakCounters weakCounters(); AsyncLocks locks(); Flow.Publisher<ContainerEvent> listen(ContainerListenerEventType... types); <T> CompletionStage<T> batch(Function<AsyncContainer, CompletionStage<T>> function); }
MutinyContainer
ã
public interface MutinyContainer extends Infinispan { MutinyCaches caches(); MutinyMultiMaps multiMaps(); MutinyStrongCounters strongCounters(); MutinyWeakCounters weakCounters(); MutinyLocks locks(); /** * @param types * @return */ Multi<ContainerEvent> listen(ContainerListenerEventType... types); <R> Uni<R> execute(String name, Object... args); <T> Uni<T> batch(Function<MutinyContainer, Uni<T>> function); }
ä»å䜿ã£ãã®ã¯Cache
ã®ã¿ã§ããã
ãããŠãåContainer
ãé
眮ãããŠããããã±ãŒãžå
ã«ãåçš®ããŒã¿æ§é ã«å¯Ÿããã€ã³ã¿ãŒãã§ãŒã¹ãé
眮ãããŠããŸãã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/api/src/main/java/org/infinispan/api/sync
Cacheã®ã€ã³ã¿ãŒãã§ãŒã¹ãã€ãã«ãjava.util.Map
ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ããªããªããŸãããã
å®è£
ã¯ãå¥ã¢ãžã¥ãŒã«ïŒä»åã¯Hot Rod Clientã§ããinfinispan-hotrod
ïŒã«å«ãŸããŠããŸãã
åæãéåæãMutinyã®å®çŸ
ä»åã®ããŒã¹ãšæãAPIã¯ãåæãéåæãMutinyã®3çš®é¡ã§æäŸãããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹ã¯infinispan-api
ã¢ãžã¥ãŒã«ã«ãããŸããããå®è£
ã¯ã©ããã£ã圢ã§å®çŸããŠãããã§ããããã
å®è£
ãèŠãŠãããšãåºæ¬çã«ã¯éåæããã³RxJavaãããŒã¹ã«ãªã£ãŠããŸããã€ãŸãHotRodAsyncCache
ã1çªãªãªãžãã«ã«è¿ãã§ãã
SyncCache
ã®å Žåã¯ãCompletableFuture#get
ã§åæçã«åããŠããããã«èŠããããŠããŸãã
MutinyCache
ã®å Žåã¯CompletableFuture
ãUni
ãžãFlow.Publisher
ãMulti
ã«å€æããããšã§SmallRye Mutinyã®APIãšããŠ
èŠããŠããŸãã
ãªãããããã®Cache
ãRemoteCache
ãšããã€ã³ã¿ãŒãã§ãŒã¹ãå®äœã«ãªã£ãŠããŠããã¡ããCompletionStage
ãFlow.Publisher
ã
APIã®åºç€ãšããŠäœ¿çšããŠããŸãã
ã¡ãªã¿ã«ããã®ãããªCompletableFuture
ãFlow.Publisher
ãããŒã¹ã«ããŠãããã®ã®ãåæåŒã³åºãã¯CompletableFuture
ã®åŸ
ã¡åããã§
å®çŸãããšãã£ãæ¹æ³ã¯ãæ¢åã®Hot Rod Clientãåãã§ãã
æ°ããHot Rod Clientãšæ¢åã®Hot Rod Clientã®é¢ä¿
çŸæç¹ã§2系統ã®Hot Rod Clientã¢ãžã¥ãŒã«ãããããã§ãããäž¡è
ã®é¢ä¿ã¯ãšãããšãé¢ä¿ãããŸãããããã°ã«æžããŠãããšããã
æ°ããHot Rod Clientã¯å®å
šã«åèšèšããŠããããã§ãã
ãã¡ããæ°ããHot Rod Clientã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/client/hotrod
ãã¡ããæ¢åã®Hot Rod Clientã
https://github.com/infinispan/infinispan/tree/14.0.0.Final/client/hotrod-client
æåã¯åŸæ¥ã®Hot Rod Clientã®ã©ãããŒã«ãªã£ãŠãããããã®ã§ã¯ïŒãšãæããŸãããããããªããšã¯ãããŸããã§ããã
ãŸã ãŸã ã§ããªãããšãå€ã
RemoteCacheImpl
ãèŠãŠãããšããããŸãããUnsupportedOperationException
ãæããŠããã¡ãœããããããªãã«ãããŸãã
Configuration
ã®ååŸãNear Cacheãžã®ãªã¹ããŒã®è¿œå ãCacheã®ãµã€ãºèšç®ããªã¹ããŒã®è¿œå ãEntry Processorããã©ã³ã¶ã¯ã·ã§ã³ãªã©ã
ãŸããSyncCache
ã®ã¿ã§ããªãããšããããŸãã
確èªã®ã³ãŒãã
@Test public void simpleSyncCacheUnsupportedOperation() { URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222"); try (Infinispan infinispan = Infinispan.create(uri); SyncContainer container = infinispan.sync()) { SyncCache<String, String> cache = container .caches() .get("simpleCache"); assertThatThrownBy(() -> cache.entries()) .isInstanceOf(UnsupportedOperationException.class); assertThatThrownBy(() -> cache.keys()) .isInstanceOf(UnsupportedOperationException.class); assertThatThrownBy(() -> cache.listen(new SyncCacheContinuousQueryListener<>() { })) .isInstanceOf(UnsupportedOperationException.class); assertThatThrownBy(() -> cache.estimateSize()) .isInstanceOf(UnsupportedOperationException.class); } }
ããã£ãããš
ããã§ã¯ãããã£ãããšãå°ãæžããŠãããŸãã
äŸåé¢ä¿ã«jakarta.transaction-apiãå¿ èŠ
æåãäŸåé¢ä¿ã«infinispan-hotrod
ãšprotostream-processor
ã ãã足ããŠè©ŠããŠããã®ã§ãããInfinispan Serverã«æ¥ç¶ã§ããã«
èŠåŽããŸããã
<dependency> <groupId>org.infinispan</groupId> <artifactId>infinispan-hotrod</artifactId> </dependency> <dependency> <groupId>org.infinispan.protostream</groupId> <artifactId>protostream-processor</artifactId> <optional>true</optional> </dependency>
URIãæå®ããŠã®æ¥ç¶æ¹æ³ã ãšããã°ãåºãŠãããããªãã ããïŒããšæã£ãŠãã¬ãŒã¹ããã®ã§ãããjavax.transaction
ããã±ãŒãžã®ã¯ã©ã¹ã«
察ããŠClassNotFoundException
ãèµ·ãããŠããããã§ãã
org.infinispan.api.exception.InfinispanConfigurationException: No factory to handle URI hotrod://ispn-user:password@172.17.0.2:11222 at org.infinispan.api.Infinispan.create(Infinispan.java:40)
åŸããæ°ã¥ããŸããããConfiguration
ãæž¡ãæ¹ã ãšãã£ãšããã«ã³ã±ãŠãããŸããâŠã
java.lang.NoClassDefFoundError: javax/transaction/RollbackException at org.infinispan.hotrod.impl.HotRodTransport.<init>(HotRodTransport.java:91) at org.infinispan.hotrod.HotRod.<init>(HotRod.java:16) at org.infinispan.hotrod.HotRodFactory.create(HotRodFactory.java:29) at org.infinispan.api.Infinispan.create(Infinispan.java:49) at org.littlewings.infinispan.remote.newclient.HotRodNewClientTest.connectInfinispanServerUsingConfiguration(HotRodNewClientTest.java:53) ãçç¥ã at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: java.lang.ClassNotFoundException: javax.transaction.RollbackException at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ... 75 more
pom.xml
äžã¯optional
ã«ãªã£ãŠããŸãããå®è³ªå¿
é ã§ããâŠã
https://github.com/infinispan/infinispan/blob/14.0.0.Final/client/hotrod/pom.xml#L73-L77
URIæå®ã§SerializationContextInitializerãæå®ã§ããªã
å ã«æžããéšåã§ã以äžã®ããã«æžããŠããäºè±¡ã§ããã
// URIã§ã¯Propertiesã®éšåã¯èªãŸãªã //URI uri = URI.create("hotrod://ispn-user:password@172.17.0.2:11222?context-initializers=org.littlewings.infinispan.remote.newclient.EntitiesInitializerImpl");
ããã¯ã©ãããŠçºçããããšãããšãURIãããŒã¹ããŠåŸãããProperties
ã
ConfigurationBuilder
å
ã§ç¡èŠããŠããããã§ãâŠã
@Override public HotRodConfigurationBuilder withProperties(Properties properties) { //FIXME return this; }
FIXME
ãä»ããŠããã®ã§ãä¿®æ£ãããã®ãåŸ
ã¡ãŸãããâŠã
Mutinyã§åäœããªã
MutinyCache
ãååŸããããšãããšãè¬ã®ClassCastException
ãçºçããŸãã
java.lang.ClassCastException: class java.util.concurrent.CompletableFuture cannot be cast to class org.infinispan.hotrod.impl.cache.RemoteCache (java.util.concurrent.CompletableFuture is in module java.base of loader 'bootstrap'; org.infinispan.hotrod.impl.cache.RemoteCache is in unnamed module of loader 'app') at org.infinispan.hotrod.HotRodMutinyCaches.lambda$get$2(HotRodMutinyCaches.java:35) at io.smallrye.mutiny.operators.uni.UniOnItemTransform$UniOnItemTransformProcessor.onItem(UniOnItemTransform.java:36) at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38) at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.access$100(UniCreateFromKnownItem.java:26) at io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23) at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36) at io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22) at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36) at io.smallrye.mutiny.operators.uni.UniBlockingAwait.await(UniBlockingAwait.java:60) at io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:65) at io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:46) ãçç¥ã
HotRodMutinyCaches
ã¯ã©ã¹ãèŠãŠã¿ããšãããããªFIXME
ãšæžããŠãããŸãã
@Override public <K, V> Uni<MutinyCache<K, V>> create(String name, CacheConfiguration cacheConfiguration) { // FIXME return Uni.createFrom().item(hotrod.transport.getRemoteCache(name)).map(r -> new HotRodMutinyCache<>(hotrod, (RemoteCache<K, V>) r)); } @Override public <K, V> Uni<MutinyCache<K, V>> create(String name, String template) { // FIXME return Uni.createFrom().item(hotrod.transport.getRemoteCache(name)).map(r -> new HotRodMutinyCache<>(hotrod, (RemoteCache<K, V>) r)); } @Override public <K, V> Uni<MutinyCache<K, V>> get(String name) { return Uni.createFrom().item(hotrod.transport.getRemoteCache(name)).map(r -> new HotRodMutinyCache<>(hotrod, (RemoteCache<K, V>) r)); }
HotRod#transport#getRemoteCache
ã®çµæã¯CompletableFuture
ãªã®ã§ãRemoteCache
ã«ãã£ã¹ãã§ããã«å€±æããŠããŸãâŠã
ãŸãããã¹ãã¯AsyncCache
åãããªãã£ãã§ãããâŠã
è¿œèšïŒ Infinispan 14.0.4.Finalã§ä¿®æ£ãããã®ã§ãè¿œå ã®ãšã³ããªãŒãæžããŸãã
Infinispan 14.0の新しいHot Rod Client APIのMutiny版を試す - CLOVER🍀
ãŸãšã
Infinispan 14.0ã§è¿œå ããããæ°ããHot Rod Client APIãè©ŠããŠã¿ãŸããã
ããããã¥ã¡ã³ãããªãã£ãããåããªãã£ãããæ©èœããŸã 足ããªãã£ãããšããç¶æ ãªããšãããããŸããã
ãŸãããŸã ã§ããã°ã£ããã§ãããå®è£ ãé²ãã®ãããã¡ãã£ãšåŸ ã€ããšã«ããŸãã
Infinispan 10.0ã®æã«ããæ°ããAPIãè©ŠããŠã¿ããã®ã®ãã®ãŸãŸè©±é¡ã«æãããªããªã£ãæã®ããšãæãåºããŸãããâŠã
Infinispan 10のNew Reactive API(Hot Rod)を試す - CLOVER🍀
ä»åäœæãããœãŒã¹ã³ãŒãã¯ããã¡ãã«çœ®ããŠããŸãã