CLOVERšŸ€

That was when it all began.

Infinispan 14.0ć®ę–°ć—ć„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’Hot Rod恧試恙

恓悌ćÆ态ćŖć«ć‚’ć—ćŸćć¦ę›øć„ćŸć‚‚ć®ļ¼Ÿ

Infinispan恧å…Øꖇꤜē“¢ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’ä½æē”Øć™ć‚‹å “åˆć€Cache恫äæå­˜ć™ć‚‹ć‚Øćƒ³ćƒˆćƒŖćƒ¼ć®å„ćƒ—ćƒ­ćƒ‘ćƒ†ć‚£ć«åÆ¾ć—ć¦Hibernate Search恮
ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ä½æē”Ø恗恦čØ­å®šć‚’č”Œć£ć¦ć„ć¾ć—ćŸć€‚

恓悌恌Infinispan 14.0恧态Infinispanč‡Ŗčŗ«ćŒć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ęä¾›ć™ć‚‹ć‚ˆć†ć«ćŖć£ćŸć‚ˆć†ć§ć™ć€‚

Native Infinispan indexing annotations which finally replace the legacy Hibernate Query annotations weā€™ve used in past versions

Infinispan 14.0.0.Final

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć«é–¢ć™ć‚‹å¤‰ę›“ćÆä»–ć«ć‚‚ć‚ć‚‹ć‚ˆć†ć§ć™ćŒć€ä»Šå›žćÆć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«é–¢ć—ć¦č¦‹ć¦ć„ć“ć†ćØę€ć„ć¾ć™ć€‚

Index startup mode to determine what happens to indexes on cache start

Dynamic index schema updates allow you to evolve your schema at runtime with near-zero impact to your queries

Infinispanć«ć‚ˆć‚‹ę–°ć—ć„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³

ć¾ćšć€Infinispan恮ć‚Æć‚ØćƒŖćƒ¼ć‚„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć«é–¢ć™ć‚‹ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆćÆ态恓恔悉恧恙怂

Querying Infinispan caches

Infinispan恮ć‚Æć‚ØćƒŖćƒ¼ć®ć†ć”ć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’ä½æć£ćŸć‚‚ć®ćÆHibernate SearchćØApache Luceneć«ć‚ˆć£ć¦å®Ÿē¾ć•ć‚Œć¦ć„ć¾ć™ć€‚

ć‚Æć‚ØćƒŖćƒ¼ćÆ态Ickle QueryćØ恄恆JPQLćƒ©ć‚¤ć‚ÆćŖč؀čŖžć‚’ä½æć£ć¦čؘčæ°ć—ć¾ć™ć€‚

Querying Infinispan caches / Creating Ickle queries

ä»Šå›žć®ę–°ć—ć„ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«ć¤ć„ć¦ćÆćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć«ćÆę›øć‹ć‚Œć¦ć„ćŖ恄悈恆ćŖ恮恧态仄äø‹ć®ćƒ–ćƒ­ć‚°ć‚„ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‚’é ¼ć‚Šć«č¦‹ć¦ć„ćć“ćØ恫
ć—ć¾ć™ć€‚

Infinispan 14 indexing & query news

ćŖćŠć€ć“ć®å¤‰ę›“ćŒå…„ć£ćŸć®ćÆ仄äø‹ć®Pull Requestć®ć‚ˆć†ć§ć™ć€‚

ISPN-9893 New API indexing annotations by fax4ever · Pull Request #9942 · infinispan/infinispan · GitHub

惖惭悰ć‚Øćƒ³ćƒˆćƒŖćƒ¼ć«ćÆć€ć“ć®ć‚ˆć†ćŖć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć®ē“¹ä»‹ćÆč”Œć‚ć‚Œć¦ć„ć‚‹ć®ć§ć™ćŒć€importꖇ悂ćŖć„ć®ć§ć©ć®ćƒ‘ćƒƒć‚±ćƒ¼ć‚øćŖ恮恋悂
ć‚ć‹ć‚Šć¾ć›ć‚“ć€‚

@Indexed
public class Poem {
    private Author author;
    private String description;
    private Integer year;

    @Embedded(includeDepth = 2, structure = Structure.NESTED)
    public Author getAuthor() {
        return author;
    }

    @Text(projectable = true, analyzer = "whitespace", termVector = TermVector.WITH_OFFSETS)
    public String getDescription() {
        return description;
    }

    @Basic(projectable = true, sortable = true, indexNullAs = "1800")
    public Integer getYear() {
    return year;
    }
}

@Indexed
public class Author {
    private String name;

    public Author(String name) {
        this.name = name;
    }

    @Keyword(projectable = true, sortable = true, normalizer = "lowercase", indexNullAs = "unnamed", norms = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

čŖ¬ę˜ŽćÆå°‘ć—ę›øć‹ć‚Œć¦ć„ć¾ć™ć€‚

ć¾ćšć€å…ˆć«ć‚‚ę›øćć¾ć—ćŸćŒć€‚ä»Šå›žć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćÆHibernate Searchć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ē½®ćę›ćˆć‚‹Infinispanć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć«
ćŖć‚Šć¾ć™ć€‚Embedded态Remote恮恩恔悉恧悂ä½æ恈悋悈恆恧恙怂

We are going to replace Hibernate annotations with Infinispan indexing annotations. The new annotations can be used in the same way for both embedded and remote queries.

ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³č‡Ŗä½“ć«ć‚‚č§¦ć‚Œć¦ć„ć¾ć™ć€‚

  • @Basic ā€¦ ē‰¹ć«ę–‡å­—åˆ—å¤‰ę›å‡¦ē†ć‚’č”Œć‚ćŖć„ćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰
  • @Keyword ā€¦ Stringćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«ćƒŽćƒ¼ćƒ©ćƒžć‚¤ć‚¶ćƒ¼ć‚’é©ē”Ø恙悋
  • @Text ā€¦ Stringćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«ć‚¢ćƒŠćƒ©ć‚¤ć‚¶ćƒ¼ć‚’é©ē”Ø恙悋

ć‚½ćƒ¼ćƒˆć‚„ćƒ—ćƒ­ć‚ø悧ć‚Æć‚·ćƒ§ćƒ³ćŒć§ćć‚‹ć‹ć©ć†ć‹ćÆ态sortable悄projectableć§ęŒ‡å®šć—ć¾ć™ć€‚ä½æē”Ø恧恍ćŖ恄ēµ„ćæåˆć‚ć›ć‚‚ć‚ć‚Šć€ćŸćØ恈恰sortablećØ
ć‚¢ćƒŠćƒ©ć‚¤ć‚ŗć‚’č”Œć†@TextćÆēµ„ćæåˆć‚ć›ć‚‹ć“ćØćŒć§ćć¾ć›ć‚“ć€‚

ćƒć‚¹ćƒˆć—ćŸć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć‚’ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć«äæå­˜ć™ć‚‹éš›ć«ćÆ态@Embeddedć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ä½æē”Øć—ć¾ć™ć€‚ć“ć®ę™‚ć€ćƒć‚¹ćƒˆć—ćŸć‚Ŗ惖ć‚ø悧ć‚Æ惈悒
ć©ć®ć‚ˆć†ć«ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć«äæå­˜ć™ć‚‹ć‹ćÆstructureå±žę€§ć§ęŒ‡å®šć—ć¾ć™ć€‚NESTEDćŒćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć§ć€ć‚Ŗ惖ć‚ø悧ć‚Æćƒˆć®ę§‹é€ ć‚’ē¶­ęŒć—ć¾ć™ć€‚
ć¤ć¾ć‚Šć€ćƒć‚¹ćƒˆć—ćŸć‚Ŗ惖ć‚ø悧ć‚Æ惈ćÆåˆ„ć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚Øćƒ³ćƒˆćƒŖćƒ¼ćØć—ć¦ę‰±ć‚ć‚Œć¾ć™ć€‚ć‚‚ć†ć²ćØ恤ćÆFLATTENEDć§ć€ćƒć‚¹ćƒˆć—ćŸć‚Ŗ惖ć‚ø悧ć‚Æ惈ćÆ
č¦Ŗć‚Ŗ惖ć‚ø悧ć‚Æ惈恮äø€éƒØćØ恗恦äæå­˜ć•ć‚Œć¾ć™ć€‚

Infinispanć®ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ć‹ć‚‰ć€č©²å½“ć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ęŽ¢ć—ć¦ćæć¾ć—ć‚‡ć†ć€‚org.infinispan.api.annotations.indexingćƒ‘ćƒƒć‚±ćƒ¼ć‚ø配äø‹ć«
恂悋悈恆恧恙怂

$ grep -rE 'Simplified version for Infinispan of|Infinispan version of' api/src/main/java/org/infinispan/api/annotations/indexing
api/src/main/java/org/infinispan/api/annotations/indexing/option/TermVector.java: * Simplified version for Infinispan of {@link org.hibernate.search.engine.backend.types.TermVector}
api/src/main/java/org/infinispan/api/annotations/indexing/option/Structure.java: * Simplified version for Infinispan of {@link org.hibernate.search.engine.backend.types.ObjectStructure}
api/src/main/java/org/infinispan/api/annotations/indexing/model/Point.java: * Simplified version for Infinispan of {@link org.hibernate.search.engine.spatial.GeoPoint}
api/src/main/java/org/infinispan/api/annotations/indexing/GeoCoordinates.java: * Infinispan version of {@link org.hibernate.search.mapper.pojo.bridge.builtin.annotation.GeoPointBinding}
api/src/main/java/org/infinispan/api/annotations/indexing/Longitude.java: * Infinispan version of {@link org.hibernate.search.mapper.pojo.bridge.builtin.annotation.Longitude}
api/src/main/java/org/infinispan/api/annotations/indexing/Text.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField}
api/src/main/java/org/infinispan/api/annotations/indexing/Embedded.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.IndexedEmbedded}
api/src/main/java/org/infinispan/api/annotations/indexing/Latitude.java: * Infinispan version of {@link org.hibernate.search.mapper.pojo.bridge.builtin.annotation.Latitude}
api/src/main/java/org/infinispan/api/annotations/indexing/Keyword.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.KeywordField}
api/src/main/java/org/infinispan/api/annotations/indexing/Decimal.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.ScaledNumberField}
api/src/main/java/org/infinispan/api/annotations/indexing/Basic.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField}
api/src/main/java/org/infinispan/api/annotations/indexing/Indexed.java: * Simplified version for Infinispan of {@link org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed}

https://github.com/infinispan/infinispan/tree/14.0.3.Final/api/src/main/java/org/infinispan/api/annotations/indexing

ć‚³ćƒ”ćƒ³ćƒˆć‚’č¦‹ć‚‹ćØ态Hibernate Searchć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć®Infinispanē‰ˆć§ć‚悋恓ćØ恌ę›øć‹ć‚Œć¦ć„ć¾ć™ć­ć€‚

åƾåæœč”Øć‚’ä½œć£ć¦ćæć¾ć—ć‚‡ć†ć€‚

Infinispanć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ Hibernate Searchć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³
org.infinispan.api.annotations.indexing.@Indexed org.hibernate.search.mapper.pojo.mapping.definition.annotation.@Indexed
org.infinispan.api.annotations.indexing.@Text org.hibernate.search.mapper.pojo.mapping.definition.annotation.@FullTextField
org.infinispan.api.annotations.indexing.@Basic org.hibernate.search.mapper.pojo.mapping.definition.annotation.@GenericField
org.infinispan.api.annotations.indexing.@Keyword org.hibernate.search.mapper.pojo.mapping.definition.annotation.@KeywordField
org.infinispan.api.annotations.indexing.@Decimal org.hibernate.search.mapper.pojo.mapping.definition.annotation.@ScaledNumberField
org.infinispan.api.annotations.indexing.@GeoCoordinates org.hibernate.search.mapper.pojo.bridge.builtin.annotation.@GeoPointBinding
org.infinispan.api.annotations.indexing.@Latitude org.hibernate.search.mapper.pojo.bridge.builtin.annotation.@Latitude
org.infinispan.api.annotations.indexing.@Longitude org.hibernate.search.mapper.pojo.bridge.builtin.annotation.@Longitude
org.infinispan.api.annotations.indexing.@Embedded org.hibernate.search.mapper.pojo.mapping.definition.annotation.@IndexedEmbedded
Infinispan恮ć‚Æćƒ©ć‚¹ć‚„enum Hibernate Search恮ć‚Æćƒ©ć‚¹ć‚„enum
org.infinispan.api.annotations.indexing.model.Point org.hibernate.search.engine.spatial.GeoPoint
org.infinispan.api.annotations.indexing.option.Structure org.hibernate.search.engine.backend.types.ObjectStructure
org.infinispan.api.annotations.indexing.option.TermVector org.hibernate.search.engine.backend.types.TermVector

ć“ć®ć‚ćŸć‚Šć®čŖ¬ę˜ŽćÆ态Hibernate Searchć®ćƒ‰ć‚­ćƒ„ćƒ”ćƒ³ćƒˆć‚’č¦‹ć‚‹ć®ćŒć‚ˆć„ć§ć—ć‚‡ć†ć€‚

Infinispan偓ćÆ态恂ćØćÆćƒ†ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć‚’å‚č€ƒć«ć€‚

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/dsl/embedded/testdomain

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/model

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/api

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/indexedembedded

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/queries

https://github.com/infinispan/infinispan/tree/14.0.3.Final/query/src/test/java/org/infinispan/query/test

https://github.com/infinispan/infinispan/tree/14.0.3.Final/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/annotation/model

今回ćÆ态ꖰ恗恄Inifinispanć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’ä½æć£ć¦ć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćØć‚Æć‚ØćƒŖćƒ¼ć‚’ä½æć£ć¦ćæć¾ć—ć‚‡ć†ć€‚

å°‘ć—č„±ē·šļ¼š Elasticsearch惐惃ć‚Æć‚Øćƒ³ćƒ‰

ćć®å‰ć«ć€å°‘ć—č„±ē·šć—恦怂

恝恆恄恈恰态Infinispan 9.0ć‹ć‚‰å®Ÿéؓēš„ćŖę©Ÿčƒ½ćØ恗恦Elasticsearch悒惐惃ć‚Æć‚Øćƒ³ćƒ‰ć«ć—ćŸę¤œē“¢ę©Ÿčƒ½ćŒć‚ć‚Šć¾ć—ćŸćŒć€11.0ć§å‰Šé™¤ć•ć‚Œć¦ć„ćŸ
ćæ恟恄恧恙恭怂

[ISPN-11646] Drop Elasticsearch support - Red Hat Issue Tracker

ISPN-11646 Drop Support for Elasticsearch by gustavocoding · Pull Request #8204 · infinispan/infinispan · GitHub

ć„ć‚„ć€ć‘ć£ć“ć†å‰ć‹ć‚‰ę°—ć„ć„ć¦ć„ćŸć‚“ć§ć™ćŒć€ęŒ™ć’ć‚‹ę©Ÿä¼šćŒćŖć‹ć£ćŸć®ć§ā€¦ć€‚

ćŠé”Œ

ä»Šå›žć®ćŠé”ŒćÆ态仄äø‹ć®ć‚ˆć†ć«ć—ćŸć„ćØę€ć„ć¾ć™ć€‚

  • Hot Rod Client悒ä½æ恆ļ¼ˆRemote Cache悒ä½æ恆ļ¼‰
  • Cacheć«ę ¼ē“ć™ć‚‹ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ćÆć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹å®šē¾©ćŖ恗态恂悊恮2ēØ®é”žć‚’ä½æ恆
    • Cacheć‚‚ćć‚Œćžć‚Œć«ä½œęˆć™ć‚‹
  • 恩恔悉恮Cache恫悂态ć‚Æć‚ØćƒŖćƒ¼ć‚’ęŠ•ć’ć¦ćæ悋

ē’°å¢ƒ

ä»Šå›žć®ē’°å¢ƒćÆ态恓恔悉怂

$ java --version
openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK 64-Bit Server VM (build 17.0.5+8-Ubuntu-2ubuntu120.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 17.0.5, 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-135-generic", arch: "amd64", family: "unix"

Infinispan ServerćÆ态172.18.0.2怜172.18.0.4恮3ć¤ć®ćƒŽćƒ¼ćƒ‰ć§å‹•ä½œć—ć€ć‚Æćƒ©ć‚¹ć‚æćƒ¼ć‚’ę§‹ęˆć—ć¦ć„ć‚‹ć‚‚ć®ćØć—ć¾ć™ć€‚

$ java --version
openjdk 17.0.5 2022-10-18
OpenJDK Runtime Environment Temurin-17.0.5+8 (build 17.0.5+8)
OpenJDK 64-Bit Server VM Temurin-17.0.5+8 (build 17.0.5+8, mixed mode, sharing)


$ bin/server.sh --version

Infinispan Server 14.0.3.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)

ęŗ–å‚™

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>

    <dependencies>
        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-api</artifactId>
            <version>14.0.3.Final</version>
        </dependency>
        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-client-hotrod</artifactId>
            <version>14.0.3.Final</version>
        </dependency>
        <dependency>
           <groupId>org.infinispan</groupId>
           <artifactId>infinispan-remote-query-client</artifactId>
            <version>14.0.3.Final</version>
        </dependency>
        <dependency>
           <groupId>org.infinispan</groupId>
           <artifactId>infinispan-query-dsl</artifactId>
            <version>14.0.3.Final</version>
        </dependency>
        <dependency>
            <groupId>org.infinispan.protostream</groupId>
            <artifactId>protostream-processor</artifactId>
            <version>4.5.0.Final</version>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-core</artifactId>
            <version>14.0.3.Final</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.9.1</version>
            <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>

依存関äæ‚ćØ恗恦态infinispan-api悒čæ½åŠ ć—ć¦ćŠćć¾ć™ć€‚ć¾ćŸć€Remote Query悒ä½æ恆恮恧infinispan-client-hotrod态infinispan-remote-query-client态
infinispan-query-dsl悂ä½æē”Øć—ć¾ć™ć€‚

各Infinispan Server恫ćÆ态恝悌恞悌ē®”ē†ē”Øćƒ¦ćƒ¼ć‚¶ćƒ¼ć€ć‚¢ćƒ—ćƒŖć‚±ćƒ¼ć‚·ćƒ§ćƒ³ē”Øćƒ¦ćƒ¼ć‚¶ćƒ¼ć‚’ä½œęˆć—ć¦ćŠćć¾ć™ć€‚

$ bin/cli.sh user create -g admin -p password ispn-admin
$ bin/cli.sh user create -g application -p password ispn-user

ćƒ†ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć®é››å½¢ć‚’ä½œęˆć™ć‚‹

動作ē¢ŗčŖćÆć€ćƒ†ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć§č”Œć„ć¾ć™ć€‚ć¾ćšćÆćć®é››å½¢ć‚’ę›øć„ć¦ćŠćć¾ć—ć‚‡ć†ć€‚

src/test/java/org/littlewings/infinispan/remote/query/RemoteQueryTest.java

package org.littlewings.infinispan.remote.query;

import java.util.List;
import java.util.function.Consumer;

import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
import org.infinispan.client.hotrod.RemoteCacheManagerAdmin;
import org.infinispan.client.hotrod.Search;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.IndexStartupMode;
import org.infinispan.configuration.cache.IndexStorage;
import org.infinispan.query.dsl.Query;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.remote.client.ProtobufMetadataManagerConstants;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class RemoteQueryTest {
    static String createUri(String userName, String password) {
        return String.format(
                "hotrod://%s:%s@172.18.0.2:11222,172.18.0.3:11222,172.18.0.4:11222"
                        + "?context-initializers=org.littlewings.infinispan.remote.query.EntitiesInitializerImpl",
                userName,
                password
        );
    }

    @BeforeAll
    static void setUpAll() {
        String uri = createUri("ispn-admin", "password");

        try (RemoteCacheManager manager = new RemoteCacheManager(uri)) {
            // create permission
            manager.getConfiguration().getContextInitializers().forEach(serializationContextInitializer -> {
                RemoteCache<String, String> protoCache = manager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
                protoCache.put("entities.proto", serializationContextInitializer.getProtoFile());
            });

            RemoteCacheManagerAdmin admin = manager.administration();

            org.infinispan.configuration.cache.Configuration indexLessDistCacheConfiguration =
                    new org.infinispan.configuration.cache.ConfigurationBuilder()
                            .clustering()
                            .cacheMode(org.infinispan.configuration.cache.CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            .build();

            admin.getOrCreateCache("bookCache", indexLessDistCacheConfiguration);

            org.infinispan.configuration.cache.Configuration indexedDistCacheConfiguration =
                    new ConfigurationBuilder()
                            .clustering()
                            .cacheMode(CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            // indexing
                            .indexing()
                            .enable()
                            .addIndexedEntities("entity.IndexedBook")
                            .storage(IndexStorage.FILESYSTEM)
                            .path("index/indexedBookCache")
                            .startupMode(IndexStartupMode.REINDEX)
                            .reader().refreshInterval(0L)
                            .writer().commitInterval(1000)
                            .build();

            admin.getOrCreateCache("indexedBookCache", indexedDistCacheConfiguration);
        }
    }

    <K, V> void withCache(String cacheName, Consumer<RemoteCache<K, V>> func) {
        String uri = createUri("ispn-user", "password");

        try (RemoteCacheManager manager = new RemoteCacheManager(uri)) {
            RemoteCache<K, V> cache = manager.getCache(cacheName);

            func.accept(cache);
        }
    }

    // ć“ć“ć«ć€ćƒ†ć‚¹ćƒˆć‚’ę›ø恏ļ¼ļ¼

}

Cacheć‚’ä½œęˆć™ć‚‹å‡¦ē†ćŖć©ćŒć‚ć‚‹ć®ć§ć™ćŒć€ćć‚ŒćÆå¾Œć§čŖ¬ę˜Žć—ć¾ć™ć€‚

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćŖ恗恧ć‚Æć‚ØćƒŖćƒ¼ć‚’ä½æ恆

ęœ€åˆćÆć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćŖ恗恧ć‚Æć‚ØćƒŖćƒ¼ć‚’ä½æć£ć¦ćæć¾ć—ć‚‡ć†ć€‚

ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ć®å®šē¾©ć€‚

src/main/java/org/littlewings/infinispan/remote/query/Book.java

package org.littlewings.infinispan.remote.query;

import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
import org.infinispan.protostream.descriptors.Type;

public class Book {
    @ProtoField(number = 1, type = Type.STRING)
    String isbn;

    @ProtoField(number = 2, type = Type.STRING)
    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ļ¼setterćÆēœē•„
}

MarshallingćÆProtoStreamćØć—ć¾ć™ć€‚

SerializationContextInitializerć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć‚’ē¶™ę‰æć—ćŸć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć‚’ä½œęˆć€‚

src/main/java/org/littlewings/infinispan/remote/query/EntitiesInitializer.java

package org.littlewings.infinispan.remote.query;

import org.infinispan.protostream.SerializationContextInitializer;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;

@AutoProtoSchemaBuilder(
        includeClasses = {Book.class},
        schemaFileName = "entities.proto",
        schemaFilePath = "proto/",
        schemaPackageName = "entity"
)
public interface EntitiesInitializer extends SerializationContextInitializer {
}

ć“ć®ć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć‚’ä½œęˆć—ć€ä¾å­˜é–¢äæ‚恫protostream-processorć‚’åŠ ćˆć¦ć„ć‚‹ćØć‚³ćƒ³ćƒ‘ć‚¤ćƒ«ć—ćŸę™‚ć«Protocol Buffers恮IDL恌
ē”Ÿęˆć•ć‚Œć‚‹ć‚ˆć†ć«ćŖć‚Šć¾ć™ć€‚

target/classes/proto/entities.proto

// File name: entities.proto
// Generated from : org.littlewings.infinispan.remote.query.EntitiesInitializer

syntax = "proto2";

package entity;



message Book {

   optional string isbn = 1;

   optional string title = 2;

   optional int32 price = 3 [default = 0];
}

ę¬”ć«ć€ćƒ†ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć«ē§»ć‚Šć¾ć™ć€‚

ꎄē¶šURLć®ä½œęˆć‹ć‚‰ć€‚context-initializersćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćƒ¼ć«ć€å…ˆć»ć©ä½œęˆć—ćŸSerializationContextInitializerć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć‚’ē¶™ę‰æć—ćŸć‚‚ć®ć‹ć‚‰
ē”Ÿęˆć•ć‚ŒćŸå®Ÿč£…ć‚Æćƒ©ć‚¹ć®FQCNć‚’ęŒ‡å®šć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚

    static String createUri(String userName, String password) {
        return String.format(
                "hotrod://%s:%s@172.18.0.2:11222,172.18.0.3:11222,172.18.0.4:11222"
                        + "?context-initializers=org.littlewings.infinispan.remote.query.EntitiesInitializerImpl",
                userName,
                password
        );
    }

Cacheć‚’ä½œęˆć—ć¾ć—ć‚‡ć†ć€‚

    @BeforeAll
    static void setUpAll() {
        String uri = createUri("ispn-admin", "password");

        try (RemoteCacheManager manager = new RemoteCacheManager(uri)) {
            // create permission
            manager.getConfiguration().getContextInitializers().forEach(serializationContextInitializer -> {
                RemoteCache<String, String> protoCache = manager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
                protoCache.put("entities.proto", serializationContextInitializer.getProtoFile());
            });

            RemoteCacheManagerAdmin admin = manager.administration();

            org.infinispan.configuration.cache.Configuration indexLessDistCacheConfiguration =
                    new org.infinispan.configuration.cache.ConfigurationBuilder()
                            .clustering()
                            .cacheMode(org.infinispan.configuration.cache.CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            .build();

            admin.getOrCreateCache("bookCache", indexLessDistCacheConfiguration);

            怜ēœē•„怜
        }
    }

ē”Ÿęˆć•ć‚ŒćŸProtocol Buffers恮IDL悒Infinispan Server恫ē™»éŒ²ć—ć¾ć™ć€‚

            // create permission
            manager.getConfiguration().getContextInitializers().forEach(serializationContextInitializer -> {
                RemoteCache<String, String> protoCache = manager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
                protoCache.put("entities.proto", serializationContextInitializer.getProtoFile());
            });

IDL悒ē™»éŒ²ć™ć‚‹ę–¹ę³•ćÆ态Web UI态CLI态REST API态Hot Rod Client恋悉APIå‘¼ć³å‡ŗ恗态SerializationContextInitializerć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć®å®Ÿč£…ć‚’
å«ć‚“ć JARćƒ•ć‚”ć‚¤ćƒ«ć‚’Infinispan Serverć«ćƒ‡ćƒ—ćƒ­ć‚¤ā€¦ćØć„ćć¤ć‹ę–¹ę³•ćŒć‚ć‚Šć¾ć™ćŒć€ä»Šå›žćÆHot Rod Client恋悉APIå‘¼ć³å‡ŗ恗恧ē™»éŒ²ć™ć‚‹
恓ćØć«ć—ć¾ć—ćŸć€‚

Encoding Infinispan caches and marshalling data / Marshalling custom objects with ProtoStream / Creating serialization context initializers / Registering Protobuf schemas with Infinispan Server

ē™»éŒ²ć—ćŸIDLćÆ态CLI恧ē¢ŗčŖć™ć‚‹ć“ćØć‚‚ć§ćć¾ć™ć€‚

[infinispan-server-29760@cluster//containers/default]> schema ls
[{"name":"entities.proto","error":null}]
[infinispan-server-29760@cluster//containers/default]> schema get entities.proto
[infinispan-server-29760@cluster//containers/default]> schema get entities.proto
// File name: entities.proto
// Generated from : org.littlewings.infinispan.remote.query.EntitiesInitializer

syntax = "proto2";

package entity;



message Book {

   optional string isbn = 1;

   optional string title = 2;

   optional int32 price = 3 [default = 0];
}

ć¾ćŸć€å…ˆć»ć©ć®ć‚³ćƒ¼ćƒ‰ć§ē™»éŒ²ć•ć‚Œć‚‹Distributed Cacheć®å®šē¾©ćÆ仄äø‹ć«ćŖć‚Šć¾ć™ć€‚

server/data/caches.xml

<?xml version="1.0"?>
<infinispan xmlns="urn:infinispan:config:14.0">
    <cache-container>
        <caches>
            <distributed-cache name="bookCache" mode="SYNC" remote-timeout="17500" statistics="true">
                <encoding>
                    <key media-type="application/x-protostream"/>
                    <value media-type="application/x-protostream"/>
                </encoding>
                <locking concurrency-level="1000" acquire-timeout="15000" striping="false"/>
                <state-transfer timeout="60000"/>
            </distributed-cache>
        </caches>
    </cache-container>
</infinispan>

恂ćØćÆćƒ‡ćƒ¼ć‚æ悒ē™»éŒ²ć—恦态ć‚Æć‚ØćƒŖćƒ¼ć‚’ęŠ•ć’ć‚‹ćƒ—ćƒ­ć‚°ćƒ©ćƒ ć‚’ę›ø恑恰OK恧恙怂

    @Test
    public void indexLessQuery() {
        this.<String, Book>withCache("bookCache", cache -> {
            List<Book> books = List.of(
                    Book.create("978-1782169970", "Infinispan Data Grid Platform Definitive Guide", 5242),
                    Book.create("978-4048917353", "Rediså…„é–€ ć‚¤ćƒ³ćƒ”ćƒ¢ćƒŖKVSć«ć‚ˆć‚‹é«˜é€Ÿćƒ‡ćƒ¼ć‚æē®”ē†", 3400),
                    Book.create("978-4798045733", "RDBęŠ€č”“č€…ć®ćŸć‚ć®NoSQLć‚¬ć‚¤ćƒ‰", 3400),
                    Book.create("978-1785285332", "Getting Started with Hazelcast - Second Edition", 4129),
                    Book.create("978-1789347531", "Apache Ignite Quick Start Guide: Distributed data caching and processing made easy", 3476)
            );

            books.forEach(book -> cache.put(book.getIsbn(), book));

            assertThat(cache.size()).isEqualTo(5);

            QueryFactory queryFactory = Search.getQueryFactory(cache);
            Query<Book> query =
                    queryFactory.create("from entity.Book where price > :price order by price desc");
            query.setParameter("price", 4000);

            List<Book> results = query.execute().list();

            assertThat(results).hasSize(2);
            assertThat(results.get(0).getTitle()).isEqualTo("Infinispan Data Grid Platform Definitive Guide");
            assertThat(results.get(1).getTitle()).isEqualTo("Getting Started with Hazelcast - Second Edition");
        });
    }

Ickle Query悒ä½æć†ćŸć‚ć®API恮ē“¹ä»‹ćÆ恓恔悉怂

Querying Infinispan caches / Creating Ickle queries / Ickle queries

ćć—ć¦ć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’ä½æ悏ćŖć„å “åˆć®ć‚Æć‚ØćƒŖćƒ¼ć®ę§‹ę–‡ćÆ恓恔悉恧恙怂

Querying Infinispan caches / Creating Ickle queries / Ickle query language syntax

ä»Šå›žć®ć‚Æć‚ØćƒŖćƒ¼ćÆDistributed Cache恫åÆ¾ć—ć¦ć‚½ćƒ¼ćƒˆć‚’č”Œć£ć¦ć„ć¾ć™ćŒ

            Query<Book> query =
                    queryFactory.create("from entity.Book where price > :price order by price desc");

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćŒćŖ恄ēŠ¶ę…‹ć§ć“ć®ć‚ˆć†ćŖć‚½ćƒ¼ćƒˆć‚’č”Œć†ćØ态Infinispan Serverå“ć§WARN惭悰恌å‡ŗåŠ›ć•ć‚Œć‚‹ć“ćØ恫ćŖć‚Šć¾ć™ć€‚

2022-12-02 15:11:52,527 WARN  (blocking-thread--p3-t1) [org.infinispan.query.core.impl.BaseEmbeddedQuery] ISPN014827: Distributed sort not supported for non-indexed query 'from entity.Book where price > :price order by price desc'. Consider using an index for optimal performance.

ćƒ‘ćƒ•ć‚©ćƒ¼ćƒžćƒ³ć‚¹ćŒč‰Æ恏ćŖ恄恧恙悈态ćØ恄恆恓ćØ恧恙恭怂

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’å®šē¾©ć—恦ć‚Æć‚ØćƒŖćƒ¼ć‚’å®Ÿč”Œć™ć‚‹

ē¶šć„恦ćÆć€ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’å®šē¾©ć—恦ć‚Æć‚ØćƒŖćƒ¼ć‚’å®Ÿč”Œć—ć¦ćæć¾ć—ć‚‡ć†ć€‚

ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ć®å®šē¾©ć€‚

src/main/java/org/littlewings/infinispan/remote/query/IndexedBook.java

package org.littlewings.infinispan.remote.query;

import org.infinispan.api.annotations.indexing.Basic;
import org.infinispan.api.annotations.indexing.Indexed;
import org.infinispan.api.annotations.indexing.Keyword;
import org.infinispan.api.annotations.indexing.Text;
import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
import org.infinispan.protostream.descriptors.Type;

@Indexed
public class IndexedBook {
    @Keyword(sortable = true)
    @ProtoField(number = 1, type = Type.STRING)
    String isbn;

    // ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆć®AnalyzerćÆstandard
    @Text(analyzer = "standard")
    @ProtoField(number = 2, type = Type.STRING)
    String title;

    @Basic(sortable = true)
    @ProtoField(number = 3, type = Type.INT32, defaultValue = "0")
    int price;

    @ProtoFactory
    public static IndexedBook create(String isbn, String title, int price) {
        IndexedBook book = new IndexedBook();
        book.setIsbn(isbn);
        book.setTitle(title);
        book.setPrice(price);

        return book;
    }

    // getterļ¼setterćÆēœē•„
}

ć“ć“ć§ć€ä»Šå›žć®äø»é”Œć§ć‚ć‚‹Infinispanć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćŒå‡ŗć¦ćć¾ć™ć€‚

ć™ć§ć«ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³č‡Ŗ体ćÆē“¹ä»‹ć—ć¦ć„ć¾ć™ćŒć€ć“ć‚Œć‚‰ć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćÆinfinispan-apić«å«ć¾ć‚Œć¦ć„ć¾ć™ć€‚

        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-api</artifactId>
            <version>14.0.3.Final</version>
        </dependency>

SerializationContextInitializerć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć‚’ē¶™ę‰æć—ćŸć‚¤ćƒ³ć‚æćƒ¼ćƒ•ć‚§ćƒ¼ć‚¹ć€‚

src/main/java/org/littlewings/infinispan/remote/query/EntitiesInitializer.java

package org.littlewings.infinispan.remote.query;

import org.infinispan.protostream.SerializationContextInitializer;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;

@AutoProtoSchemaBuilder(
        includeClasses = {IndexedBook.class},
        schemaFileName = "entities.proto",
        schemaFilePath = "proto/",
        schemaPackageName = "entity"
)
public interface EntitiesInitializer extends SerializationContextInitializer {
}

ē”Ÿęˆć•ć‚ŒćŸProtocol Buffers恮IDLć€‚ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć®čؘčæ°ćŒć‚³ćƒ”ćƒ³ćƒˆćØć—ć¦ę®‹ć£ć¦ć„ć¾ć™ć€‚

target/classes/proto/entities.proto

// File name: entities.proto
// Generated from : org.littlewings.infinispan.remote.query.EntitiesInitializer

syntax = "proto2";

package entity;



/**
 * @Indexed
 */
message IndexedBook {

   /**
    * @Keyword(sortable=true)
    */
   optional string isbn = 1;

   /**
    * @Text(analyzer="standard")
    */
   optional string title = 2;

   /**
    * @Basic(sortable=true)
    */
   optional int32 price = 3 [default = 0];
}

Cacheć®å®šē¾©ć€‚

    @BeforeAll
    static void setUpAll() {
        String uri = createUri("ispn-admin", "password");

        try (RemoteCacheManager manager = new RemoteCacheManager(uri)) {
            // create permission
            manager.getConfiguration().getContextInitializers().forEach(serializationContextInitializer -> {
                RemoteCache<String, String> protoCache = manager.getCache(ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME);
                protoCache.put("entities.proto", serializationContextInitializer.getProtoFile());
            });

            RemoteCacheManagerAdmin admin = manager.administration();

            怜ēœē•„怜

            org.infinispan.configuration.cache.Configuration indexedDistCacheConfiguration =
                    new ConfigurationBuilder()
                            .clustering()
                            .cacheMode(CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            // indexing
                            .indexing()
                            .enable()
                            .addIndexedEntities("entity.IndexedBook")
                            .storage(IndexStorage.FILESYSTEM)
                            .path("${infinispan.server.data.path}/index/indexedBookCache")
                            //.path("index/indexedBookCache")
                            .startupMode(IndexStartupMode.REINDEX)
                            .reader().refreshInterval(0L)
                            .writer().commitInterval(1000)
                            .build();

            admin.getOrCreateCache("indexedBookCache", indexedDistCacheConfiguration);
        }
    }

Infinispan Server恫ē™»éŒ²ć•ć‚ŒćŸProtocol Buffers恮IDL怂

[infinispan-server-48098@cluster//containers/default]> schema get entities.proto
// File name: entities.proto
// Generated from : org.littlewings.infinispan.remote.query.EntitiesInitializer

syntax = "proto2";

package entity;



/**
 * @Indexed
 */
message IndexedBook {

   /**
    * @Keyword(sortable=true)
    */
   optional string isbn = 1;

   /**
    * @Text(analyzer="standard")
    */
   optional string title = 2;

   /**
    * @Basic(sortable=true)
    */
   optional int32 price = 3 [default = 0];
}

Infinispan Serverå“ć§ē”Ÿęˆć•ć‚Œć‚‹Cacheć®å®šē¾©ć€‚

server/data/caches.xml

<?xml version="1.0"?>
<infinispan xmlns="urn:infinispan:config:14.0">
    <cache-container>
        <caches>
            <distributed-cache name="indexedBookCache" mode="SYNC" remote-timeout="17500" statistics="true">
                <encoding>
                    <key media-type="application/x-protostream"/>
                    <value media-type="application/x-protostream"/>
                </encoding>
                <locking concurrency-level="1000" acquire-timeout="15000" striping="false"/>
                <indexing enabled="true" storage="filesystem" startup-mode="REINDEX" path="/opt/infinispan-server/server/data/index/indexedBookCache">
                    <index-writer commit-interval="1000"/>
                    <indexed-entities>
                        <indexed-entity>entity.IndexedBook</indexed-entity>
                    </indexed-entities>
                </indexing>
                <state-transfer timeout="60000"/>
            </distributed-cache>
        </caches>
    </cache-container>
</infinispan>

ć“ć®ć‚ćŸć‚ŠćŒć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć®čح定ćŖć®ć§ć™ćŒ

                            // indexing
                            .indexing()
                            .enable()
                            .addIndexedEntities("entity.IndexedBook")
                            .storage(IndexStorage.FILESYSTEM)
                            .path("${infinispan.server.data.path}/index/indexedBookCache")
                            //.path("index/indexedBookCache")
                            .startupMode(IndexStartupMode.REINDEX)
                            .reader().refreshInterval(0L)
                            .writer().commitInterval(1000)

čŖ¬ę˜ŽćÆć€ć“ć®ć‚ćŸć‚Šć«ć‚ć‚Šć¾ć™ć­ć€‚

Querying Infinispan caches / Indexing Infinispan caches / Configuring Infinispan to index caches / Index configuration

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’ęœ‰åŠ¹ć«ć—ć¦

                            .indexing()
                            .enable()

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹äæå­˜ć®åÆ¾č±”ćØ恙悋ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ć‚’ē™»éŒ²ć€‚

                            .addIndexedEntities("entity.IndexedBook")

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć®äæå­˜å “ꉀćÆć€ä»Šå›žćÆćƒ•ć‚”ć‚¤ćƒ«ć‚·ć‚¹ćƒ†ćƒ ćØć—ć¾ć—ćŸć€‚

                            .storage(IndexStorage.FILESYSTEM)
                            .path("${infinispan.server.data.path}/index/indexedBookCache")

恔ćŖćæ恫态恓恆ę›ø恄恦悂äæå­˜å “ꉀćÆå¤‰ć‚ć‚Šć¾ć›ć‚“ć€‚

                            .storage(IndexStorage.FILESYSTEM)
                            .path("index/indexedBookCache")

ć“ć®å “åˆć€${infinispan.server.data.path}恋悉恮ē›øåÆ¾ćƒ‘ć‚¹ćØć—ć¦č§£ę±ŗć•ć‚Œć¾ć™ć€‚

                <indexing enabled="true" storage="filesystem" startup-mode="REINDEX" path="index/indexedBookCache">
                    <index-writer commit-interval="1000"/>
                    <indexed-entities>
                        <indexed-entity>entity.IndexedBook</indexed-entity>
                    </indexed-entities>
                </indexing>

恓恔悉恫恤恄恦ćÆć€å¾Œć§å°‘ć—ę›øćć¾ć™ć€‚

ć‚Æć‚ØćƒŖćƒ¼ć‚’ä½æć£ćŸćƒ†ć‚¹ćƒˆć‚³ćƒ¼ćƒ‰ć€‚

    @Test
    public void indexedQuery() {
        this.<String, IndexedBook>withCache("indexedBookCache", cache -> {
            List<IndexedBook> books = List.of(
                    IndexedBook.create("978-1782169970", "Infinispan Data Grid Platform Definitive Guide", 5242),
                    IndexedBook.create("978-4048917353", "Rediså…„é–€ ć‚¤ćƒ³ćƒ”ćƒ¢ćƒŖKVSć«ć‚ˆć‚‹é«˜é€Ÿćƒ‡ćƒ¼ć‚æē®”ē†", 3400),
                    IndexedBook.create("978-4798045733", "RDBęŠ€č”“č€…ć®ćŸć‚ć®NoSQLć‚¬ć‚¤ćƒ‰", 3400),
                    IndexedBook.create("978-1785285332", "Getting Started with Hazelcast - Second Edition", 4129),
                    IndexedBook.create("978-1789347531", "Apache Ignite Quick Start Guide: Distributed data caching and processing made easy", 3476)
            );

            books.forEach(book -> cache.put(book.getIsbn(), book));

            assertThat(cache.size()).isEqualTo(5);

            QueryFactory queryFactory = Search.getQueryFactory(cache);

            Query<IndexedBook> query1 =
                    queryFactory.create("from entity.IndexedBook where title: 'guide' and price: [4000 to *] order by price");

            List<IndexedBook> results1 = query1.execute().list();

            assertThat(results1).hasSize(1);
            assertThat(results1.get(0).getTitle()).isEqualTo("Infinispan Data Grid Platform Definitive Guide");

            Query<IndexedBook> query2 =
                    queryFactory.create("from entity.IndexedBook where isbn = '978-4048917353'");

            List<IndexedBook> results2 = query2.execute().list();

            assertThat(results2).hasSize(1);
            assertThat(results2.get(0).getTitle()).isEqualTo("Rediså…„é–€ ć‚¤ćƒ³ćƒ”ćƒ¢ćƒŖKVSć«ć‚ˆć‚‹é«˜é€Ÿćƒ‡ćƒ¼ć‚æē®”ē†");

            Query<IndexedBook> query3 =
                    queryFactory.create("from entity.IndexedBook where (title: 'data' and title: 'guide') or price: [* to 3400] order by price desc, isbn asc");

            List<IndexedBook> results3 = query3.execute().list();

            assertThat(results3).hasSize(4);
            assertThat(results3.get(0).getTitle()).isEqualTo("Infinispan Data Grid Platform Definitive Guide");
            assertThat(results3.get(1).getTitle()).isEqualTo("Apache Ignite Quick Start Guide: Distributed data caching and processing made easy");
            assertThat(results3.get(2).getTitle()).isEqualTo("Rediså…„é–€ ć‚¤ćƒ³ćƒ”ćƒ¢ćƒŖKVSć«ć‚ˆć‚‹é«˜é€Ÿćƒ‡ćƒ¼ć‚æē®”ē†");
            assertThat(results3.get(3).getTitle()).isEqualTo("RDBęŠ€č”“č€…ć®ćŸć‚ć®NoSQLć‚¬ć‚¤ćƒ‰");
        });
    }

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’ęœ‰åŠ¹ć«ć—ć¦ć„ć‚‹ćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«åÆ¾ć™ć‚‹ć‚Æć‚ØćƒŖćƒ¼ę§‹ę–‡ćÆ态恓恔悉怂

Querying Infinispan caches / Creating Ickle queries / Full-text queries

ć“ć®ć‚ćŸć‚Šć§ć™ć­ć€‚

            Query<IndexedBook> query1 =
                    queryFactory.create("from entity.IndexedBook where title: 'guide' and price: [4000 to *] order by price");


            怜ēœē•„怜


            Query<IndexedBook> query3 =
                    queryFactory.create("from entity.IndexedBook where (title: 'data' and title: 'guide') or price: [* to 3400] order by price desc, isbn asc");

ā€» ćƒ•ćƒ«ćƒ†ć‚­ć‚¹ćƒˆć‚Æć‚ØćƒŖćƒ¼ć«åÆ¾ć—ć¦ćÆć€ćƒć‚¤ćƒ³ćƒ‰ćƒ‘ćƒ©ćƒ”ćƒ¼ć‚æćÆäø€éƒØå‹•ä½œć—ćŖ恄悈恆ćŖć®ć§ć€ä»Šå›žåÆ¾č±”å¤–ć«ć—ć¦ć„ć¾ć™

@Keywordć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćÆć‚¢ćƒŠćƒ©ć‚¤ć‚ŗć‚’č”Œć‚ćŖ恄恟悁态通åøø恮ć‚Æć‚ØćƒŖćƒ¼ć®ę§‹ę–‡ć«ćŖć‚Šć¾ć™ć€‚

            Query<IndexedBook> query2 =
                    queryFactory.create("from entity.IndexedBook where isbn = '978-4048917353'");

ć¾ćŸć€ć‚½ćƒ¼ćƒˆć‚’ć—ćŸć„ćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«åÆ¾ć—ć¦ćÆ

            Query<IndexedBook> query1 =
                    queryFactory.create("from entity.IndexedBook where title: 'guide' and price: [4000 to *] order by price");


            怜ēœē•„怜


            Query<IndexedBook> query3 =
                    queryFactory.create("from entity.IndexedBook where (title: 'data' and title: 'guide') or price: [* to 3400] order by price desc, isbn asc");

꘎ē¤ŗēš„恫sortable悒true恫恙悋åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚

    @Keyword(sortable = true)
    @ProtoField(number = 1, type = Type.STRING)
    String isbn;

    怜ēœē•„怜

    @Basic(sortable = true)
    @ProtoField(number = 3, type = Type.INT32, defaultValue = "0")
    int price;

ć‚¢ćƒŠćƒ©ć‚¤ć‚ŗć‚’č”Œć†@Textć®ć‚ˆć†ćŖćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«åÆ¾ć—ć¦ćÆć€ć‚½ćƒ¼ćƒˆćÆęœ‰åŠ¹ć«ć§ćć¾ć›ć‚“ć€‚

äæå­˜ć•ć‚ŒćŸć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ćÆ态恓恔悉怂

$ ll server/data/index/indexedBookCache/entity.IndexedBook
total 24
drwxr-xr-x 2 xxxxx xxxxx 4096 Dec  2 15:32 ./
drwxr-xr-x 3 xxxxx xxxxx 4096 Dec  2 15:32 ../
-rw-r--r-- 1 xxxxx xxxxx  479 Dec  2 15:32 _0.cfe
-rw-r--r-- 1 xxxxx xxxxx 3632 Dec  2 15:32 _0.cfs
-rw-r--r-- 1 xxxxx xxxxx  373 Dec  2 15:32 _0.si
-rw-r--r-- 1 xxxxx xxxxx  154 Dec  2 15:32 segments_2
-rw-r--r-- 1 xxxxx xxxxx    0 Dec  2 15:32 write.lock

ćØ悊恂恈恚态ē°”å˜ć«ć§ć™ćŒInfinispanć®ę–°ć—ć„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’č©¦ć—ć¦ćæć¾ć—ćŸć€‚

2恤恮ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ć®å†…å®¹ć‚’åˆć‚ć›ćŸå®šē¾©

ć“ć“ć¾ć§2恤恮ć‚Øćƒ³ćƒ†ć‚£ćƒ†ć‚£ć‚’ćć‚Œćžć‚Œåˆ„ć€…ć«ä½æć„ć¾ć—ćŸćŒć€åˆć‚ć›ćŸę™‚ć®å®šē¾©ć‚‚č¼‰ć›ć¦ćŠćć¾ć™ć€‚ć‚Ŗćƒžć‚±ēš„ć§ć™ćŒć€‚

src/main/java/org/littlewings/infinispan/remote/query/EntitiesInitializer.java

package org.littlewings.infinispan.remote.query;

import org.infinispan.protostream.SerializationContextInitializer;
import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder;

@AutoProtoSchemaBuilder(
        includeClasses = {Book.class, IndexedBook.class},
        schemaFileName = "entities.proto",
        schemaFilePath = "proto/",
        schemaPackageName = "entity"
)
public interface EntitiesInitializer extends SerializationContextInitializer {
}
[infinispan-server-63828@cluster//containers/default]> schema get entities.proto
// File name: entities.proto
// Generated from : org.littlewings.infinispan.remote.query.EntitiesInitializer

syntax = "proto2";

package entity;



/**
 * @Indexed
 */
message IndexedBook {

   /**
    * @Keyword(sortable=true)
    */
   optional string isbn = 1;

   /**
    * @Text(analyzer="standard")
    */
   optional string title = 2;

   /**
    * @Basic(sortable=true)
    */
   optional int32 price = 3 [default = 0];
}


message Book {

   optional string isbn = 1;

   optional string title = 2;

   optional int32 price = 3 [default = 0];
}

恓恔悉恮2恤恮Cacheć‚’ä½œęˆć—ćŸéš›ć«ć€

            org.infinispan.configuration.cache.Configuration indexLessDistCacheConfiguration =
                    new org.infinispan.configuration.cache.ConfigurationBuilder()
                            .clustering()
                            .cacheMode(org.infinispan.configuration.cache.CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            .build();

            admin.getOrCreateCache("bookCache", indexLessDistCacheConfiguration);

            org.infinispan.configuration.cache.Configuration indexedDistCacheConfiguration =
                    new ConfigurationBuilder()
                            .clustering()
                            .cacheMode(CacheMode.DIST_SYNC)
                            .encoding().key().mediaType("application/x-protostream")
                            .encoding().value().mediaType("application/x-protostream")
                            // indexing
                            .indexing()
                            .enable()
                            .addIndexedEntities("entity.IndexedBook")
                            .storage(IndexStorage.FILESYSTEM)
                            .path("${infinispan.server.data.path}/index/indexedBookCache")
                            //.path("index/indexedBookCache")
                            .startupMode(IndexStartupMode.REINDEX)
                            .reader().refreshInterval(0L)
                            .writer().commitInterval(1000)
                            .build();

            admin.getOrCreateCache("indexedBookCache", indexedDistCacheConfiguration);

Infinispan Serverå“ć§ē”Ÿęˆć•ć‚Œć‚‹Cache定ē¾©ć€‚

server/data/caches.xml

<?xml version="1.0"?>
<infinispan xmlns="urn:infinispan:config:14.0">
    <cache-container>
        <caches>
            <distributed-cache name="bookCache" mode="SYNC" remote-timeout="17500" statistics="true">
                <encoding>
                    <key media-type="application/x-protostream"/>
                    <value media-type="application/x-protostream"/>
                </encoding>
                <locking concurrency-level="1000" acquire-timeout="15000" striping="false"/>
                <state-transfer timeout="60000"/>
            </distributed-cache>
            <distributed-cache name="indexedBookCache" mode="SYNC" remote-timeout="17500" statistics="true">
                <encoding>
                    <key media-type="application/x-protostream"/>
                    <value media-type="application/x-protostream"/>
                </encoding>
                <locking concurrency-level="1000" acquire-timeout="15000" striping="false"/>
                <indexing enabled="true" storage="filesystem" startup-mode="REINDEX" path="/opt/infinispan-server/server/data/index/indexedBookCache">
                    <index-writer commit-interval="1000"/>
                    <indexed-entities>
                        <indexed-entity>entity.IndexedBook</indexed-entity>
                    </indexed-entities>
                </indexing>
                <state-transfer timeout="60000"/>
            </distributed-cache>
        </caches>
    </cache-container>
</infinispan>

å°‘ć—å®Ÿč£…ć‚’čæ½ć£ć¦ćæ悋

今回ćÆInfinispanć®ę–°ć—ć„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’č¦‹ć¦ććŸć®ć§ć™ćŒć€ć“ć‚Œć‚‰ćÆHibernate SearchćØć©ć®ć‚ˆć†ćŖ関äæ‚ćŒć‚ć‚‹ć®ć§ć—ć‚‡ć†ć‹ļ¼Ÿ

ē­”ćˆćÆć€ć“ć®ć‚ćŸć‚Šć«ć‚ć‚Šćć†ć§ć™ć€‚

https://github.com/infinispan/infinispan/tree/14.0.3.Final/api/src/main/java/org/infinispan/api/common/annotations/indexing/_private

TextProcessorć‚’ä¾‹ć«č¦‹ć¦ćæć¾ć—ć‚‡ć†ć€‚

package org.infinispan.api.common.annotations.indexing._private;

import org.hibernate.search.mapper.pojo.mapping.definition.annotation.processing.PropertyMappingAnnotationProcessor;
import org.hibernate.search.mapper.pojo.mapping.definition.annotation.processing.PropertyMappingAnnotationProcessorContext;
import org.hibernate.search.mapper.pojo.mapping.definition.programmatic.PropertyMappingFullTextFieldOptionsStep;
import org.hibernate.search.mapper.pojo.mapping.definition.programmatic.PropertyMappingStep;
import org.infinispan.api.annotations.indexing.Text;

public class TextProcessor implements PropertyMappingAnnotationProcessor<Text> {

   @Override
   public void process(PropertyMappingStep mapping, Text annotation, PropertyMappingAnnotationProcessorContext context) {
      String name = annotation.name();
      PropertyMappingFullTextFieldOptionsStep fullTextField = (name.isEmpty()) ?
            mapping.fullTextField() : mapping.fullTextField(name);

      fullTextField.analyzer(annotation.analyzer());

      String searchAnalyzer = annotation.searchAnalyzer();
      if (!searchAnalyzer.isEmpty()) {
         fullTextField.searchAnalyzer(searchAnalyzer);
      }

      fullTextField.norms(Options.norms(annotation.norms()));
      fullTextField.termVector(Options.termVector(annotation.termVector()));
      fullTextField.projectable(Options.projectable(annotation.projectable()));
      fullTextField.searchable(Options.searchable(annotation.searchable()));
   }
}

https://github.com/infinispan/infinispan/blob/14.0.3.Final/api/src/main/java/org/infinispan/api/common/annotations/indexing/_private/TextProcessor.java

恩恆悄悉态Hibernate Searchć®ć‚«ć‚¹ć‚æćƒ ćƒžćƒƒćƒ”ćƒ³ć‚°ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćØ恄恆仕ēµ„ćæ悒ä½æć£ć¦ć„ć‚‹ćæ恟恄恧恙恭怂

Hibernate Search: Reference Documentation / Mapping Hibernate ORM entities to indexes / Custom mapping annotations

@Textć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćŠć‚ˆć³TextProcessorć®å®£čØ€ć‚’č¦‹ć‚‹ćØć€é–¢é€£ćŒć‚ć‚‹ć®ćŒć‚ć‹ć‚Šć¾ć™ć­ć€‚

@Documented
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Text.List.class)
@PropertyMapping(processor = @PropertyMappingAnnotationProcessorRef(type = TextProcessor.class, retrieval = BeanRetrieval.CONSTRUCTOR))
public @interface Text {


public class TextProcessor implements PropertyMappingAnnotationProcessor<Text> {

恓恮仕ēµ„ćæćŒć„ć¤å‹•ä½œć—ć¦ć„ć‚‹ć‹ćØ恄恆ćØć€ćƒ•ć‚£ćƒ¼ćƒ«ćƒ‰ć«ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćŒä»˜äøŽć•ć‚Œć¦ć„ć‚‹ć®ć‚’ę¤œå‡ŗ恗恟ć‚æć‚¤ćƒŸćƒ³ć‚°ć®ć‚ˆć†ć§ć™ćŒć€
Hot Rod Clientč‡Ŗ体ćÆHibernate Search恫ćÆä¾å­˜ć—ć¦ć„ćŖ恄恮恧态Infinispan Serverå†…ć§å‹•ä½œć—ć¦ć„ć‚‹ć“ćØ恫ćŖć‚Šć¾ć™ć­ć€‚

ćØć„ć†ć‚ć‘ć§ć€č¦‹ćŸē›®ćÆInfinispanć‚ŖćƒŖć‚øćƒŠćƒ«ć®ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćŖć®ć§ć™ćŒć€å®Ÿéš›ć«ćÆHibernate Searchć®å‡¦ē†ć«å¤‰ę›ć•ć‚Œć¦
å‹•ä½œć™ć‚‹ć€ćØć„ć†ć®ćŒč£čˆžå°ć®ć‚ˆć†ć§ć™ć€‚

ć¾ćŸć€ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ćØćÆ関äæ‚ćŖć„ć®ć§ć™ćŒć€ęœ€åˆćÆć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć®äæå­˜å…ˆć‚’仄äø‹ć®ć‚ˆć†ć«ē›øåÆ¾ćƒ‘ć‚¹ć«ęŒ‡å®šć™ć‚‹ćØ恩恓恫äæå­˜ć•ć‚Œć‚‹ć®ć‹ćŖćØ
ę€ć£ć¦č©¦ć—ć¦ćæćŸć®ć§ć™ćŒ

                            .indexing()
                            .enable()
                            .addIndexedEntities("entity.IndexedBook")
                            .storage(IndexStorage.FILESYSTEM)
                            .path("index/indexedBookCache")

ēµęžœćÆ态[Infinispan Serverć®ć‚¤ćƒ³ć‚¹ćƒˆćƒ¼ćƒ«ćƒ‡ć‚£ćƒ¬ć‚Æ惈ćƒŖ]/server/dataćƒ‡ć‚£ćƒ¬ć‚Æ惈ćƒŖå†…ć®ē›øåÆ¾ćƒ‘ć‚¹ćØć—ć¦č§£é‡ˆć•ć‚Œć¾ć—ćŸć€‚

ć©ć†ć„ć†č§£ę±ŗ恫ćŖć£ć¦ć„ć‚‹ć®ć‹ćŖļ¼ŸćØę€ć£ć¦č¦‹ć¦ćæć¾ć—ćŸć€‚

仄äø‹ć‚’見悋ćØć€ćƒ‘ć‚¹ęŒ‡å®šćŒēµ¶åÆ¾ćƒ‘ć‚¹ć®å “åˆćÆćć®ć¾ć¾ä½æ恄态ē›øåÆ¾ćƒ‘ć‚¹ć®å “åˆćÆGlobalStateConfiguration#persistentLocation恋悉恮
ē›øåÆ¾ćƒ‘ć‚¹ćØć—ć¦č§£é‡ˆć•ć‚Œć‚‹ć‚ˆć†ć§ć™ć€‚

https://github.com/infinispan/infinispan/blob/14.0.3.Final/query/src/main/java/org/infinispan/query/impl/config/SearchPropertyExtractor.java#L157-L166

恓恮čØ­å®šć‚’ę§‹ēÆ‰ć—ć¦ć„ć‚‹ć®ćÆć“ć”ć‚‰ć®ć‚ˆć†ć§ć™ćŒć€

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/java/org/infinispan/server/Server.java#L307

Inifnispan Serverć®ćƒ‡ćƒ•ć‚©ćƒ«ćƒˆčØ­å®šć‚’čŖ­ćæč¾¼ć‚“ć§ć„ć‚‹ć®ćÆ恓恔悉怂

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/java/org/infinispan/server/Server.java#L298-L299

čØ­å®šćƒ•ć‚”ć‚¤ćƒ«ć‚’č¦‹ć‚‹ćØ态${infinispan.server.data.path}ćŒęŒ‡ć™å€¤ćŒćƒ‡ćƒ•ć‚©ćƒ«ćƒˆå€¤ć«ćŖć£ć¦ć„ć¾ć™ć€‚

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/resources/infinispan-defaults.xml#L12

ćć®å®Ÿéš›ć®å€¤ćÆćØ恄恆ćØ态server/data恧恙恭怂

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/java/org/infinispan/server/Server.java#L254

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/java/org/infinispan/server/Server.java#L176

https://github.com/infinispan/infinispan/blob/14.0.3.Final/server/runtime/src/main/java/org/infinispan/server/Server.java#L179

ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ć‚’é©å½“ć«č©¦ć—ć¦ć„ć‚‹ę™‚ćÆćƒ”ćƒ¢ćƒŖäøŠć«äæå­˜ć—恦恄悋恓ćØćŒå¤šć‹ć£ćŸć®ć§ć€ä»Šå›žć”ć‚‡ć£ćØčˆˆå‘³ć‚’ęŒć£ć¦č¦‹ć¦ćæć¾ć—ćŸć€‚

ć¾ćØ悁

Infinispanć®ę–°ć—ć„ć‚¤ćƒ³ćƒ‡ćƒƒć‚Æć‚¹ē”Øć®ć‚¢ćƒŽćƒ†ćƒ¼ć‚·ćƒ§ćƒ³ć‚’č©¦ć—ć¦ćæć¾ć—ćŸć€‚

å®Ÿéš›ć®ćØ恓悍ćÆHibernate Searchć®å‡¦ē†ć«čŖ­ćæę›æćˆć‚‰ć‚Œć‚‹ć®ć§ć€ē‰¹ć«ćŖć«ć‹ę–°ć—ć„å‹•ä½œćŒåŠ ć‚ć£ćŸć‚ć‘ć§ć‚‚ć‚ć‚Šć¾ć›ć‚“ć€‚ćŖć®ć§ć€ęƒ…å ±č‡Ŗ体ćÆ
ćŖć‹ć£ćŸć®ć§ć™ćŒćć‚Œć»ć©å›°ć‚‰ćšć«ä½æćˆć¾ć—ćŸć€‚

Hibernate SearchćØć©ć†ć„ć†é–¢äæ‚ć«ć‚ć‚‹ć‚“ć ć‚ć†ļ¼ŸćØčŖæć¹ćŸć‚Šć™ć‚‹ćØ恓悍ćÆć€ćć“ćć“ę™‚é–“ćŒć‹ć‹ć‚Šć¾ć—ćŸć‘ć©ć­ć€‚

ä»Šå›žä½œęˆć—ćŸć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰ćÆ态恓恔悉恫ē½®ć„ć¦ć„ć¾ć™ć€‚

https://github.com/kazuhira-r/infinispan-getting-started/tree/master/remote-query-infinispan-annotation