Search code examples
spring-bootgemfilespring-data-gemfiregeodegfsh

Unable to connect to Locator via GFSH


I have started a GemFire Server and Locator via Spring Boot and when I try to connect to the Locator from GFSH, I getting the following issue:

gfsh> connect
Connecting to Locator at [host=localhost, port=10334] ..
Connection refused: connect

Below, is the Spring (Java) configuration:

@Configuration 
@ComponentScan 
@EnableGemfireRepositories(basePackages= "com.gemfire.demo") 
@CacheServerApplication(locators = "localhost[10334]") 
@EnableManager 
public class GemfireConfiguration {

    @Bean
    Properties gemfireProperties() {
        Properties gemfireProperties = new Properties();
        gemfireProperties.setProperty("name", "SpringDataGemFireApplication");
        gemfireProperties.setProperty("mcast-port", "0");
        gemfireProperties.setProperty("log-level", "info");
        return gemfireProperties;
    }

    @Bean
    @Autowired
    CacheFactoryBean gemfireCache() {
        CacheFactoryBean gemfireCache = new CacheFactoryBean();
        gemfireCache.setClose(true);
        gemfireCache.setProperties(gemfireProperties());
        return gemfireCache;
    }

    @Bean(name="employee")
    @Autowired
    LocalRegionFactoryBean<String, Employee> getEmployee(final GemFireCache cache) {
        LocalRegionFactoryBean<String, Employee> employeeRegion = new LocalRegionFactoryBean<String, Employee>();
        employeeRegion.setCache(cache);
        employeeRegion.setClose(false);
        employeeRegion.setName("employee");
        employeeRegion.setPersistent(false);
        employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
        return employeeRegion;
    }
}

Ref:Spring Data Gemfire locator as per John's advice, I have enabled the Manager though I am still unable to connect.


Solution

  • You are not able to connect to the Locator (using Gfsh) because you don't have a Locator (service, either standalone or embedded) running with just the Spring (Java) config shown above.

    Note that the @CacheServerApplication(locators = "localhost[10334]") annotation, specifically with the locators attribute as you have configured above, does NOT start an embedded Locator. It simply allows this Spring Boot configured and bootstrapped Apache Geode or Pivotal GemFire peer Cache node to join an existing distributed system (cluster) with an "existing" Locator running on localhost, listening on port 10334.

    For instance, you could have started a Locator using Gfsh (e.g. start locator --name=X ...), then started your Spring Boot application with the Spring (Java) config shown above and you would see the Spring Boot app as part of the cluster formed by the Gfsh started Locator.

    It is simply a shortcut (convenience) to configure and start an "embedded" Locator, but to do so, you need to use the @EnableLocator annotation.

    Therefore, to configure and start an (embedded) Locator service in the same Spring Boot application as the CacheServer (and Manager), you must also include the @EnableLocator annotation, like so:

    @SpringBootApplicaton
    @CacheServerApplication
    @EnableLocator
    @EnableManager(start = true)
    public class GemFireServerApplication {
    
      ...
    }
    

    I have plenty of examples of this here, for instance here, and talk about this generally here, etc.

    As a side note, your whole configuration (class) is confused and it is clear you don't quite understand what you are doing. For instance, declaring the gemfireProperties and gemfireCache beans in JavaConfig is redundant and unnecessary since you are using the @CacheServerApplication annotation. Your whole configuration could be simplified to:

    @CacheServerApplication( name = "SpringDataGemFireApplication", locators = "localhost[10334]", logLevel = "info" ) @EnableLocator @EnableManager(start = true) @EnableGemfireRepositories(basePackages= "com.gemfire.demo") @ComponentScan public class GemfireConfiguration {

    @Bean(name="employee")
    LocalRegionFactoryBean<String, Employee> getEmployee(GemFireCache cache) {
    
        LocalRegionFactoryBean<String, Employee> employeeRegion = 
            new LocalRegionFactoryBean<String, Employee>();
    
        employeeRegion.setCache(cache);
        employeeRegion.setClose(false);
        employeeRegion.setName("employee");
        employeeRegion.setPersistent(false);
        employeeRegion.setDataPolicy(DataPolicy.PRELOADED);
    
        return employeeRegion;
    }
    

    }

    Two things:

    1) First, I would be highly careful about using classpath component scanning (@ComponentScan). I am not a fan of this configuration approach, especially in production where things should be explicit.

    2) I would encourage your to considering using the type-safe basePackageClasses attribute on the @EnableGemFireRepositorities annotation rather than the basePackages attribute. With basePackageClasses, you only need to refer to a single interface/class in the desired package (e.g. com.gemfire.demo) rather than every interface/class. The referenced interface/class serves as a pointer to identify the package to scan from, including all sub-packages. It is type-safe and when your interfaces/classes in that package are re-located, then your attribute is still valid after the refactoring.

    Anyway...

    Hope this helps.

    -j