(window.webpackJsonp=window.webpackJsonp||[]).push([[115],{538:function(e,t,n){"use strict";n.r(t);var a=n(56),r=Object(a.a)({},(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[n("h1",{attrs:{id:"pivotal-gemfire-and-apache-geode-support"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#pivotal-gemfire-and-apache-geode-support"}},[e._v("#")]),e._v(" Pivotal GemFire and Apache Geode Support")]),e._v(" "),n("h2",{attrs:{id:"pivotal-gemfire-and-apache-geode-support-2"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#pivotal-gemfire-and-apache-geode-support-2"}},[e._v("#")]),e._v(" Pivotal GemFire and Apache Geode Support")]),e._v(" "),n("p",[e._v("Spring Integration provides support for Pivotal GemFire and Apache Geode.")]),e._v(" "),n("p",[e._v("You need to include this dependency into your project:")]),e._v(" "),n("p",[e._v("Maven")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("\n org.springframework.integration\n spring-integration-gemfire\n 5.5.9\n\n")])])]),n("p",[e._v("Gradle")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('compile "org.springframework.integration:spring-integration-gemfire:5.5.9"\n')])])]),n("p",[e._v("GemFire is a distributed data management platform that provides a key-value data grid along with advanced distributed system features, such as event processing, continuous querying, and remote function execution.\nThis guide assumes some familiarity with the commercial "),n("a",{attrs:{href:"https://pivotal.io/pivotal-gemfire",target:"_blank",rel:"noopener noreferrer"}},[e._v("Pivotal GemFire"),n("OutboundLink")],1),e._v(" or Open Source "),n("a",{attrs:{href:"https://geode.apache.org",target:"_blank",rel:"noopener noreferrer"}},[e._v("Apache Geode"),n("OutboundLink")],1),e._v(".")]),e._v(" "),n("p",[e._v("Spring integration provides support for GemFire by implementing inbound adapters for entry and continuous query events, an outbound adapter to write entries to the cache, and message and metadata stores and "),n("code",[e._v("GemfireLockRegistry")]),e._v(" implementations.\nSpring integration leverages the "),n("a",{attrs:{href:"https://projects.spring.io/spring-data-gemfire",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data for Pivotal GemFire"),n("OutboundLink")],1),e._v(" project, providing a thin wrapper over its components.")]),e._v(" "),n("p",[e._v("Starting with version 5.1, the Spring Integration GemFire module uses the "),n("a",{attrs:{href:"https://github.com/spring-projects/spring-data-geode",target:"_blank",rel:"noopener noreferrer"}},[e._v("Spring Data for Apache Geode"),n("OutboundLink")],1),e._v(" transitive dependency by default.\nTo switch to the commercial Pivotal GemFire-based Spring Data for Pivotal GemFire, exclude "),n("code",[e._v("spring-data-geode")]),e._v(" from dependencies and add "),n("code",[e._v("spring-data-gemfire")]),e._v(", as the following Maven snippet shows:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("\n org.springframework.integration\n spring-integration-gemfire\n \n \n org.springframework.data\n spring-data-geode\n \n \n\n\n\n org.springframework.data\n spring-data-gemfire\n\n")])])]),n("p",[e._v("To configure the 'int-gfe' namespace, include the following elements within the headers of your XML configuration file:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('xmlns:int-gfe="http://www.springframework.org/schema/integration/gemfire"\nxsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire\n\thttps://www.springframework.org/schema/integration/gemfire/spring-integration-gemfire.xsd"\n')])])]),n("h3",{attrs:{id:"inbound-channel-adapter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#inbound-channel-adapter"}},[e._v("#")]),e._v(" Inbound Channel Adapter")]),e._v(" "),n("p",[e._v("The inbound channel adapter produces messages on a channel when triggered by a GemFire "),n("code",[e._v("EntryEvent")]),e._v(".\nGemFire generates events whenever an entry is "),n("code",[e._v("CREATED")]),e._v(", "),n("code",[e._v("UPDATED")]),e._v(", "),n("code",[e._v("DESTROYED")]),e._v(", or "),n("code",[e._v("INVALIDATED")]),e._v(" in the associated region.\nThe inbound channel adapter lets you filter on a subset of these events.\nFor example, you may want to produce messages only in response to an entry being created.\nIn addition, the inbound channel adapter can evaluate a SpEL expression if, for example, you want your message payload to contain an event property such as the new entry value.\nThe following example shows how to configure an inbound channel adapter with a SpEL language (in the "),n("code",[e._v("expression")]),e._v(" attribute):")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n\n\n')])])]),n("p",[e._v("The preceding configuration creates a GemFire "),n("code",[e._v("Cache")]),e._v(" and "),n("code",[e._v("Region")]),e._v(" by using Spring GemFire’s 'gfe' namespace.\nThe "),n("code",[e._v("inbound-channel-adapter")]),e._v(" element requires a reference to the GemFire region on which the adapter listens for events.\nOptional attributes include "),n("code",[e._v("cache-events")]),e._v(", which can contain a comma-separated list of event types for which a message is produced on the input channel.\nBy default, "),n("code",[e._v("CREATED")]),e._v(" and "),n("code",[e._v("UPDATED")]),e._v(" are enabled.\nIf no "),n("code",[e._v("channel")]),e._v(" attribute is provided, the channel is created from the "),n("code",[e._v("id")]),e._v(" attribute.\nThis adapter also supports an "),n("code",[e._v("error-channel")]),e._v(".\nThe GemFire "),n("a",{attrs:{href:"https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/EntryEvent.html",target:"_blank",rel:"noopener noreferrer"}},[n("code",[e._v("EntryEvent")]),n("OutboundLink")],1),e._v(" is the "),n("code",[e._v("#root")]),e._v(" object of the "),n("code",[e._v("expression")]),e._v(" evaluation.\nThe following example shows an expression that replaces a value for a key:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('expression="new something.MyEvent(key, oldValue, newValue)"\n')])])]),n("p",[e._v("If the "),n("code",[e._v("expression")]),e._v(" attribute is not provided, the message payload is the GemFire "),n("code",[e._v("EntryEvent")]),e._v(" itself.")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("This adapter conforms to Spring Integration conventions.")])])]),e._v(" "),n("tbody")]),e._v(" "),n("h3",{attrs:{id:"continuous-query-inbound-channel-adapter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#continuous-query-inbound-channel-adapter"}},[e._v("#")]),e._v(" Continuous Query Inbound Channel Adapter")]),e._v(" "),n("p",[e._v("The continuous query inbound channel adapter produces messages on a channel when triggered by a GemFire continuous query or "),n("code",[e._v("CqEvent")]),e._v(" event.\nIn release "),n("code",[e._v("1.1")]),e._v(", Spring Data introduced continuous query support, including "),n("code",[e._v("ContinuousQueryListenerContainer")]),e._v(", which provides a nice abstraction over the GemFire native API.\nThis adapter requires a reference to a "),n("code",[e._v("ContinuousQueryListenerContainer")]),e._v(" instance, creates a listener for a given "),n("code",[e._v("query")]),e._v(", and executes the query.\nThe continuous query acts as an event source that fires whenever its result set changes state.")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("GemFire queries are written in OQL and are scoped to the entire cache (not just one region)."),n("br"),e._v("Additionally, continuous queries require a remote (that is, running in a separate process or remote host) cache server."),n("br"),e._v("See the "),n("a",{attrs:{href:"https://gemfire82.docs.pivotal.io/docs-gemfire/gemfire_nativeclient/continuous-querying/continuous-querying.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("GemFire documentation"),n("OutboundLink")],1),e._v(" for more information on implementing continuous queries.")])])]),e._v(" "),n("tbody")]),e._v(" "),n("p",[e._v("The following configuration creates a GemFire client cache (recall that a remote cache server is required for this implementation and its address is configured as a child element of the pool), a client region, and a "),n("code",[e._v("ContinuousQueryListenerContainer")]),e._v(" that uses Spring Data:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n\n\n \x3c!--configure server or locator here required to address the cache server --\x3e\n\n\n\n\n\n\n\n')])])]),n("p",[e._v("The continuous query inbound channel adapter requires a "),n("code",[e._v("cq-listener-container")]),e._v(" attribute, which must contain a reference to the "),n("code",[e._v("ContinuousQueryListenerContainer")]),e._v(".\nOptionally, it accepts an "),n("code",[e._v("expression")]),e._v(" attribute that uses SpEL to transform the "),n("code",[e._v("CqEvent")]),e._v(" or extract an individual property as needed.\nThe "),n("code",[e._v("cq-inbound-channel-adapter")]),e._v(" provides a "),n("code",[e._v("query-events")]),e._v(" attribute that contains a comma-separated list of event types for which a message is produced on the input channel.\nThe available event types are "),n("code",[e._v("CREATED")]),e._v(", "),n("code",[e._v("UPDATED")]),e._v(", "),n("code",[e._v("DESTROYED")]),e._v(", "),n("code",[e._v("REGION_DESTROYED")]),e._v(", and "),n("code",[e._v("REGION_INVALIDATED")]),e._v(".\nBy default, "),n("code",[e._v("CREATED")]),e._v(" and "),n("code",[e._v("UPDATED")]),e._v(" are enabled.\nAdditional optional attributes include "),n("code",[e._v("query-name")]),e._v(" (which provides an optional query name), "),n("code",[e._v("expression")]),e._v(" (which works as described in the preceding section), and "),n("code",[e._v("durable")]),e._v(" (a boolean value indicating if the query is durable — it is false by default).\nIf you do not provide a "),n("code",[e._v("channel")]),e._v(", the channel is created from the "),n("code",[e._v("id")]),e._v(" attribute.\nThis adapter also supports an "),n("code",[e._v("error-channel")]),e._v(".")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("This adapter conforms to Spring Integration conventions.")])])]),e._v(" "),n("tbody")]),e._v(" "),n("h3",{attrs:{id:"outbound-channel-adapter"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#outbound-channel-adapter"}},[e._v("#")]),e._v(" Outbound Channel Adapter")]),e._v(" "),n("p",[e._v("The outbound channel adapter writes cache entries that are mapped from the message payload.\nIn its simplest form, it expects a payload of type "),n("code",[e._v("java.util.Map")]),e._v(" and puts the map entries into its configured region.\nThe following example shows how to configure an outbound channel adapter:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n')])])]),n("p",[e._v("Given the preceding configuration, an exception is thrown if the payload is not a "),n("code",[e._v("Map")]),e._v(".\nAdditionally, you can configure the outbound channel adapter to create a map of cache entries by using SpEL.\nThe following example shows how to do so:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n \n \n \n \n\n')])])]),n("p",[e._v("In the preceding configuration, the inner element ("),n("code",[e._v("cache-entries")]),e._v(") is semantically equivalent to a Spring 'map' element.\nThe adapter interprets the "),n("code",[e._v("key")]),e._v(" and "),n("code",[e._v("value")]),e._v(" attributes as SpEL expressions with the message as the evaluation context.\nNote that this can contain arbitrary cache entries (not only those derived from the message) and that literal values must be enclosed in single quotes.\nIn the preceding example, if the message sent to "),n("code",[e._v("cacheChannel")]),e._v(" has a "),n("code",[e._v("String")]),e._v(" payload with a value "),n("code",[e._v("Hello")]),e._v(", two entries ("),n("code",[e._v("[HELLO:hello, thing1:thing2]")]),e._v(") are written (either created or updated) in the cache region.\nThis adapter also supports the "),n("code",[e._v("order")]),e._v(" attribute, which may be useful if it is bound to a "),n("code",[e._v("PublishSubscribeChannel")]),e._v(".")]),e._v(" "),n("h3",{attrs:{id:"gemfire-message-store"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gemfire-message-store"}},[e._v("#")]),e._v(" Gemfire Message Store")]),e._v(" "),n("p",[e._v("As described in EIP, a "),n("a",{attrs:{href:"https://www.enterpriseintegrationpatterns.com/MessageStore.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("message store"),n("OutboundLink")],1),e._v(" lets you persist messages.\nThis can be useful when dealing with components that have a capability to buffer messages ("),n("code",[e._v("QueueChannel")]),e._v(", "),n("code",[e._v("Aggregator")]),e._v(", "),n("code",[e._v("Resequencer")]),e._v(", and others) if reliability is a concern.\nIn Spring Integration, the "),n("code",[e._v("MessageStore")]),e._v(" strategy interface also provides the foundation for the "),n("a",{attrs:{href:"https://www.enterpriseintegrationpatterns.com/StoreInLibrary.html",target:"_blank",rel:"noopener noreferrer"}},[e._v("claim check"),n("OutboundLink")],1),e._v(" pattern, which is described in EIP as well.")]),e._v(" "),n("p",[e._v("Spring Integration’s Gemfire module provides "),n("code",[e._v("GemfireMessageStore")]),e._v(", which is an implementation of both the "),n("code",[e._v("MessageStore")]),e._v(" strategy (mainly used by the "),n("code",[e._v("QueueChannel")]),e._v(" and "),n("code",[e._v("ClaimCheck")]),e._v(" patterns) and the "),n("code",[e._v("MessageGroupStore")]),e._v(" strategy (mainly used by the "),n("code",[e._v("Aggregator")]),e._v(" and "),n("code",[e._v("Resequencer")]),e._v(" patterns).")]),e._v(" "),n("p",[e._v("The following example configures the cache and region by using the "),n("code",[e._v("spring-gemfire")]),e._v(" namespace (not to be confused with the "),n("code",[e._v("spring-integration-gemfire")]),e._v(" namespace):")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n \n\n\n\n\n\n\n\n \n\n\n\n')])])]),n("p",[e._v("Often, it is desirable for the message store to be maintained in one or more remote cache servers in a client-server configuration.\nIn this case, you should configure a client cache, a client region, and a client pool and inject the region into the "),n("code",[e._v("MessageStore")]),e._v(".\nThe following example shows how to do so:")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v('\n \n\n\n\n\n\n\n\n \n\n')])])]),n("p",[e._v("Note that the "),n("code",[e._v("pool")]),e._v(" element is configured with the address of a cache server (you can substitute a locator here).\nThe region is configured as a 'PROXY' so that no data is stored locally.\nThe region’s "),n("code",[e._v("id")]),e._v(" corresponds to a region with the same name in the cache server.")]),e._v(" "),n("p",[e._v("Starting with version 4.3.12, the "),n("code",[e._v("GemfireMessageStore")]),e._v(" supports the key "),n("code",[e._v("prefix")]),e._v(" option to allow distinguishing between instances of the store on the same GemFire region.")]),e._v(" "),n("h3",{attrs:{id:"gemfire-lock-registry"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gemfire-lock-registry"}},[e._v("#")]),e._v(" Gemfire Lock Registry")]),e._v(" "),n("p",[e._v("Starting with version 4.0, the "),n("code",[e._v("GemfireLockRegistry")]),e._v(" is available.\nCertain components (for example, the aggregator and the resequencer) use a lock obtained from a "),n("code",[e._v("LockRegistry")]),e._v(" instance to ensure that only one thread is manipulating a group at any given time.\nThe "),n("code",[e._v("DefaultLockRegistry")]),e._v(" performs this function within a single component.\nYou can now configure an external lock registry on these components.\nWhen you use a shared "),n("code",[e._v("MessageGroupStore")]),e._v(" with the "),n("code",[e._v("GemfireLockRegistry")]),e._v(", it can provide this functionality across multiple application instances, such that only one instance can manipulate the group at a time.")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("One of the "),n("code",[e._v("GemfireLockRegistry")]),e._v(" constructors requires a "),n("code",[e._v("Region")]),e._v(" as an argument."),n("br"),e._v("It is used to obtain a "),n("code",[e._v("Lock")]),e._v(" from the "),n("code",[e._v("getDistributedLock()")]),e._v(" method."),n("br"),e._v("This operation requires "),n("code",[e._v("GLOBAL")]),e._v(" scope for the "),n("code",[e._v("Region")]),e._v("."),n("br"),e._v("Another constructor requires a "),n("code",[e._v("Cache")]),e._v(", and the "),n("code",[e._v("Region")]),e._v(" is created with "),n("code",[e._v("GLOBAL")]),e._v(" scope and with the name, "),n("code",[e._v("LockRegistry")]),e._v(".")])])]),e._v(" "),n("tbody")]),e._v(" "),n("h3",{attrs:{id:"gemfire-metadata-store"}},[n("a",{staticClass:"header-anchor",attrs:{href:"#gemfire-metadata-store"}},[e._v("#")]),e._v(" Gemfire Metadata Store")]),e._v(" "),n("p",[e._v("Version 4.0 introduced a new Gemfire-based "),n("code",[e._v("MetadataStore")]),e._v(" ("),n("RouterLink",{attrs:{to:"/en/spring-integration/meta-data-store.html#metadata-store"}},[e._v("Metadata Store")]),e._v(") implementation.\nYou can use the "),n("code",[e._v("GemfireMetadataStore")]),e._v(" to maintain metadata state across application restarts.\nThis new "),n("code",[e._v("MetadataStore")]),e._v(" implementation can be used with adapters such as:")],1),e._v(" "),n("ul",[n("li",[n("p",[n("RouterLink",{attrs:{to:"/en/spring-integration/feed.html#feed-inbound-channel-adapter"}},[e._v("Feed Inbound Channel Adapter")])],1)]),e._v(" "),n("li",[n("p",[n("RouterLink",{attrs:{to:"/en/spring-integration/file.html#file-reading"}},[e._v("Reading Files")])],1)]),e._v(" "),n("li",[n("p",[n("RouterLink",{attrs:{to:"/en/spring-integration/ftp.html#ftp-inbound"}},[e._v("FTP Inbound Channel Adapter")])],1)]),e._v(" "),n("li",[n("p",[n("RouterLink",{attrs:{to:"/en/spring-integration/sftp.html#sftp-inbound"}},[e._v("SFTP Inbound Channel Adapter")])],1)])]),e._v(" "),n("p",[e._v("To get these adapters to use the new "),n("code",[e._v("GemfireMetadataStore")]),e._v(", declare a Spring bean with a bean name of "),n("code",[e._v("metadataStore")]),e._v(".\nThe feed inbound channel adapter automatically picks up and use the declared "),n("code",[e._v("GemfireMetadataStore")]),e._v(".")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("The "),n("code",[e._v("GemfireMetadataStore")]),e._v(" also implements "),n("code",[e._v("ConcurrentMetadataStore")]),e._v(", letting it be reliably shared across multiple application instances, where only one instance can store or modify a key’s value."),n("br"),e._v("These methods give various levels of concurrency guarantees based on the scope and data policy of the region."),n("br"),e._v("They are implemented in the peer cache and client-server cache but are disallowed in peer regions that have "),n("code",[e._v("NORMAL")]),e._v(" or "),n("code",[e._v("EMPTY")]),e._v(" data policies.")])])]),e._v(" "),n("tbody")]),e._v(" "),n("table",[n("thead",[n("tr",[n("th"),e._v(" "),n("th",[e._v("Since version 5.0, the "),n("code",[e._v("GemfireMetadataStore")]),e._v(" also implements "),n("code",[e._v("ListenableMetadataStore")]),e._v(", which lets you listen to cache events by providing "),n("code",[e._v("MetadataStoreListener")]),e._v(" instances to the store, as the following example shows:")])])]),e._v(" "),n("tbody")]),e._v(" "),n("div",{staticClass:"language- extra-class"},[n("pre",{pre:!0,attrs:{class:"language-text"}},[n("code",[e._v("GemfireMetadataStore metadataStore = new GemfireMetadataStore(cache);\nmetadataStore.addListener(new MetadataStoreListenerAdapter() {\n\n @Override\n public void onAdd(String key, String value) {\n ...\n }\n\n});\n")])])])])}),[],!1,null,null,null);t.default=r.exports}}]);