All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.renarj.jasdb.core.SimpleKernel Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
package nl.renarj.jasdb.core;

import nl.renarj.jasdb.api.model.DBInstanceFactory;
import nl.renarj.jasdb.core.caching.GlobalCachingMemoryManager;
import nl.renarj.jasdb.core.exceptions.ConfigurationException;
import nl.renarj.jasdb.core.exceptions.JasDBException;
import nl.renarj.jasdb.core.exceptions.JasDBStorageException;
import nl.renarj.jasdb.core.exceptions.LocatorException;
import nl.renarj.jasdb.core.exceptions.NoComponentFoundException;
import nl.renarj.jasdb.core.locator.NodeInformation;
import nl.renarj.jasdb.core.platform.PlatformManager;
import nl.renarj.jasdb.core.platform.PlatformManagerFactory;
import nl.renarj.jasdb.service.StorageServiceFactory;
import nl.renarj.jasdb.storage.exceptions.RecordStoreInUseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SimpleKernel {
    private static final Logger LOG = LoggerFactory.getLogger(SimpleKernel.class);

    private static final Lock reconfigureLock = new ReentrantLock();
    private static SimpleKernel INSTANCE;

    private String instanceId = PlatformManagerFactory.getPlatformManager().getProcessId();
    private NodeInformation nodeInformation;
    private String kernelVersion = "unknown";

    private PlatformManager platformManager;

    private CountDownLatch latch = new CountDownLatch(1);

    private SimpleKernel() throws ConfigurationException {
		bootstrapKernel();
        LOG.debug("Loaded kernel with classloader instance: {}", getClass().getClassLoader().hashCode());
	}
	
	public static DBInstanceFactory getInstanceFactory() throws JasDBStorageException {
        return getInstance().platformManager.getComponent(DBInstanceFactory.class);
	}

	public static StorageServiceFactory getStorageServiceFactory() throws JasDBStorageException {
        return getInstance().platformManager.getComponent(StorageServiceFactory.class);
	}

    public static  T getKernelModule(Class requiredModuleType) throws JasDBStorageException {
        return getInstance().platformManager.getComponent(requiredModuleType);
    }

    public static NodeInformation getNodeInformation() throws JasDBStorageException {
        try {
            return getInstance().nodeInformation;
        } catch(ConfigurationException e) {
            throw new JasDBStorageException("Unable to get node information: " + e.getMessage());
        }
    }
	
	private static SimpleKernel getInstance() throws ConfigurationException {
		if(INSTANCE == null) {
            loadKernel();
		}
		return INSTANCE;
	}
	
	public static void shutdown() throws JasDBException {
        reconfigureLock.lock();
        try {
            if(INSTANCE != null) {
                INSTANCE.kernelShutdown();
            }
        } finally {
            reconfigureLock.unlock();
        }
	}

    private void kernelShutdown() throws JasDBException {
        LOG.info("Shutting down kernel");


        try {
            List remoteServices = platformManager.getComponents(RemoteService.class);
            if (remoteServices != null) {
                for (RemoteService remoteService : remoteServices) {
                    LOG.debug("Stopping remote service endpoint: {}", remoteService.getClass().getName());
                    remoteService.stopService();
                }
            }
        } catch(NoComponentFoundException e) {
            LOG.info("No Active RemoteService components found to stop");
        }

        LOG.debug("Doing kernel shutdown, stopping instance and storage services");

        GlobalCachingMemoryManager.shutdown();

        LOG.info("KernelShutdown shutdown complete");
        INSTANCE.latch.countDown();
        INSTANCE = null;

        PlatformManagerFactory.getPlatformManager().shutdownPlatform();
    }

    /**
     * Public kernel bootstrap initializer, this guarantees the kernel gets started with all services
     * @throws ConfigurationException
     */
	public static void initializeKernel() throws ConfigurationException {
		getInstance();
	}

    public static void waitForShutdown() throws ConfigurationException {
        try {
            getInstance().latch.await();
        } catch(InterruptedException e) {
            LOG.info("Interrupted whilst waiting for kernel shutdown");
        }
    }

    /**
     * This performs the actual kernel loading in case it was not initialized
     * @throws ConfigurationException
     */
	private static void loadKernel() throws ConfigurationException {
        reconfigureLock.lock();
        try {
            if(INSTANCE == null) {
                INSTANCE = new SimpleKernel();
            }
        } finally {
            reconfigureLock.unlock();
        }
	}
    
	private void bootstrapKernel() throws ConfigurationException {
        LOG.info("Bootstrapping database kernel");


        platformManager = PlatformManagerFactory.getPlatformManager();
        LOG.info("Initializing platform: {}", platformManager);

        platformManager.initializePlatform();

        LOG.info("Finished platform initialization");

        try {
            this.nodeInformation = new NodeInformation(instanceId, null);

            try {
                List remoteServices = platformManager.getComponents(RemoteService.class);
                if(remoteServices != null) {
                    for(RemoteService remoteService : remoteServices) {
                        if(remoteService.isEnabled()) {
                            this.nodeInformation.addServiceInformation(remoteService.getServiceInformation());

                            LOG.info("Starting remote service: {}", remoteService.getClass().getName());

                            remoteService.startService();
                        }
                    }
                }
            } catch(NoComponentFoundException e) {
                LOG.info("No remote service available");
            }

            kernelVersion = PlatformManagerFactory.getPlatformManager().getVersionData();
            LOG.info("Booting JasDB version: {}", kernelVersion);
            LOG.info("JasDB process id: {}", instanceId);
            registerShutdownHooks();

        } catch (LocatorException e) {
            handleBootupError("Unable to load kernel, unable to start locator service", e);
        } catch(RecordStoreInUseException e) {
            handleBootupError("Kernel cannot be loaded, DB is currently in use, are you running another JasDB instance on the same instance location?", e);
        } catch(JasDBException e) {
            handleBootupError("Unable to load kernel, storage services cannot be initialized", e);
        }
        LOG.info("Finished booting kernel, JASDB ready for usage...");
	}

    private void handleBootupError(String message, Throwable e) throws ConfigurationException {
        latch.countDown();
        String errorMessage = message + ": " + e.getMessage();
        LOG.error(message, e);
        throw new ConfigurationException(errorMessage);
    }

    private void registerShutdownHooks() throws JasDBStorageException {
        Thread shutdownThread = new Thread(new KernelShutdown());
        Runtime.getRuntime().addShutdownHook(shutdownThread);
    }

    public static String getVersion() throws ConfigurationException {
        return getInstance().kernelVersion;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy