PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/remote-query/remote-query-server/src/main/java/org/infinispan/query/remote/impl/LifecycleManager.java

https://github.com/Sanne/infinispan
Java | 216 lines | 172 code | 29 blank | 15 comment | 21 complexity | 6b10de12305987220ace1e7dc58223a5 MD5 | raw file
  1. package org.infinispan.query.remote.impl;
  2. import static org.infinispan.commons.dataconversion.MediaType.APPLICATION_JSON;
  3. import static org.infinispan.commons.dataconversion.MediaType.APPLICATION_OBJECT;
  4. import static org.infinispan.query.remote.client.ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME;
  5. import java.util.Map;
  6. import java.util.Set;
  7. import javax.management.ObjectName;
  8. import org.infinispan.AdvancedCache;
  9. import org.infinispan.Cache;
  10. import org.infinispan.commons.CacheConfigurationException;
  11. import org.infinispan.commons.CacheException;
  12. import org.infinispan.commons.dataconversion.ByteArrayWrapper;
  13. import org.infinispan.commons.dataconversion.MediaType;
  14. import org.infinispan.commons.dataconversion.Transcoder;
  15. import org.infinispan.commons.logging.LogFactory;
  16. import org.infinispan.commons.marshall.AdvancedExternalizer;
  17. import org.infinispan.configuration.cache.Configuration;
  18. import org.infinispan.configuration.cache.ContentTypeConfiguration;
  19. import org.infinispan.configuration.global.GlobalConfiguration;
  20. import org.infinispan.factories.ComponentRegistry;
  21. import org.infinispan.factories.GlobalComponentRegistry;
  22. import org.infinispan.factories.annotations.InfinispanModule;
  23. import org.infinispan.factories.impl.BasicComponentRegistry;
  24. import org.infinispan.jmx.CacheManagerJmxRegistration;
  25. import org.infinispan.lifecycle.ModuleLifecycle;
  26. import org.infinispan.manager.EmbeddedCacheManager;
  27. import org.infinispan.marshall.core.EncoderRegistry;
  28. import org.infinispan.marshall.protostream.impl.SerializationContextRegistry;
  29. import org.infinispan.protostream.SerializationContext;
  30. import org.infinispan.query.backend.KeyTransformationHandler;
  31. import org.infinispan.query.core.stats.IndexStatistics;
  32. import org.infinispan.query.core.stats.impl.LocalQueryStatistics;
  33. import org.infinispan.query.impl.ComponentRegistryUtils;
  34. import org.infinispan.query.impl.EntityLoader;
  35. import org.infinispan.query.remote.ProtobufMetadataManager;
  36. import org.infinispan.query.remote.client.impl.Externalizers.QueryRequestExternalizer;
  37. import org.infinispan.query.remote.client.impl.MarshallerRegistration;
  38. import org.infinispan.query.remote.client.impl.QueryRequest;
  39. import org.infinispan.query.remote.impl.filter.ContinuousQueryResultExternalizer;
  40. import org.infinispan.query.remote.impl.filter.FilterResultExternalizer;
  41. import org.infinispan.query.remote.impl.filter.IckleBinaryProtobufFilterAndConverter;
  42. import org.infinispan.query.remote.impl.filter.IckleContinuousQueryProtobufCacheEventFilterConverter;
  43. import org.infinispan.query.remote.impl.filter.IckleProtobufCacheEventFilterConverter;
  44. import org.infinispan.query.remote.impl.filter.IckleProtobufFilterAndConverter;
  45. import org.infinispan.query.remote.impl.logging.Log;
  46. import org.infinispan.query.remote.impl.mapping.SerializationContextSearchMapping;
  47. import org.infinispan.query.remote.impl.persistence.PersistenceContextInitializerImpl;
  48. import org.infinispan.query.stats.impl.LocalIndexStatistics;
  49. import org.infinispan.registry.InternalCacheRegistry;
  50. import org.infinispan.search.mapper.mapping.SearchMapping;
  51. import org.infinispan.search.mapper.mapping.SearchMappingCommonBuilding;
  52. /**
  53. * Initializes components for remote query. Each cache manager has its own instance of this class during its lifetime.
  54. *
  55. * @author anistor@redhat.com
  56. * @since 6.0
  57. */
  58. @InfinispanModule(name = "remote-query-server", requiredModules = {"core", "query", "server-core"})
  59. public final class LifecycleManager implements ModuleLifecycle {
  60. private static final Log log = LogFactory.getLog(LifecycleManager.class, Log.class);
  61. @Override
  62. public void cacheManagerStarting(GlobalComponentRegistry gcr, GlobalConfiguration globalCfg) {
  63. Map<Integer, AdvancedExternalizer<?>> externalizerMap = globalCfg.serialization().advancedExternalizers();
  64. externalizerMap.put(ExternalizerIds.ICKLE_PROTOBUF_CACHE_EVENT_FILTER_CONVERTER, new IckleProtobufCacheEventFilterConverter.Externalizer());
  65. externalizerMap.put(ExternalizerIds.ICKLE_PROTOBUF_FILTER_AND_CONVERTER, new IckleProtobufFilterAndConverter.Externalizer());
  66. externalizerMap.put(ExternalizerIds.ICKLE_CONTINUOUS_QUERY_CACHE_EVENT_FILTER_CONVERTER, new IckleContinuousQueryProtobufCacheEventFilterConverter.Externalizer());
  67. externalizerMap.put(ExternalizerIds.ICKLE_BINARY_PROTOBUF_FILTER_AND_CONVERTER, new IckleBinaryProtobufFilterAndConverter.Externalizer());
  68. externalizerMap.put(ExternalizerIds.ICKLE_CONTINUOUS_QUERY_RESULT, new ContinuousQueryResultExternalizer());
  69. externalizerMap.put(ExternalizerIds.ICKLE_FILTER_RESULT, new FilterResultExternalizer());
  70. BasicComponentRegistry bcr = gcr.getComponent(BasicComponentRegistry.class);
  71. SerializationContextRegistry ctxRegistry = gcr.getComponent(SerializationContextRegistry.class);
  72. ctxRegistry.addContextInitializer(SerializationContextRegistry.MarshallerType.PERSISTENCE, new PersistenceContextInitializerImpl());
  73. ctxRegistry.addContextInitializer(SerializationContextRegistry.MarshallerType.GLOBAL, MarshallerRegistration.INSTANCE);
  74. initProtobufMetadataManager(bcr);
  75. EmbeddedCacheManager cacheManager = gcr.getComponent(EmbeddedCacheManager.class);
  76. cacheManager.getClassAllowList()
  77. .addClasses(QueryRequest.class, QueryRequestExternalizer.class);
  78. }
  79. private void initProtobufMetadataManager(BasicComponentRegistry bcr) {
  80. ProtobufMetadataManagerImpl protobufMetadataManager = new ProtobufMetadataManagerImpl();
  81. bcr.registerComponent(ProtobufMetadataManager.class, protobufMetadataManager, true).running();
  82. EncoderRegistry encoderRegistry = bcr.getComponent(EncoderRegistry.class).wired();
  83. encoderRegistry.registerWrapper(ProtobufWrapper.INSTANCE);
  84. }
  85. @Override
  86. public void cacheManagerStarted(GlobalComponentRegistry gcr) {
  87. BasicComponentRegistry bcr = gcr.getComponent(BasicComponentRegistry.class);
  88. ProtobufMetadataManagerImpl protobufMetadataManager =
  89. (ProtobufMetadataManagerImpl) bcr.getComponent(ProtobufMetadataManager.class).running();
  90. // if not already running, start it
  91. protobufMetadataManager.getCache();
  92. GlobalConfiguration globalCfg = gcr.getGlobalConfiguration();
  93. if (globalCfg.jmx().enabled()) {
  94. registerProtobufMetadataManagerMBean(protobufMetadataManager, globalCfg, bcr);
  95. }
  96. }
  97. private void registerProtobufMetadataManagerMBean(ProtobufMetadataManagerImpl protobufMetadataManager,
  98. GlobalConfiguration globalConfig, BasicComponentRegistry bcr) {
  99. CacheManagerJmxRegistration jmxRegistration = bcr.getComponent(CacheManagerJmxRegistration.class).running();
  100. try {
  101. jmxRegistration.registerMBean(protobufMetadataManager, getRemoteQueryGroupName(globalConfig));
  102. } catch (Exception e) {
  103. throw new CacheException("Unable to register ProtobufMetadataManager MBean", e);
  104. }
  105. }
  106. private String getRemoteQueryGroupName(GlobalConfiguration globalConfig) {
  107. return "type=RemoteQuery,name=" + ObjectName.quote(globalConfig.cacheManagerName());
  108. }
  109. /**
  110. * Registers the interceptor in the ___protobuf_metadata cache before it gets started. Also creates query components
  111. * for user caches.
  112. */
  113. @Override
  114. public void cacheStarting(ComponentRegistry cr, Configuration cfg, String cacheName) {
  115. BasicComponentRegistry gcr = cr.getGlobalComponentRegistry().getComponent(BasicComponentRegistry.class);
  116. LocalQueryStatistics queryStatistics = cr.getComponent(LocalQueryStatistics.class);
  117. if (PROTOBUF_METADATA_CACHE_NAME.equals(cacheName)) {
  118. // a protobuf metadata cache is starting, need to register the interceptor
  119. ProtobufMetadataManagerImpl protobufMetadataManager =
  120. (ProtobufMetadataManagerImpl) gcr.getComponent(ProtobufMetadataManager.class).running();
  121. protobufMetadataManager.addProtobufMetadataManagerInterceptor(cr.getComponent(BasicComponentRegistry.class));
  122. }
  123. InternalCacheRegistry icr = gcr.getComponent(InternalCacheRegistry.class).running();
  124. if (!icr.isInternalCache(cacheName)) {
  125. // a stop dependency must be added for each non-internal cache
  126. ProtobufMetadataManagerImpl protobufMetadataManager =
  127. (ProtobufMetadataManagerImpl) gcr.getComponent(ProtobufMetadataManager.class).running();
  128. protobufMetadataManager.addCacheDependency(cacheName);
  129. // a remote query manager must be added for each non-internal cache
  130. SerializationContext serCtx = protobufMetadataManager.getSerializationContext();
  131. SearchMappingCommonBuilding commonBuilding = cr.getComponent(SearchMappingCommonBuilding.class);
  132. SearchMapping searchMapping = cr.getComponent(SearchMapping.class);
  133. if (commonBuilding != null && searchMapping == null) {
  134. AdvancedCache<?, ?> cache = cr.getComponent(Cache.class).getAdvancedCache().withStorageMediaType()
  135. .withWrapping(ByteArrayWrapper.class, ProtobufWrapper.class);
  136. KeyTransformationHandler keyTransformationHandler = ComponentRegistryUtils.getKeyTransformationHandler(cache);
  137. searchMapping = SerializationContextSearchMapping.buildMapping(commonBuilding,
  138. new EntityLoader<>(queryStatistics, cache, keyTransformationHandler),
  139. cache.getCacheConfiguration().indexing().indexedEntityTypes(), serCtx);
  140. if (searchMapping != null) {
  141. cr.registerComponent(searchMapping, SearchMapping.class);
  142. BasicComponentRegistry bcr = cr.getComponent(BasicComponentRegistry.class);
  143. bcr.replaceComponent(IndexStatistics.class.getName(), new LocalIndexStatistics(), true);
  144. bcr.rewire();
  145. }
  146. }
  147. RemoteQueryManager remoteQueryManager = buildQueryManager(cfg, serCtx, cr);
  148. cr.registerComponent(remoteQueryManager, RemoteQueryManager.class);
  149. if (cfg.indexing().enabled()) {
  150. AdvancedCache<?, ?> cache = cr.getComponent(Cache.class).getAdvancedCache();
  151. if (cache.getValueDataConversion().getStorageMediaType().match(MediaType.APPLICATION_PROTOSTREAM)) {
  152. // Try to resolve the indexed type names to protobuf type names.
  153. Set<String> knownTypes = protobufMetadataManager.getSerializationContext().getGenericDescriptors().keySet();
  154. for (String typeName : cfg.indexing().indexedEntityTypes()) {
  155. if (!knownTypes.contains(typeName)) {
  156. throw new CacheConfigurationException("The declared indexed type '" + typeName + "' is not known. Please register its proto schema file first.");
  157. }
  158. if (searchMapping == null || searchMapping.indexedEntity(typeName) == null) {
  159. throw log.typeNotIndexed(typeName);
  160. }
  161. }
  162. }
  163. }
  164. }
  165. }
  166. private RemoteQueryManager buildQueryManager(Configuration cfg, SerializationContext ctx, ComponentRegistry cr) {
  167. ContentTypeConfiguration valueEncoding = cfg.encoding().valueDataType();
  168. MediaType valueStorageMediaType = valueEncoding.mediaType();
  169. AdvancedCache<?, ?> cache = cr.getComponent(Cache.class).getAdvancedCache();
  170. MediaType storageMediaType = cache.getValueDataConversion().getStorageMediaType();
  171. QuerySerializers querySerializers = buildQuerySerializers(cr, storageMediaType);
  172. boolean isObjectStorage = valueStorageMediaType != null && valueStorageMediaType.match(APPLICATION_OBJECT);
  173. if (isObjectStorage) return new ObjectRemoteQueryManager(cache, cr, querySerializers);
  174. return new ProtobufRemoteQueryManager(cache, cr, ctx, querySerializers);
  175. }
  176. private QuerySerializers buildQuerySerializers(ComponentRegistry cr, MediaType storageMediaType) {
  177. EncoderRegistry encoderRegistry = cr.getGlobalComponentRegistry().getComponent(EncoderRegistry.class);
  178. QuerySerializers querySerializers = new QuerySerializers();
  179. DefaultQuerySerializer defaultQuerySerializer = new DefaultQuerySerializer(encoderRegistry);
  180. querySerializers.addSerializer(MediaType.MATCH_ALL, defaultQuerySerializer);
  181. if (encoderRegistry.isConversionSupported(storageMediaType, APPLICATION_JSON)) {
  182. Transcoder jsonStorage = encoderRegistry.getTranscoder(APPLICATION_JSON, storageMediaType);
  183. querySerializers.addSerializer(APPLICATION_JSON, new JsonQuerySerializer(storageMediaType, jsonStorage));
  184. }
  185. return querySerializers;
  186. }
  187. }