Package org.infinispan.query.remote

Source Code of org.infinispan.query.remote.ProtobufMetadataManager$ProtobufMetadataRegistryListener

package org.infinispan.query.remote;

import org.infinispan.commons.util.Util;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Stop;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.jmx.annotations.MBean;
import org.infinispan.jmx.annotations.ManagedOperation;
import org.infinispan.jmx.annotations.Parameter;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
import org.infinispan.protostream.BaseMarshaller;
import org.infinispan.protostream.FileDescriptorSource;
import org.infinispan.protostream.SerializationContext;
import org.infinispan.query.remote.logging.Log;
import org.infinispan.registry.ClusterRegistry;
import org.infinispan.registry.ScopedKey;
import org.infinispan.util.logging.LogFactory;

import javax.management.MBeanException;
import javax.management.ObjectName;
import java.io.IOException;
import java.nio.file.Paths;

/**
* A clustered repository of protobuf descriptors. All protobuf types and their marshallers must be registered with this
* repository before being used.
*
* @author anistor@redhat.com
* @author gustavonalle
* @since 6.0
*/
@Scope(Scopes.GLOBAL)
@MBean(objectName = ProtobufMetadataManager.OBJECT_NAME,
        description = "Component that acts as a manager and container for Protocol Buffers metadata descriptors in the scope of a CacheManger.")
public class ProtobufMetadataManager implements ProtobufMetadataManagerMBean {

   private static final Log log = LogFactory.getLog(ProtobufMetadataManager.class, Log.class);

   public static final String OBJECT_NAME = "ProtobufMetadataManager";

   private static final String REGISTRY_SCOPE = ProtobufMetadataManager.class.getName();

   private static final String REGISTRY_KEY = "_descriptors";

   private ObjectName objectName;

   private ClusterRegistry<String, String, FileDescriptorSource> clusterRegistry;

   private volatile ProtobufMetadataRegistryListener registryListener;

   private final SerializationContext serCtx;

   public ProtobufMetadataManager(SerializationContext serCtx) {
      this.serCtx = serCtx;
   }

   private void ensureInit() {
      if (registryListener == null) {
         synchronized (this) {
            if (registryListener == null) {
               registryListener = new ProtobufMetadataRegistryListener();
               clusterRegistry.addListener(REGISTRY_SCOPE, registryListener);
               FileDescriptorSource descriptorSource = getFileDescriptorSource();
               if (!descriptorSource.getFileDescriptors().isEmpty()) {
                  try {
                     serCtx.registerProtoFiles(descriptorSource);
                  } catch (Exception e) {
                     log.error(e);
                  }
               }
            }
         }
      }
   }

   @Inject
   protected void injectDependencies(ClusterRegistry<String, String, FileDescriptorSource> clusterRegistry) {
      this.clusterRegistry = clusterRegistry;
   }

   @Stop
   protected void stop() {
      if (registryListener != null) {
         clusterRegistry.removeListener(registryListener);
         registryListener = null;
      }
   }

   public ObjectName getObjectName() {
      return objectName;
   }

   public void setObjectName(ObjectName objectName) {
      this.objectName = objectName;
   }

   public <T> void registerMarshaller(BaseMarshaller<T> marshaller) {
      ensureInit();
      serCtx.registerMarshaller(marshaller);
   }

   @ManagedOperation(description = "Registers a set of Protobuf definition files", displayName = "Register Protofiles")
   public void registerProtofiles(@Parameter(name = "fileNames", description = "names of the protofiles") String[] names,
                                  @Parameter(name = "fileContents", description = "content of the files") String[] contents)
           throws Exception {
      if (names.length != contents.length)
         throw new MBeanException(new IllegalArgumentException("invalid parameter sizes"));
      FileDescriptorSource fileDescriptorSource = getFileDescriptorSource();
      for (int i = 0; i < names.length; i++) {
         fileDescriptorSource.addProtoFile(names[i], contents[i]);
      }
      clusterRegistry.put(REGISTRY_SCOPE, REGISTRY_KEY, fileDescriptorSource);
   }

   @ManagedOperation(description = "Registers a Protobuf definition file", displayName = "Register Protofile")
   public void registerProtofile(@Parameter(name = "fileName", description = "the name of the .proto file") String name,
                                 @Parameter(name = "contents", description = "contents of the file") String contents) throws Exception {
      FileDescriptorSource fileDescriptorSource = getFileDescriptorSource();
      fileDescriptorSource.addProtoFile(name, contents);

      clusterRegistry.put(REGISTRY_SCOPE, REGISTRY_KEY, fileDescriptorSource);
   }

   @ManagedOperation(description = "Display a protobuf definition file", displayName = "Register Protofile")
   public String displayProtofile(@Parameter(name = "fileName", description = "the name of the .proto file") String name) {
      FileDescriptorSource fileDescriptorSource = clusterRegistry.get(REGISTRY_SCOPE, REGISTRY_KEY);
      if (fileDescriptorSource == null)
         return null;
      char[] data = fileDescriptorSource.getFileDescriptors().get(name);
      return data != null ? String.valueOf(data) : null;
   }

   public void registerProtofiles(String... classPathResources) throws Exception {
      FileDescriptorSource fileDescriptorSource = getFileDescriptorSource();
      for (String classPathResource : classPathResources) {
         String fileName = Paths.get(classPathResource).getFileName().toString();
         fileDescriptorSource.addProtoFile(fileName, Util.getResourceAsStream(classPathResource, getClass().getClassLoader()));
      }
      clusterRegistry.put(REGISTRY_SCOPE, REGISTRY_KEY, fileDescriptorSource);
   }

   public static SerializationContext getSerializationContext(EmbeddedCacheManager cacheManager) {
      if (cacheManager == null) {
         throw new IllegalArgumentException("cacheManager cannot be null");
      }
      ProtobufMetadataManager metadataManager = cacheManager.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class);
      if (metadataManager == null) {
         throw new IllegalStateException("ProtobufMetadataManager not initialised yet!");
      }
      metadataManager.ensureInit();
      return metadataManager.serCtx;
   }

   private FileDescriptorSource getFileDescriptorSource() {
      FileDescriptorSource fileDescriptorSource = clusterRegistry.get(REGISTRY_SCOPE, REGISTRY_KEY);
      if (fileDescriptorSource == null) {
         fileDescriptorSource = new FileDescriptorSource();
      }
      return fileDescriptorSource;
   }

   @Listener
   class ProtobufMetadataRegistryListener {

      @CacheEntryCreated
      public void created(CacheEntryCreatedEvent<ScopedKey<String, String>, FileDescriptorSource> e) throws IOException {
         if (!e.isPre()) {
            registerProtofile(e.getValue());
         }
      }

      private void registerProtofile(FileDescriptorSource value) throws IOException {
         serCtx.registerProtoFiles(value);
      }

      @CacheEntryModified
      public void modified(CacheEntryModifiedEvent<ScopedKey<String, String>, FileDescriptorSource> e) throws IOException {
         if (!e.isPre()) {
            registerProtofile(e.getValue());
         }
      }
   }
}
TOP

Related Classes of org.infinispan.query.remote.ProtobufMetadataManager$ProtobufMetadataRegistryListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.