SGF-636 - Add support for GemFire JCA ResourceAdapter.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.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.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* The {@link EnableGemFireAsLastResource} annotation is used to enable GemFire as a Last Resource in a Spring,
|
||||
* CMT/JTA Transaction.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.context.annotation.EnableAspectJAutoProxy
|
||||
* @see org.springframework.context.annotation.Import
|
||||
* @see org.springframework.data.gemfire.config.annotation.GemFireAsLastResourceConfiguration
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
@EnableAspectJAutoProxy
|
||||
@Import(GemFireAsLastResourceConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public @interface EnableGemFireAsLastResource {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.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.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* The EnableRegionDataAccessTracing class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
@EnableAspectJAutoProxy
|
||||
@Import(RegionDataAccessTracingConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public @interface EnableRegionDataAccessTracing {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.support.GemFireAsLastResourceConnectionAcquiringAspect;
|
||||
import org.springframework.data.gemfire.config.annotation.support.GemFireAsLastResourceConnectionClosingAspect;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* The {@link GemFireAsLastResourceConfiguration} class is a Spring {@link Configuration @Configuration}
|
||||
* annotated class used to configure the GemFire "Last Resource" Spring Data GemFire {@link Aspect Aspects}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.aspectj.lang.annotation.Aspect
|
||||
* @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.EnableGemFireAsLastResource
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireAsLastResourceConnectionAcquiringAspect
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.GemFireAsLastResourceConnectionClosingAspect
|
||||
* @see org.springframework.transaction.annotation.EnableTransactionManagement
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public class GemFireAsLastResourceConfiguration implements ImportAware {
|
||||
|
||||
private Integer enableTransactionManagementOrder;
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.enableTransactionManagementOrder = resolveEnableTransactionManagementOrder(importMetadata);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
protected int resolveEnableTransactionManagementOrder(AnnotationMetadata importMetadata) {
|
||||
|
||||
AnnotationAttributes enableTransactionManagementAttributes =
|
||||
resolveEnableTransactionManagementAttributes(importMetadata);
|
||||
|
||||
Integer order = enableTransactionManagementAttributes.getNumber("order");
|
||||
|
||||
return Optional.ofNullable(order)
|
||||
.filter(it -> !(it == Integer.MAX_VALUE || it == Integer.MIN_VALUE))
|
||||
.orElseThrow(() -> newIllegalArgumentException(
|
||||
"The @%1$s(order) attribute value [%2$s] must be explicitly set to a value"
|
||||
+ " other than Integer.MAX_VALUE or Integer.MIN_VALUE",
|
||||
EnableTransactionManagement.class.getSimpleName(), String.valueOf(order)));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("all")
|
||||
protected AnnotationAttributes resolveEnableTransactionManagementAttributes(
|
||||
AnnotationMetadata importMetadata) {
|
||||
|
||||
Map<String, Object> enableTransactionManagementAttributes =
|
||||
importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName());
|
||||
|
||||
return Optional.ofNullable(enableTransactionManagementAttributes)
|
||||
.map(AnnotationAttributes::fromMap)
|
||||
.orElseThrow(() -> newIllegalStateException(
|
||||
"The @%1$s annotation may only be used on a Spring application @%2$s class"
|
||||
+ " that is also annotated with @%3$s having an explicit [order] set",
|
||||
EnableGemFireAsLastResource.class.getSimpleName(), Configuration.class.getSimpleName(),
|
||||
EnableTransactionManagement.class.getSimpleName()));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Integer getEnableTransactionManagementOrder() {
|
||||
|
||||
return Optional.ofNullable(this.enableTransactionManagementOrder)
|
||||
.orElseThrow(() -> newIllegalStateException(
|
||||
"The @%1$s(order) attribute was not properly set [%2$s]; Also, please make your"
|
||||
+ " Spring application @%3$s annotated class is annotated with both @%4$s and @%1$s",
|
||||
EnableTransactionManagement.class.getSimpleName(), String.valueOf(this.enableTransactionManagementOrder),
|
||||
Configuration.class.getSimpleName(), EnableGemFireAsLastResource.class.getSimpleName()));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Bean
|
||||
public Object gemfireCachePostProcessor(@Autowired(required = false) GemFireCache gemfireCache) {
|
||||
Optional.ofNullable(gemfireCache).ifPresent(cache -> cache.setCopyOnRead(true));
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Bean
|
||||
public GemFireAsLastResourceConnectionAcquiringAspect gemfireJcaConnectionAcquiringAspect() {
|
||||
|
||||
GemFireAsLastResourceConnectionAcquiringAspect connectionAcquiringAspect =
|
||||
new GemFireAsLastResourceConnectionAcquiringAspect();
|
||||
|
||||
int order = (getEnableTransactionManagementOrder() + 1);
|
||||
|
||||
connectionAcquiringAspect.setOrder(order);
|
||||
|
||||
return connectionAcquiringAspect;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Bean
|
||||
public GemFireAsLastResourceConnectionClosingAspect gemfireJcaConnectionClosingAspect() {
|
||||
|
||||
GemFireAsLastResourceConnectionClosingAspect connectionClosingAspect =
|
||||
new GemFireAsLastResourceConnectionClosingAspect();
|
||||
|
||||
int order = (getEnableTransactionManagementOrder() - 1);
|
||||
|
||||
connectionClosingAspect.setOrder(order);
|
||||
|
||||
return connectionClosingAspect;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.gemfire.config.annotation.support.RegionDataAccessTracingAspect;
|
||||
|
||||
/**
|
||||
* The RegionDataAccessTracingConfiguration class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@SuppressWarnings("unused")
|
||||
public class RegionDataAccessTracingConfiguration {
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Bean
|
||||
public RegionDataAccessTracingAspect regionDataAccessTracingAspect() {
|
||||
return new RegionDataAccessTracingAspect();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation.support;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.resource.ResourceException;
|
||||
|
||||
import org.apache.geode.cache.GemFireCache;
|
||||
import org.apache.geode.ra.GFConnection;
|
||||
import org.apache.geode.ra.GFConnectionFactory;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.event.Level;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link AbstractGemFireAsLastResourceAspectSupport} is an abstract base class encapsulating functionality common
|
||||
* to all AOP Aspect extensions/implementations involving the GemFire JCA ResourceAdapter object registered in
|
||||
* the JNDI context of a managed environment.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see javax.naming.Context
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see org.apache.geode.ra.GFConnection
|
||||
* @see org.slf4j.Logger
|
||||
* @see org.springframework.core.Ordered
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class AbstractGemFireAsLastResourceAspectSupport implements Ordered {
|
||||
|
||||
protected static final boolean DEFAULT_THROW_ON_ERROR = false;
|
||||
|
||||
protected static final int DEFAULT_ORDER = Integer.MAX_VALUE;
|
||||
|
||||
protected static final Consumer<String> NO_OP_LOGGER = message -> {};
|
||||
|
||||
protected static final String DEFAULT_GEMFIRE_JCA_RESOURCE_ADAPTER_JNDI_NAME = "gfe/jca";
|
||||
|
||||
private boolean throwOnError = DEFAULT_THROW_ON_ERROR;
|
||||
|
||||
private int order = DEFAULT_ORDER;
|
||||
|
||||
@Autowired(required = false)
|
||||
private Context context;
|
||||
|
||||
@Autowired(required = false)
|
||||
private GemFireCache gemfireCache;
|
||||
|
||||
private final Logger logger = newLogger();
|
||||
|
||||
@Value("${spring.data.gemfire.jca.resource-adapter.jndi.name:"
|
||||
+ DEFAULT_GEMFIRE_JCA_RESOURCE_ADAPTER_JNDI_NAME + "}")
|
||||
private String gemfireJcaResourceAdapterJndiName;
|
||||
|
||||
@Value("${spring.data.gemfire.naming.context.factory:}")
|
||||
private String initialContextFactory;
|
||||
|
||||
@Value("${spring.data.gemfire.naming.context.provider-url:}")
|
||||
private String providerUrl;
|
||||
|
||||
/**
|
||||
* Returns a reference to the naming {@link Context}.
|
||||
*
|
||||
* @return a reference to the naming {@link Context}.
|
||||
* @see javax.naming.Context
|
||||
*/
|
||||
protected synchronized Context getContext() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the {@link GemFireCache} used to interact with GemFire.
|
||||
*
|
||||
* @param <T> {@link Class} sub-type of the {@link GemFireCache} in use.
|
||||
* @return a reference to the {@link GemFireCache}.
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected synchronized <T extends GemFireCache> T getGemFireCache() {
|
||||
return (T) this.gemfireCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured reference to GemFire's JCA ResourceAdapter registered in the managed environment's
|
||||
* JNDI context.
|
||||
*
|
||||
* @return a {@link String} containing the configured reference to GemFire's JCA ResourceAdapter
|
||||
* registered in the managed environment's JNDI context.
|
||||
*/
|
||||
public String getGemFireJcaResourceAdapterJndiName() {
|
||||
return this.gemfireJcaResourceAdapterJndiName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured, fully-qualified classname of the {@link javax.naming.spi.InitialContextFactory}
|
||||
* used to construct the {@link InitialContext} that is then used to lookup managed objects registered
|
||||
* in the JNDI context of the managed environment.
|
||||
*
|
||||
* @return the configured, fully-qualified classname of the {@link javax.naming.spi.InitialContextFactory}
|
||||
* used to construct the {@link InitialContext}.
|
||||
*/
|
||||
public String getInitialContextFactory() {
|
||||
return this.initialContextFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the {@link Logger} used to record debug, info, warning and error messages
|
||||
* logged by the application.
|
||||
*
|
||||
* @return a reference to the configured {@link Logger} used by the application for logging purposes.
|
||||
* @see org.slf4j.Logger
|
||||
*/
|
||||
protected Logger getLogger() {
|
||||
return this.logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the order of this AOP Aspect relative to other Aspects in the chain of Aspects configured
|
||||
* in Spring's Transaction Management.
|
||||
*
|
||||
* @param order int value specifying the relative order of this Aspect.
|
||||
* @see org.springframework.core.Ordered
|
||||
*/
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order of this AOP Aspect relative to other Aspects in the chain of Aspects configured
|
||||
* in Spring's Transaction Management.
|
||||
*
|
||||
* @return an int value specifying the relative order of this Aspect.
|
||||
* @see org.springframework.core.Ordered
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
|
||||
return Optional.of(this.order)
|
||||
.filter(order -> !(order == Integer.MAX_VALUE || order == Integer.MIN_VALUE))
|
||||
.orElseGet(this::getDefaultOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default order used by this AOP Aspect in the chain of Aspects configured
|
||||
* in Spring's Transaction Management.
|
||||
*
|
||||
* @return an int value specifying the default order used by this AOP Aspect in the chain of Aspects
|
||||
* configured in Spring's Transaction Management.
|
||||
*/
|
||||
protected Integer getDefaultOrder() {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the Naming Context Provider as a {@link String}.
|
||||
*
|
||||
* @return the URL of the Naming Context Provider.
|
||||
*/
|
||||
public String getProviderUrl() {
|
||||
return this.providerUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an Exception should be thrown when this Aspect is unable to perform its function.
|
||||
*
|
||||
* Alternatively (and by default) the error condition is simply logged.
|
||||
*
|
||||
* Defaults to {@literal false}.
|
||||
*
|
||||
* @return a boolean value indicating whether this Aspect should throw an Exception when an error occurs
|
||||
* preventing this Aspect from performing its normal function.
|
||||
*/
|
||||
public boolean isThrowOnError() {
|
||||
return this.throwOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an AOP Pointcut identifying Join Points during the execution of the application's components
|
||||
* on which this Aspect should be applied.
|
||||
*
|
||||
* This particular Pointcut identifies {@link org.springframework.transaction.annotation.Transactional} annotated
|
||||
* application service {@link Class types}. That is, the {@link org.springframework.transaction.annotation.Transactional}
|
||||
* annotation is used at the class level.
|
||||
*
|
||||
* @see org.aspectj.lang.annotation.Pointcut
|
||||
*/
|
||||
@Pointcut("@within(org.springframework.transaction.annotation.Transactional)")
|
||||
protected void atTransactionalType() {}
|
||||
|
||||
/**
|
||||
* Defines an AOP Pointcut identifying Join Points during the execution of the application's components
|
||||
* on which this Aspect should be applied.
|
||||
*
|
||||
* This particular Pointcut identifies {@link org.springframework.transaction.annotation.Transactional} annotated
|
||||
* application service {@link java.lang.reflect.Method methods}. That is, the
|
||||
* {@link org.springframework.transaction.annotation.Transactional} annotation is used at the service class,
|
||||
* service {@link java.lang.reflect.Method method} level.
|
||||
*
|
||||
* @see org.aspectj.lang.annotation.Pointcut
|
||||
*/
|
||||
@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")
|
||||
protected void atTransactionalMethod() {}
|
||||
|
||||
/**
|
||||
* Formats the given {@link String message} with the provided array of {@link Object arguments}.
|
||||
*
|
||||
* @param message {@link String} containing the message to format.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return the {@link String message} formatted with the provided array of {@link Object arguments}.
|
||||
* @see java.lang.String#format(String, Object...)
|
||||
*/
|
||||
protected String format(String message, Object... args) {
|
||||
return String.format(message, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link String message} formatted with the given array of {@link Object arguments}
|
||||
* at {@link Level#DEBUG} level when debugging is enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param message {@link String} containing the message to log.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return this aspect.
|
||||
* @see org.slf4j.Logger#isDebugEnabled()
|
||||
* @see org.slf4j.Logger#debug(String, Object...)
|
||||
* @see #format(String, Object...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logDebugInfo(String message, Object... args) {
|
||||
|
||||
Logger logger = getLogger();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(format(message, args), args);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link String message} formatted with the given array of {@link Object arguments}
|
||||
* at {@link Level#INFO} level when info logging is enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param message {@link String} containing the message to log.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return this aspect.
|
||||
* @see org.slf4j.Logger#isInfoEnabled()
|
||||
* @see org.slf4j.Logger#info(String, Object...)
|
||||
* @see #format(String, Object...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logInfo(String message, Object... args) {
|
||||
|
||||
Logger logger = getLogger();
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(format(message, args), args);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link String message} formatted with the given array of {@link Object arguments}
|
||||
* at {@link Level#TRACE} level when tracing is enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param message {@link String} containing the message to log.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return this aspect.
|
||||
* @see java.util.function.Supplier
|
||||
* @see #logTraceInfo(Supplier)
|
||||
*/
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logTraceInfo(String message, Object... args) {
|
||||
return logTraceInfo(() -> format(message, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link Supplier log message} at {@link Level#TRACE} level when tracing is enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param logMessage {@link Supplier} of the message to log.
|
||||
* @return this aspect.
|
||||
* @see java.util.function.Supplier
|
||||
* @see org.slf4j.Logger#isTraceEnabled()
|
||||
* @see org.slf4j.Logger#trace(String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logTraceInfo(Supplier<String> logMessage) {
|
||||
|
||||
Logger logger = getLogger();
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(logMessage.get());
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link String message} formatted with the given array of {@link Object arguments}
|
||||
* at {@link Level#WARN} level when warnings are enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param message {@link String} containing the message to log.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return this aspect.
|
||||
* @see org.slf4j.Logger#isWarnEnabled()
|
||||
* @see org.slf4j.Logger#warn(String, Object...)
|
||||
* @see #format(String, Object...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logWarning(String message, Object... args) {
|
||||
|
||||
Logger logger = getLogger();
|
||||
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn(format(message, args), args);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the given {@link String message} formatted with the given array of {@link Object arguments}
|
||||
* at {@link Level#ERROR} level when error logging is enabled.
|
||||
*
|
||||
* @param <T> {@link Class} type extension of {@link AbstractGemFireAsLastResourceAspectSupport}.
|
||||
* @param message {@link String} containing the message to log.
|
||||
* @param args array of {@link Object arguments} used to format the message.
|
||||
* @return this aspect.
|
||||
* @see org.slf4j.Logger#isErrorEnabled()
|
||||
* @see org.slf4j.Logger#error(String, Object...)
|
||||
* @see #format(String, Object...)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends AbstractGemFireAsLastResourceAspectSupport> T logError(String message, Object... args) {
|
||||
|
||||
Logger logger = getLogger();
|
||||
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error(format(message, args), args);
|
||||
}
|
||||
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the {@link InitialContext} configured with the given {@link Hashtable environment}.
|
||||
*
|
||||
* @param environment {@link Hashtable} containing environment configuration meta-data used to access
|
||||
* the JNDI context in a managed environment.
|
||||
* @return a new instance of the {@link InitialContext} configured with the given {@link Hashtable environment}.
|
||||
* @throws NamingException if the {@link InitialContext} could not be initialized with
|
||||
* the provided {@link Hashtable environment}.
|
||||
* @see javax.naming.InitialContext
|
||||
* @see java.util.Hashtable
|
||||
*/
|
||||
protected InitialContext newInitialContext(Hashtable<?, ?> environment) throws NamingException {
|
||||
return new InitialContext(environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@link Logger} used by this application to log messages.
|
||||
*
|
||||
* @return a new, configured instance of {@link Logger}.
|
||||
*/
|
||||
protected Logger newLogger() {
|
||||
return LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the {@link Context} used to perform lookups of registered, managed objects in a management environment.
|
||||
*
|
||||
* @return the {@link Context} used to perform lookups of registered, managed objects in a managed environment.
|
||||
* @throws IllegalStateException if the {@link Context} could not be resolved.
|
||||
* @see org.apache.geode.cache.GemFireCache#getJNDIContext()
|
||||
* @see #newInitialContext(Hashtable)
|
||||
* @see #resolveEnvironment()
|
||||
* @see #resolveGemFireCache()
|
||||
* @see #getContext()
|
||||
* @see javax.naming.Context
|
||||
*/
|
||||
protected synchronized Context resolveContext() {
|
||||
|
||||
Context context = getContext();
|
||||
|
||||
if (context == null) {
|
||||
|
||||
Hashtable<?, ?> resolvedEnvironment = resolveEnvironment();
|
||||
|
||||
try {
|
||||
context = this.context = newInitialContext(resolvedEnvironment);
|
||||
}
|
||||
catch (NamingException cause) {
|
||||
context = this.context = Optional.ofNullable(resolveGemFireCache()).map(GemFireCache::getJNDIContext)
|
||||
.orElseThrow(() -> newIllegalStateException(cause,
|
||||
"Failed to initialize an %1$s with the provided Environment configuration ['%2$s']",
|
||||
InitialContext.class.getName(), resolvedEnvironment));
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the {@link Hashtable environment} used by the application to configure the {@link InitialContext}.
|
||||
*
|
||||
* @return the resolved {@link Hashtable environment} used to configure the {@link InitialContext}.
|
||||
* @see #getInitialContextFactory()
|
||||
* @see #getProviderUrl()
|
||||
* @see java.util.Hashtable
|
||||
*/
|
||||
protected Hashtable<?, ?> resolveEnvironment() {
|
||||
|
||||
Hashtable<Object, Object> environment = new Hashtable<>();
|
||||
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, getInitialContextFactory());
|
||||
environment.put(Context.PROVIDER_URL, getProviderUrl());
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a reference to the {@link GemFireCache} required by this Aspect to perform its function.
|
||||
*
|
||||
* This method either returns the configured {@link GemFireCache} instance or looks up
|
||||
* the {@link GemFireCache} instance using GemFire's API.
|
||||
*
|
||||
* @return a reference to the resolved {@link GemFireCache} instance.
|
||||
* @see org.springframework.data.gemfire.GemfireUtils#resolveGemFireCache()
|
||||
* @see org.apache.geode.cache.GemFireCache
|
||||
* @see #getGemFireCache()
|
||||
*/
|
||||
protected synchronized GemFireCache resolveGemFireCache() {
|
||||
|
||||
GemFireCache gemfireCache = getGemFireCache();
|
||||
|
||||
if (gemfireCache == null) {
|
||||
gemfireCache = this.gemfireCache = GemfireUtils.resolveGemFireCache();
|
||||
}
|
||||
|
||||
return gemfireCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the configured JNDI name used to lookup and resolve the GemFire JCA ResourceAdapter object
|
||||
* from the JNDI context in the managed environment.
|
||||
*
|
||||
* @return a {@link String} containing the JNDI name used to lookup and resolve the GemFire JCA ResourceAdapter
|
||||
* object from the JNDI context in the managed environment.
|
||||
* @see #getGemFireJcaResourceAdapterJndiName()
|
||||
*/
|
||||
protected String resolveGemFireJcaResourceAdapterJndiName() {
|
||||
|
||||
String gemfireJcaResourceAdapterJndiName = getGemFireJcaResourceAdapterJndiName();
|
||||
|
||||
return (StringUtils.hasText(gemfireJcaResourceAdapterJndiName) ? gemfireJcaResourceAdapterJndiName
|
||||
: DEFAULT_GEMFIRE_JCA_RESOURCE_ADAPTER_JNDI_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder method used to set the {@link #isThrowOnError() throwOnError} property.
|
||||
*
|
||||
* The {@link #isThrowOnError() throwOnError} property is used to indicate whether an Exception should be thrown
|
||||
* when an error occurs during the normal operation and function of this Aspect. By default, the error condition
|
||||
* is simply logged.
|
||||
*
|
||||
* @param <T> {@link Class sub-type} of this Aspect.
|
||||
* @param throwOnError boolean value used to set the {@link #isThrowOnError() throwOnError} property.
|
||||
* @return this Aspect.
|
||||
* @see #isThrowOnError()
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends AbstractGemFireAsLastResourceAspectSupport> T withThrowOnError(boolean throwOnError) {
|
||||
this.throwOnError = throwOnError;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
protected static class GemFireConnectionHolder {
|
||||
|
||||
private static final ThreadLocal<GFConnection> gemfireConnection = new ThreadLocal<>();
|
||||
|
||||
public static GFConnection acquire(GFConnectionFactory connectionFactory) {
|
||||
return acquire(connectionFactory, DEFAULT_THROW_ON_ERROR, NO_OP_LOGGER);
|
||||
}
|
||||
|
||||
public static GFConnection acquire(GFConnectionFactory connectionFactory, boolean throwOnError,
|
||||
Consumer<String> logger) {
|
||||
|
||||
try {
|
||||
return of(connectionFactory.getConnection());
|
||||
}
|
||||
catch (ResourceException cause) {
|
||||
|
||||
String message =
|
||||
String.format("Failed to acquire GemFire Connection from GemFire's JCA ResourceAdapter: %s",
|
||||
cause.getMessage());
|
||||
|
||||
if (throwOnError) {
|
||||
throw newRuntimeException(cause, message);
|
||||
}
|
||||
else {
|
||||
logger.accept(message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static GFConnection of(GFConnection connection) {
|
||||
gemfireConnection.set(connection);
|
||||
return connection;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static Optional<GFConnection> get() {
|
||||
return Optional.ofNullable(gemfireConnection.get());
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
close(DEFAULT_THROW_ON_ERROR, NO_OP_LOGGER);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
public static void close(boolean throwOnError, Consumer<String> logger) {
|
||||
|
||||
get().ifPresent(connection -> {
|
||||
try {
|
||||
connection.close();
|
||||
}
|
||||
catch (ResourceException cause) {
|
||||
|
||||
String message = String.format("Failed to close GemFire Connection: %s", cause.getMessage());
|
||||
|
||||
if (throwOnError) {
|
||||
throw newRuntimeException(cause, message);
|
||||
}
|
||||
else {
|
||||
logger.accept(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation.support;
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.apache.geode.ra.GFConnectionFactory;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* The {@link GemFireAsLastResourceConnectionAcquiringAspect} class is a {@link AbstractGemFireAsLastResourceAspectSupport}
|
||||
* implementation responsible for acquiring a GemFire Connection from GemFire's JCA ResourceAdapter,
|
||||
* {@link GFConnectionFactory} after a CMT/JTA Transaction is began, which is initiated by
|
||||
* Spring's Transaction infrastructure.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.ra.GFConnectionFactory
|
||||
* @see org.aspectj.lang.annotation.Aspect
|
||||
* @see org.aspectj.lang.annotation.Before
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.AbstractGemFireAsLastResourceAspectSupport
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Aspect
|
||||
public class GemFireAsLastResourceConnectionAcquiringAspect extends AbstractGemFireAsLastResourceAspectSupport {
|
||||
|
||||
private static final int DEFAULT_ORDER = 2048000;
|
||||
|
||||
@Autowired(required = false)
|
||||
private GFConnectionFactory gemfireConnectionFactory;
|
||||
|
||||
/**
|
||||
* Acquires (opens) a GemFire JCA ResourceAdapter Connection after the Spring CMT/JTA Transaction begins.
|
||||
*/
|
||||
@Before("atTransactionalType() || atTransactionalMethod()")
|
||||
public void doGemFireConnectionFactoryGetConnection() {
|
||||
|
||||
logTraceInfo("Acquiring GemFire Connection from GemFire JCA ResourceAdapter registered at [%s]...",
|
||||
resolveGemFireJcaResourceAdapterJndiName());
|
||||
|
||||
GemFireConnectionHolder.acquire(resolveGemFireConnectionFactory(), isThrowOnError(), this::logError);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
synchronized GFConnectionFactory resolveGemFireConnectionFactory() {
|
||||
|
||||
GFConnectionFactory connectionFactory = getGemFireConnectionFactory();
|
||||
|
||||
if (connectionFactory == null) {
|
||||
|
||||
String resolvedGemFireJcaResourceAdapterJndiName = resolveGemFireJcaResourceAdapterJndiName();
|
||||
|
||||
try {
|
||||
connectionFactory = this.gemfireConnectionFactory =
|
||||
(GFConnectionFactory) resolveContext().lookup(resolvedGemFireJcaResourceAdapterJndiName);
|
||||
}
|
||||
catch (NamingException cause) {
|
||||
throw newRuntimeException(cause,
|
||||
"Failed to resolve a GFConnectionFactory from the configured JNDI context name [%s]",
|
||||
resolvedGemFireJcaResourceAdapterJndiName);
|
||||
}
|
||||
}
|
||||
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the default order used by this AOP Aspect in the chain of Aspects configured
|
||||
* in Spring's Transaction Management.
|
||||
*
|
||||
* @return an int value specifying the default order used by this AOP Aspect in the chain of Aspects
|
||||
* configured in Spring's Transaction Management.
|
||||
*/
|
||||
@Override
|
||||
protected Integer getDefaultOrder() {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the configured {@link GFConnectionFactory} instance.
|
||||
*
|
||||
* @return a reference to the configured {@link GFConnectionFactory} instance; may be {@literal null}.
|
||||
* @see org.apache.geode.ra.GFConnectionFactory
|
||||
*/
|
||||
public synchronized GFConnectionFactory getGemFireConnectionFactory() {
|
||||
return this.gemfireConnectionFactory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation.support;
|
||||
|
||||
import org.aspectj.lang.annotation.After;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
||||
/**
|
||||
* The {@link GemFireAsLastResourceConnectionClosingAspect} class is a {@link AbstractGemFireAsLastResourceAspectSupport}
|
||||
* implementation responsible for closing the GemFire Connection obtained from the GemFire JCA ResourceAdapter
|
||||
* deployed in a managed environment when using GemFire as the Last Resource in a CMT/JTA Transaction
|
||||
* initiated from Spring's Transaction infrastructure.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.aspectj.lang.annotation.Aspect
|
||||
* @see org.aspectj.lang.annotation.After
|
||||
* @see org.springframework.data.gemfire.config.annotation.support.AbstractGemFireAsLastResourceAspectSupport
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Aspect
|
||||
public class GemFireAsLastResourceConnectionClosingAspect extends AbstractGemFireAsLastResourceAspectSupport {
|
||||
|
||||
private static final int DEFAULT_ORDER = 1024000;
|
||||
|
||||
/**
|
||||
* Closes the GemFire JCA ResourceAdapter Connection after the Spring CMT/JTA Transaction completes.
|
||||
*/
|
||||
@After("atTransactionalType() || atTransactionalMethod()")
|
||||
public void doGemFireConnectionClose() {
|
||||
|
||||
logTraceInfo("Closing GemFire Connection...");
|
||||
|
||||
GemFireConnectionHolder.close(isThrowOnError(), this::logWarning);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default order used by this AOP Aspect in the chain of Aspects configured
|
||||
* in Spring's Transaction Management.
|
||||
*
|
||||
* @return an int value specifying the default order used by this AOP Aspect in the chain of Aspects
|
||||
* configured in Spring's Transaction Management.
|
||||
*/
|
||||
@Override
|
||||
protected Integer getDefaultOrder() {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2017 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.data.gemfire.config.annotation.support;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The RegionDataAccessTracingAspect class...
|
||||
*
|
||||
* @author John Blum
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Aspect
|
||||
@SuppressWarnings("unused")
|
||||
public class RegionDataAccessTracingAspect {
|
||||
|
||||
private final Logger logger = newLogger();
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Logger newLogger() {
|
||||
return LoggerFactory.getLogger(getClass());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected String getCurrentThreadStackTrace() {
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
new Throwable().printStackTrace(new PrintWriter(writer));
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected Logger getLogger() {
|
||||
return this.logger;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Pointcut("target(com.gemstone.gemfire.cache.Region)")
|
||||
private void regionPointcut() {}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Pointcut("execution(* com.gemstone.gemfire.cache.Region.create(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.get(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.getAll(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.put(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.putAll(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.putIfAbsent(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.remove(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.replace(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.selectValue(..))"
|
||||
+ " || execution(* com.gemstone.gemfire.cache.Region.values(..))"
|
||||
+ "")
|
||||
private void regionDataAccessPointcut() {}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@Before("regionPointcut() && regionDataAccessPointcut()")
|
||||
public void regionDataAccessTracingAdvice() {
|
||||
getLogger().trace("Region data access call [{}]", getCurrentThreadStackTrace());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user