Add Annotation based configuration to configure the peer member's 'distributed-system-id' property.

This commit is contained in:
John Blum
2018-06-04 18:36:56 -07:00
parent 91c36588d1
commit 41a7e7bc55
3 changed files with 281 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.springframework.geode.config.annotation;
import java.lang.annotation.Annotation;
import java.util.Optional;
import org.apache.geode.cache.Cache;
import org.apache.shiro.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer;
import org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer;
import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport;
/**
* The {@link DistributedSystemIdConfiguration} class is a Spring {@link Configuration} class used to configure
* the {@literal distributed-system-id} for a {@link Cache peer Cache member} in a cluster
* when using the P2P topology.
*
* @author John Blum
* @see org.apache.geode.cache.Cache
* @see org.springframework.context.annotation.Bean
* @see org.springframework.context.annotation.Configuration
* @see org.springframework.context.annotation.ImportAware
* @see org.springframework.core.annotation.AnnotationAttributes
* @see org.springframework.core.type.AnnotationMetadata
* @see org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer
* @see org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer
* @see org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport
* @see org.springframework.geode.config.annotation.UseDistributedSystemId
* @since 1.0.0
*/
@Configuration
@SuppressWarnings("unused")
public class DistributedSystemIdConfiguration extends AbstractAnnotationConfigSupport implements ImportAware {
private static final String GEMFIRE_DISTRIBUTED_SYSTEM_ID_PROPERTY = "distributed-system-id";
private Integer distributedSystemId;
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
protected Class<? extends Annotation> getAnnotationType() {
return UseDistributedSystemId.class;
}
@Override
@SuppressWarnings("all")
public void setImportMetadata(AnnotationMetadata importMetadata) {
if (isAnnotationPresent(importMetadata)) {
AnnotationAttributes distributedSystemIdAttributes = getAnnotationAttributes(importMetadata);
setDistributedSystemId(distributedSystemIdAttributes.containsKey("value")
? distributedSystemIdAttributes.getNumber("value") : null);
setDistributedSystemId(distributedSystemIdAttributes.containsKey("id")
? distributedSystemIdAttributes.getNumber("id") : null);
}
}
protected void setDistributedSystemId(Integer distributedSystemId) {
this.distributedSystemId = Optional.ofNullable(distributedSystemId)
.filter(id -> id > -1)
.orElse(this.distributedSystemId);
}
protected Optional<Integer> getDistributedSystemId() {
return Optional.ofNullable(this.distributedSystemId)
.filter(id -> id > -1);
}
protected Logger getLogger() {
return this.logger;
}
private int validateDistributedSystemId(int distributedSystemId) {
Assert.isTrue(distributedSystemId >= -1 && distributedSystemId < 256,
String.format("Distributed System ID [%d] must be between -1 and 255", distributedSystemId));
return distributedSystemId;
}
@Bean
ClientCacheConfigurer clientCacheDistributedSystemIdConfigurer() {
return (beanName, clientCacheFactoryBean) -> getDistributedSystemId().ifPresent(distributedSystemId -> {
Logger logger = getLogger();
if (logger.isWarnEnabled()) {
logger.warn("Distributed System Id [{}] was set on the ClientCache instance, which will not have any effect",
distributedSystemId);
}
});
}
@Bean
PeerCacheConfigurer peerCacheDistributedSystemIdConfigurer() {
return (beanName, cacheFactoryBean) ->
getDistributedSystemId().ifPresent(id -> cacheFactoryBean.getProperties()
.setProperty(GEMFIRE_DISTRIBUTED_SYSTEM_ID_PROPERTY,
String.valueOf(validateDistributedSystemId(id))));
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.springframework.geode.config.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.client.ClientCache;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AliasFor;
/**
* The {@link UseDistributedSystemId} annotation configures the {@literal distributed-system-id} property
* of a {@link Cache peer Cache member} in an Apache Geode/Pivotal GemFire P2P topology.
*
* This configuration annotation is only applicable on {@link Cache peer Cache members}
* and has no effect on {@link ClientCache} instances.
*
* @author John Blum
* @see java.lang.annotation.Documented
* @see java.lang.annotation.Inherited
* @see java.lang.annotation.Retention
* @see java.lang.annotation.Target
* @see org.apache.geode.cache.Cache
* @see org.springframework.context.annotation.Import
* @see org.springframework.core.annotation.AliasFor
* @see org.springframework.geode.config.annotation.DistributedSystemIdConfiguration
* @since 1.0.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DistributedSystemIdConfiguration.class)
@SuppressWarnings("unused")
public @interface UseDistributedSystemId {
/**
* Configures the identifier used to distinguish messages from different distributed systems.
*
* This is required for Portable Data eXchange (PDX) data serialization.
*
* Set distributed-system-id to different values for different systems in a multi-site (WAN) configuration,
* and to different values for production vs. development environments. This setting must be the same
* for every member of a given distributed system and unique to each distributed system within a WAN installation.
*
* Valid values are integers in the range -1…255. -1 means no setting.
*
* Defaults to {@literal -1}.
*/
@AliasFor("id")
int value() default -1;
/**
* Configures the identifier used to distinguish messages from different distributed systems.
*
* Alias for {@literal #value()}.
*/
@AliasFor("value")
int id() default -1;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.springframework.geode.config.annotation;
import static org.assertj.core.api.Assertions.assertThat;
import org.apache.geode.cache.GemFireCache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
import org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Integration tests for {@link UseDistributedSystemId} and {@link DistributedSystemIdConfiguration}.
*
* @author John Blum
* @see org.junit.Test
* @see org.apache.geode.cache.GemFireCache
* @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication
* @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport
* @see org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects
* @see org.springframework.geode.config.annotation.DistributedSystemIdConfiguration
* @see org.springframework.geode.config.annotation.UseDistributedSystemId
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringRunner
* @since 1.0.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration
@SuppressWarnings("unused")
public class DistributedSystemIdConfigurationIntegrationTests extends IntegrationTestsSupport {
@Autowired
private GemFireCache gemfireCache;
@Test
public void distributedSystemIdWasConfiguredCorrectly() {
assertThat(this.gemfireCache).isNotNull();
assertThat(this.gemfireCache.getDistributedSystem()).isNotNull();
assertThat(this.gemfireCache.getDistributedSystem().getProperties()).isNotNull();
assertThat(this.gemfireCache.getDistributedSystem().getProperties().getProperty("distributed-system-id"))
.isEqualTo("42");
}
@PeerCacheApplication
@EnableGemFireMockObjects
@UseDistributedSystemId(42)
static class TestConfiguration { }
}