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

com.aol.micro.server.boot.config.MicrobootApp Maven / Gradle / Ivy

The newest version!
package com.aol.micro.server.boot.config;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import lombok.Getter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

import com.aol.cyclops.lambda.monads.SequenceM;
import com.aol.cyclops.lambda.utils.ExceptionSoftener;
import com.aol.micro.server.IncorrectNumberOfServersConfiguredException;
import com.aol.micro.server.Plugin;
import com.aol.micro.server.PluginLoader;
import com.aol.micro.server.config.Config;
import com.aol.micro.server.module.Module;
import com.aol.micro.server.servers.ApplicationRegister;
import com.aol.micro.server.servers.ServerApplication;
import com.aol.micro.server.servers.ServerApplicationFactory;
import com.aol.micro.server.servers.ServerRunner;
import com.aol.micro.server.spring.SpringContextFactory;
import com.aol.micro.server.spring.boot.BootApplicationConfigurator;




public class MicrobootApp {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	private final List modules;
	private final CompletableFuture end = new CompletableFuture();
	private final ExceptionSoftener softener = ExceptionSoftener.singleton.factory
			.getInstance();

	@Getter
	private final ApplicationContext springContext;

	/**
	 * This will construct a Spring context, using Spring Boot for this
	 * Microboot instance. The calling class will be used to determine the base
	 * package to auto-scan from for Spring Beans It will attempt to pick up an @Microservice
	 * annotation first, if not present the package of the calling class will be
	 * used.
	 * 
	 * @param modules
	 *            Multiple Microservice end points that can be deployed within a
	 *            single Spring context
	 */
	public MicrobootApp(Module... modules) {
		this.modules = Arrays.asList(modules);
		springContext = new SpringContextFactory(
				new MicrobootConfigurator().buildConfig(extractClass()),
				extractClass(), modules[0].getSpringConfigurationClasses())
				.withSpringBuilder(new BootApplicationConfigurator())
				.createSpringContext();

	}

	/**
	 * This will construct a Spring context, using Spring Boot for this
	 * Microboot instance. The provided class will be used to determine the base
	 * package to auto-scan from for Spring Beans It will attempt to pick up an @Microservice
	 * annotation first, if not present the package of the provided class will
	 * be used.
	 * 
	 * @param c
	 *            Class used to configure Spring
	 * @param modules
	 *            Multiple Microservice end points that can be deployed within a
	 *            single Spring context
	 */
	public MicrobootApp(Class c, Module... modules) {

		this.modules = Arrays.asList(modules);
		springContext = new SpringContextFactory(
				new MicrobootConfigurator().buildConfig(c), c,
				modules[0].getSpringConfigurationClasses()).withSpringBuilder(
				new BootApplicationConfigurator()).createSpringContext();

	}

	
	private Class extractClass() {
		try {
			return Class.forName(new Exception().getStackTrace()[2]
					.getClassName());
		} catch (ClassNotFoundException e) {
			softener.throwSoftenedException(e);
		}
		return null; // unreachable normally
	}

	public void stop() {

		end.complete(true);
		Config.reset();

	}

	public void run() {
		start().forEach(thread -> join(thread));
	}

	public List start() {

		List apps = modules
				.stream()
				.map(this::createServer)
				.collect(Collectors.toList());

		ServerRunner runner;
		try {

			runner = new ServerRunner(
					springContext.getBean(ApplicationRegister.class), apps, end);
		} catch (BeansException e) {
			runner = new ServerRunner(apps, end);
		}

		return runner.run();

	}
	private ServerApplication createServer(Module module) {
		List applications = SequenceM
				.fromStream(PluginLoader.INSTANCE.plugins.get().stream())
				.filter(m -> m.serverApplicationFactory() != null)
				.flatMapOptional(Plugin::serverApplicationFactory)
				.toList();
		if(applications.size()>1){
			logger.error("ERROR!  Multiple server application factories found ",applications);
			System.err.println("ERROR! Multiple server application factories found "+applications);
			throw new IncorrectNumberOfServersConfiguredException("Multiple server application factories found "+applications);
		}else if(applications.size()==0){
			logger.error("ERROR! No server application factories found.");
			System.err.println("ERROR! No server application factories found.");
			throw new IncorrectNumberOfServersConfiguredException("No server application factories found. ");
		}
		
		ServerApplication app = applications.get(0).createApp(module, springContext);
		
		if(Config.instance().getSslProperties()!=null)
			return app.withSSLProperties(Config.instance().getSslProperties());
		else
			return app;
	}
	private void join(Thread thread) {
		try {
			thread.join();
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			softener.throwSoftenedException(e);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy