1

With a simple client app, make an object and object repository, connect to a Geode cluster, then run a @Bean ApplicationRunner to put some data to a remote region.

@ClientCacheApplication(name = "Web", locators = @Locator, logLevel = "debug", subscriptionEnabled = true)
@EnableClusterDefinedRegions
@EnableClusterConfiguration(useHttp = true)
@EnablePdx
public class MyCache {

private static final Logger log = LoggerFactory.getLogger(MyCache.class);

@Bean
ApplicationRunner StartedUp(MyRepository myRepo){       
    log.info("In StartedUp");

    return args -> {            
    String guid = UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    MyObject msg = new MyObject(guid, "Started");

    myRepo.save(msg);

    log.info("Out StartedUp");
    };
}   

The "save" put fails with

org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer'; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://localhost:7070/gemfire/v1/regions": Connection refused: connect; nested exception is java.net.ConnectException: Connection refused: connect
rupweb
  • 3,052
  • 1
  • 30
  • 57

2 Answers2

1

Problem creating region and persist region to disk Geode Gemfire Spring Boot helped. The problem is the @EnableClusterConfiguration(useHttp = true)

This annotation makes the remote cluster appear to be a localhost. If I remove it altogether then the put works.

If remove just the useHttp = true there is another error:

org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer'; nested exception is org.apache.geode.cache.client.ServerOperationException: remote server on #.#.#.#(Web:9408:loner)### The function is not registered for function id CreateRegionFunction
rupweb
  • 3,052
  • 1
  • 30
  • 57
  • 1
    Right, without `useHttp=true`, SDG, and specifically, the `@EnableClusterConfiguration` annotation expects the servers in the cluster to have been configured and bootstrapped with SDG (or SBDG) using the Annotation-based configuration model. – John Blum Jan 16 '20 at 01:22
  • 1
    If you are using Gfsh to configure/bootstrap your cluster of servers (recommended in most cases), then you must configure `useHttp=true`. By using Gfsh, the Management REST API in the Locator should be available (which is only the case with a full distribution of GemFire/Geode). If you adjusted the host/port of the embedded HTTP service/server (i.e. Jetty) in the GemFire/Geode Locator on startup, then you can specify the `host` and/or `port` attributes on the `@EnableClusterConfiguration` annotation. – John Blum Jan 16 '20 at 01:24
1

In a nutshell, the SDG @EnableClusterConfiguration annotation (details available here) enables configuration metadata defined and declared on the client (i.e. Spring [Boot] Data, GemFire/Geode application) to be pushed from the client-side to the cluster (of GemFire/Geode servers).

I say "enable" because it depends on the client-side configuration metadata (i.e. Spring bean definitions you have explicitly or implicitly defined/declared). Explicit configuration is configuration you defined with a bean definition (in XML, or JavaConfig with @Bean, etc). Implicit configuration is auto-configuration or using SDG annotations like @EnableEntityDefinedRegions or @EnableCachingDefinedRegions, etc.

By default, the @EnableClusterConfiguration annotation assumes the cluster of GemFire or Geode servers were configured and bootstrapped with Spring, and specifically using the SDG Annotation configuration model. When the GemFire or Geode servers are configured and bootstrapped with Spring, then SDG goes on to register some provided, canned GemFire Functions that the @EnableClusterConfiguration annotation calls (by default and...) as a fallback.

NOTE: See the appendix in the SBDG reference documentation on configuring and bootstrapping a GemFire or Geode server, or even a cluster of servers, with Spring. This certainly simplifies local development and debugging as opposed to using Gfsh. You can do all sorts of interesting combinations: Gfsh Locator with Spring servers, Spring [embedded|standalone] Locator with both Gfsh and Spring servers, etc.

Most of the time, users are using Spring on the client and Gfsh to (partially) configure and bootstrap their cluster (of servers). When this is the case, then Spring is generally not on the servers' classpath and the "provided, canned" Functions I referred to above are not present and automatically registered. In which case, you must rely on GemFire/Geodes internal, Management REST API (something I know a thing or 2 about, ;-) to send the configuration metadata from the client to the server/cluster. This is why the useHttp attribute on the @EnableClusterConfiguration annotation must be set to true.

This is why you saw the Exception...

org.springframework.context.ApplicationContextException: Failed to start bean 'gemfireClusterSchemaObjectInitializer'; 

nested exception is org.apache.geode.cache.client.ServerOperationException: remote server on #.#.#.#(Web:9408:loner)### 
    The function is not registered for function id CreateRegionFunction

The CreateRegionFunction is the canned Function provided by SDG out of the box, but only when Spring is used to both configure and bootstrap the servers in the cluster.

This generally works well for CI/CD environments, and especially our own test infrastructure since we typically do not have a full installations of either Apache Geode or Pivotal GemFire available to test with in those environments. For 1, those artifacts must be resolvable from and artifact repository like Maven Central. The Apache Geode (and especially) Pivotal GemFire distributions are not. The JARs are, but the full distro isn't. Anyway...

Hopefully, all of this makes sense up to this point.

I do have a recommendation if I may.

Given your application class definition begins with...

@ClientCacheApplication(name = "Web", locators = @Locator, 
    logLevel = "debug", subscriptionEnabled = true)
@EnableClusterDefinedRegions
@EnableClusterConfiguration(useHttp = true)
@EnablePdx
public class MyCache { ... }

I would highly recommend simply using Spring Boot for Apache Geode (and Pivotal GemFire), i.e. SBDG, in place of SDG directly.

Your application class could then be simplified to:

@SpringBootApplication
@EnableClusterAware
@EnableClusterDefinedRegions
public class MyCache { ... }

You can then externalize some of the hard coded configuration settings using the Spring Boot application.properties file:

spring.application.name=Web
spring.data.gemfire.cache.log-level=debug
spring.data.gemfire.pool.subscription-enabled=true

NOTE: @EnableClusterAware is a much more robust and capable extension of @EnableClusterConfiguration. See additional details here.

Here are a few resources to get you going:

In general, SBDG, which is based on SDG, SSDG and STDG, is the preferred/recommended starting point for all things Spring for Apache Geode and Pivotal GemFire (or now, Pivotal Cloud Cache).

Hope this helps.

John Blum
  • 7,381
  • 1
  • 20
  • 30