Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2017-2020 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
*
* https://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 Pivotal 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 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 {@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 getGemFireCache() {
return (T) this.gemfireCache;
}
/**
* Returns the configured reference to Pivotal GemFire's JCA ResourceAdapter registered in the managed environment's
* JNDI context.
*
* @return a {@link String} containing the configured reference to Pivotal 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 {@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 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 {@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 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 {@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 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 {@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 logTraceInfo(Supplier 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 {@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 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 {@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 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