Skip to content

Commit

Permalink
ISPN-10137 Replace component metadata files with generated classes
Browse files Browse the repository at this point in the history
* Move component annotations to module component-annotations
* Generate accessor classes with annotation processor
* Deprecate ComponentMetadataRepo, replace with ModuleRepository
* Delete component metadata persister
* Require lifecycle with @InfinispanModule in each module
* ModuleLifecycle is no longer a service
* Require @scope for injection and lifecycle
* Require @Mbean for managed attributes or operations
* @scope and @Mbean are inherited (only from classes)
* Require duplicate @SurvivesRestarts on subclasses
* Annotated classes, fields, and methods must be package-private
* Anonymous classes are not supported
* Deprecate lifecycle method priorities
* Test module can register components via global configuration
  • Loading branch information
danberindei authored and wburns committed Jun 10, 2019
1 parent 846237e commit ddfcc89
Show file tree
Hide file tree
Showing 176 changed files with 3,039 additions and 1,271 deletions.
Expand Up @@ -15,8 +15,6 @@

<bean id="jpaStoreConfigurationParser" class="org.infinispan.persistence.jpa.configuration.JpaStoreConfigurationParser"/>
<service ref="jpaStoreConfigurationParser" interface="org.infinispan.configuration.parsing.ConfigurationParser"/>
<bean id="jpaStoreLifecycleManager" class="org.infinispan.persistence.jpa.impl.JpaStoreLifecycleManager"/>
<service ref="jpaStoreLifecycleManager" interface="org.infinispan.lifecycle.ModuleLifecycle"/>

<bean id="rocksDBStoreConfigurationParser" class="org.infinispan.persistence.rocksdb.configuration.RocksDBStoreConfigurationParser"/>
<service ref="rocksDBStoreConfigurationParser" interface="org.infinispan.configuration.parsing.ConfigurationParser"/>
Expand Down
22 changes: 17 additions & 5 deletions build-configuration/bom/pom.xml
Expand Up @@ -179,11 +179,23 @@
<artifactId>infinispan-commons-test</artifactId>
<version>${version.infinispan}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${version.infinispan}</version>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-component-annotations</artifactId>
<version>${version.infinispan}</version>
</dependency>
<!-- TODO should be here? -->
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-component-processor</artifactId>
<version>${version.infinispan}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${version.infinispan}</version>
</dependency>
<!-- TODO should be here? -->
<dependency>
<groupId>org.infinispan</groupId>
Expand Down
3 changes: 1 addition & 2 deletions cli/cli-interpreter/pom.xml
Expand Up @@ -138,8 +138,7 @@
<Include-Resource>
{maven-resources},
/META-INF/services=${project.basedir}/target/classes/META-INF/services,
/OSGI-INF/blueprint/blueprint.xml=${project.basedir}/target/classes/OSGI-INF/blueprint/blueprint.xml,
${project.build.outputDirectory}/${project.artifactId}-component-metadata.dat
/OSGI-INF/blueprint/blueprint.xml=${project.basedir}/target/classes/OSGI-INF/blueprint/blueprint.xml
</Include-Resource>
</instructions>
</configuration>
Expand Down

This file was deleted.

Expand Up @@ -7,15 +7,13 @@
import org.infinispan.commons.jmx.JmxUtil;
import org.infinispan.configuration.global.GlobalJmxStatisticsConfiguration;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.factories.components.ManageableComponentMetadata;
import org.infinispan.factories.annotations.InfinispanModule;
import org.infinispan.jmx.CacheManagerJmxRegistration;
import org.infinispan.jmx.ComponentsJmxRegistration;
import org.infinispan.jmx.ResourceDMBean;
import org.infinispan.lifecycle.ModuleLifecycle;
import org.infinispan.util.logging.LogFactory;
import org.kohsuke.MetaInfServices;

@MetaInfServices(org.infinispan.lifecycle.ModuleLifecycle.class)
@InfinispanModule(name = "cli-interpreter", requiredModules = "core")
public class LifecycleCallbacks implements ModuleLifecycle {
private static final Log log = LogFactory.getLog(LifecycleCallbacks.class, Log.class);

Expand All @@ -26,20 +24,14 @@ public void cacheManagerStarted(GlobalComponentRegistry gcr) {
// This works because the interpreter is not yet used internally, otherwise it would have to be in cacheManagerStarting
GlobalJmxStatisticsConfiguration globalCfg = gcr.getGlobalConfiguration().globalJmxStatistics();
if (globalCfg.enabled()) {
MBeanServer mbeanServer = JmxUtil.lookupMBeanServer(globalCfg.mbeanServerLookup(), globalCfg.properties());
String groupName = getGroupName(globalCfg.cacheManagerName());
Interpreter interpreter = new Interpreter();

gcr.registerComponent(interpreter, Interpreter.class);

// Pick up metadata from the component metadata repository
ManageableComponentMetadata meta = gcr.getComponentMetadataRepo().findComponentMetadata(Interpreter.class)
.toManageableComponentMetadata();
// And use this metadata when registering the transport as a dynamic MBean
try {
ResourceDMBean mbean = new ResourceDMBean(interpreter, meta);
interpreterObjName = new ObjectName(String.format("%s:%s,component=Interpreter", globalCfg.domain(), groupName));
JmxUtil.registerMBean(mbean, interpreterObjName, mbeanServer);
CacheManagerJmxRegistration jmxRegistration = gcr.getComponent(CacheManagerJmxRegistration.class);
jmxRegistration.registerExternalMBean(interpreter, globalCfg.domain(), groupName, "Interpreter");
} catch (Exception e) {
interpreterObjName = null;
log.jmxRegistrationFailed();
Expand Down
@@ -0,0 +1,4 @@
/**
* CLI interpreter engine
*/
package org.infinispan.cli.interpreter;
Expand Up @@ -4,20 +4,18 @@
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.infinispan.Cache;
import org.infinispan.AdvancedCache;
import org.infinispan.cli.interpreter.logging.Log;
import org.infinispan.cli.interpreter.result.Result;
import org.infinispan.cli.interpreter.result.StatementException;
import org.infinispan.cli.interpreter.result.StringResult;
import org.infinispan.cli.interpreter.session.Session;
import org.infinispan.factories.components.ComponentMetadata;
import org.infinispan.factories.components.ComponentMetadataRepo;
import org.infinispan.factories.components.JmxAttributeMetadata;
import org.infinispan.factories.components.ManageableComponentMetadata;
import org.infinispan.factories.impl.BasicComponentRegistry;
import org.infinispan.factories.impl.MBeanMetadata;
import org.infinispan.interceptors.AsyncInterceptor;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.util.logging.LogFactory;
Expand Down Expand Up @@ -59,7 +57,7 @@ public Result execute(Session session) throws StatementException {
}
}
} else {
printCacheStats(pw, session.getCache(cacheName));
printCacheStats(pw, session.getCache(cacheName).getAdvancedCache());
}

pw.flush();
Expand All @@ -83,31 +81,30 @@ private void printContainerStats(PrintWriter pw, DefaultCacheManager cacheManage
pw.println("}");
}

private void printCacheStats(PrintWriter pw, Cache<?, ?> cache) throws StatementException {
private void printCacheStats(PrintWriter pw, AdvancedCache<?, ?> cache) throws StatementException {
if (!cache.getCacheConfiguration().jmxStatistics().enabled()) {
throw log.statisticsNotEnabled(cache.getName());
}

for (AsyncInterceptor interceptor : cache.getAdvancedCache().getAsyncInterceptorChain().getInterceptors()) {
for (AsyncInterceptor interceptor : cache.getAsyncInterceptorChain().getInterceptors()) {
printComponentStats(pw, cache, interceptor);
}
printComponentStats(pw, cache, cache.getAdvancedCache().getLockManager());
printComponentStats(pw, cache, cache.getAdvancedCache().getRpcManager());
printComponentStats(pw, cache, cache.getLockManager());
printComponentStats(pw, cache, cache.getRpcManager());
}

private void printComponentStats(PrintWriter pw, Cache<?, ?> cache, Object component) {
private void printComponentStats(PrintWriter pw, AdvancedCache<?, ?> cache, Object component) {
if (component == null) {
return;
}
ComponentMetadataRepo mr = cache.getAdvancedCache().getComponentRegistry().getComponentMetadataRepo();
ComponentMetadata cm = mr.findComponentMetadata(component.getClass().getName());
if (cm == null || !(cm instanceof ManageableComponentMetadata)) {
BasicComponentRegistry bcr = cache.getComponentRegistry().getComponent(BasicComponentRegistry.class);
MBeanMetadata mBeanMetadata = bcr.getMBeanMetadata(component.getClass().getName());
if (mBeanMetadata == null) {
return;
}
ManageableComponentMetadata mcm = cm.toManageableComponentMetadata();
pw.printf("%s: {\n", mcm.getJmxObjectName());
List<JmxAttributeMetadata> attrs = new ArrayList<>(mcm.getAttributeMetadata());
Collections.sort(attrs, Comparator.comparing(JmxAttributeMetadata::getName));
pw.printf("%s: {\n", mBeanMetadata.getJmxObjectName());
List<JmxAttributeMetadata> attrs = new ArrayList<>(mBeanMetadata.getAttributes());
attrs.sort(Comparator.comparing(JmxAttributeMetadata::getName));
for (JmxAttributeMetadata s : attrs) {
pw.printf(" %s: %s\n", s.getName(), getAttributeValue(component, s));
}
Expand Down
@@ -0,0 +1,10 @@
package org.infinispan.client.hotrod;

import org.infinispan.factories.annotations.InfinispanModule;

/**
* {@code InfinispanModule} annotation is required for component annotation processing
*/
@InfinispanModule(name = "client-hotrod-tests")
public class TestsModule implements org.infinispan.lifecycle.ModuleLifecycle {
}
Expand Up @@ -2,6 +2,7 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -12,6 +13,7 @@
import org.infinispan.commons.CacheException;
import org.infinispan.commons.logging.Log;
import org.infinispan.commons.logging.LogFactory;

/**
* Basic reflection utilities to enhance what the JDK provides.
*
Expand Down Expand Up @@ -178,7 +180,17 @@ private static Field findFieldRecursively(Class<?> c, String fieldName) {
* @param parameters parameters
*/
public static Object invokeAccessibly(Object instance, Method method, Object[] parameters) {
return SecurityActions.invokeAccessibly(instance, method, parameters);
try {
method.setAccessible(true);
return method.invoke(instance, parameters);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
throw new CacheException("Unable to invoke method " + method + " on object of type " + (instance == null ? "null" : instance.getClass().getSimpleName()) +
(parameters != null ? " with parameters " + Arrays.asList(parameters) : ""), cause);
} catch (Exception e) {
throw new CacheException("Unable to invoke method " + method + " on object of type " + (instance == null ? "null" : instance.getClass().getSimpleName()) +
(parameters != null ? " with parameters " + Arrays.asList(parameters) : ""), e);
}
}

public static void setAccessibly(Object instance, Field field, Object value) {
Expand Down
@@ -1,12 +1,7 @@
package org.infinispan.commons.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;

import org.infinispan.commons.CacheException;

/**
* Privileged actions for the package
Expand Down Expand Up @@ -72,22 +67,6 @@ private static <T> T doPrivileged(PrivilegedAction<T> action) {
}
}

static Object invokeAccessibly(Object instance, Method method, Object[] parameters) {
return doPrivileged(() -> {
try {
method.setAccessible(true);
return method.invoke(instance, parameters);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause() != null ? e.getCause() : e;
throw new CacheException("Unable to invoke method " + method + " on object of type " + (instance == null ? "null" : instance.getClass().getSimpleName()) +
(parameters != null ? " with parameters " + Arrays.asList(parameters) : ""), cause);
} catch (Exception e) {
throw new CacheException("Unable to invoke method " + method + " on object of type " + (instance == null ? "null" : instance.getClass().getSimpleName()) +
(parameters != null ? " with parameters " + Arrays.asList(parameters) : ""), e);
}
});
}

static ClassLoader[] getClassLoaders(ClassLoader appClassLoader) {
return doPrivileged(() -> new ClassLoader[]{
appClassLoader, // User defined classes
Expand Down
58 changes: 58 additions & 0 deletions component-annotations/pom.xml
@@ -0,0 +1,58 @@
<?xml version='1.0' encoding='UTF-8'?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parent>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-parent</artifactId>
<version>10.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>infinispan-component-annotations</artifactId>
<packaging>bundle</packaging>
<name>Infinispan Component Annotations</name>
<description>Annotations for Infinispan components and MBeans</description>

<dependencies>
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
<artifactId>metainf-services</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${version.maven-compiler-plugin}</version>
<configuration>
<release>8</release>
<encoding>UTF-8</encoding>
<excludes>
<exclude>**/package-info.java</exclude>
</excludes>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Export-Package>
${project.groupId}.*;version=${project.version};-split-package:=error
</Export-Package>
<Import-Package>
!sun.reflect,
*
</Import-Package>
<Include-Resource>
{maven-resources}
</Include-Resource>
<DynamicImport-Package>*</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,28 @@
package org.infinispan.factories.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Mechanism for specifying the name of modules.
*
* There must be exactly one {@code InfinispanModule} annotation in each module.
*
* <p>It would have been nice to put the annotation on a package,
* but package-info.java source files are excluded from compilation
* because of MCOMPILER-205.</p>
*
* @author Dan Berindei
* @since 10.0
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.CLASS)
public @interface InfinispanModule {
String name();

String[] requiredModules() default {};

String[] optionalModules() default {};
}

0 comments on commit ddfcc89

Please sign in to comment.