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

org.appops.service.entrypoint.ServiceEntryPoint Maven / Gradle / Ivy

/*
 * AppOps is a Java framework to develop, deploy microservices with ease and is available for free
 * and common use developed by AinoSoft ( www.ainosoft.com )
 *
 * AppOps and AinoSoft are registered trademarks of Aino Softwares private limited, India.
 *
 * Copyright (C) <2016> 
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version along with applicable additional terms as
 * provisioned by GPL 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License and applicable additional terms
 * along with this program.
 *
 * If not, see  and 
 */

package org.appops.service.entrypoint;

import java.io.File;
import java.lang.annotation.Annotation;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.appops.configuration.ModuleConfig;
import org.appops.configuration.guice.ConfigServiceModule;
import org.appops.configuration.loader.ConfigurationLoader;
import org.appops.configuration.slimimpl.SlimImplStructure;
import org.appops.configuration.store.ConfigurationStore;
import org.appops.configuration.store.CurrentRunningServiceContext;
import org.appops.core.ClassPathAnalyser;
import org.appops.core.ServiceException;
import org.appops.core.deployment.DeploymentMode;
import org.appops.core.deployment.ServiceConfiguration;
import org.appops.core.service.meta.ServiceMeta;
import org.appops.marshaller.DescriptorType;
import org.appops.marshaller.Marshaller;
import org.appops.marshaller.guice.MarshallerModule;
import org.appops.service.ServiceInitializer;
import org.appops.service.deployment.ServiceJettyLauncher;
import org.appops.service.exception.AppEntryPointException;
import org.appops.service.exception.DeploymentException;
import org.appops.service.injection.ServiceBaseModule;
import org.appops.web.jetty.JettyWebServiceModule;

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.name.Names;

/**
 * 

* ServiceEntryPoint class. *

* */ public class ServiceEntryPoint { private static Injector BASE_INJECTOR = null; /** * Process raw arguments to select profile to use and to replace other configurations from command * line. * * @param args an array of {@link java.lang.String} objects. * @throws org.appops.core.ServiceException if any. */ public void startService(String[] args) throws ServiceException { startService(new ServiceArgs(args)); } /** * Read actual configurations and prepare modules to bind * * @param serviceArgs a {@link org.appops.service.entrypoint.ServiceArgs} object. */ protected void startService(ServiceArgs serviceArgs) { try { createBaseInjector(); String configString = FileUtils.readFileToString(serviceArgs.getServiceConfig(), StandardCharsets.UTF_8); Marshaller marshaller = BASE_INJECTOR.getInstance(Marshaller.class); DescriptorType descriptorType = DescriptorType.fromExtension(serviceArgs.getServiceConfig().getName()); ServiceConfiguration serviceConfiguration = marshaller.unmarshall(configString, ServiceConfiguration.class, descriptorType); String serviceDeploymentMode = serviceArgs.getDeploymentMode(); setDeployementMode(serviceDeploymentMode, serviceConfiguration); String depConfigLight = marshaller.marshall(serviceConfiguration.lightweightCopy(), descriptorType); ConfigurationStore configurationStore = BASE_INJECTOR.getInstance(ConfigurationStore.class); configurationStore.addConfiguration(ServiceConfiguration.class.getCanonicalName(), depConfigLight, descriptorType); String profileName = serviceArgs.getSelectedProfileName(); String profileRoot = serviceArgs.getProfileRoot(); File folder = new File(profileRoot + profileName); File[] listOfFiles = folder.listFiles(); HashMap serviceConfigMap = new HashMap<>(); for (File file : listOfFiles) { if (file.isDirectory()) { String slimImplServiceName = file.getName(); boolean isCoreService = false; if (serviceConfiguration.getServiceName().equals(slimImplServiceName)) { isCoreService = true; } File[] files = file.listFiles(); for (File slimImplconfigfile : files) { String configFileName = slimImplconfigfile.getName(); if (isYamlFile(configFileName)) { if (isCoreService) { populateServiceConfiguration(marshaller, slimImplconfigfile, serviceConfiguration, serviceConfigMap); } else if (serviceDeploymentMode.equalsIgnoreCase(DeploymentMode.CLUBBED.toString()) && isImplYml(configFileName)) { populateClubbedConfiguration(marshaller, slimImplconfigfile, slimImplServiceName, serviceConfigMap, serviceConfiguration.getMode()); } else if (serviceDeploymentMode.equalsIgnoreCase( DeploymentMode.STANDALONE.toString()) && !isImplYml(configFileName)) { populateStandaloneConfiguration(marshaller, slimImplconfigfile, slimImplServiceName, serviceConfigMap, serviceConfiguration.getMode()); } } } } } Injector appInjector = createAppInjector(BASE_INJECTOR, serviceConfigMap, serviceConfiguration.getMode(), serviceConfiguration); initializeServices(serviceConfigMap, appInjector, serviceConfiguration, profileName, profileRoot); ServiceJettyLauncher appLauncher = appInjector.getInstance(ServiceJettyLauncher.class); System.setProperty("currentProfile", profileName); System.setProperty("baseUrl", serviceConfiguration.serviceUrl()); appLauncher.launch(serviceConfiguration); } catch (Exception e) { throw new AppEntryPointException(e); } } /** * It checks given file is yaml file or not and return appropriate result. * * @param configFileName configuration file name * @return true, if file yaml file otherwise false */ private boolean isYamlFile(String configFileName) { if (configFileName.endsWith(".yml") || configFileName.endsWith(".yaml")) { return true; } return false; } /** * It populates the given instance of {@link ServiceConfiguration} using given file. * * @param marshaller instance of {@link Marshaller} * @param slimImplconfigfile instance of file contains service slim or impl configuration * @param serviceConfiguration instance of {@link ServiceConfiguration} * @param serviceConfigMap map of service name vs it's configuration * @throws Exception */ private void populateServiceConfiguration(Marshaller marshaller, File slimImplconfigfile, ServiceConfiguration serviceConfiguration, HashMap serviceConfigMap) throws Exception { try { String serviceconfigString = FileUtils.readFileToString(slimImplconfigfile, StandardCharsets.UTF_8); DescriptorType configDescriptorType = DescriptorType.fromExtension(slimImplconfigfile.getName()); SlimImplStructure slimImplConfig = marshaller.unmarshall(serviceconfigString, SlimImplStructure.class, configDescriptorType); if (slimImplconfigfile.getName().endsWith("slim.yml")) { serviceConfiguration.getModules().getSlimModules().addAll(slimImplConfig.getModules()); serviceConfigMap.put(serviceConfiguration.getServiceName(), serviceConfiguration); } else if (slimImplconfigfile.getName().endsWith("impl.yml")) { serviceConfiguration.getModules().getImplModules().addAll(slimImplConfig.getModules()); serviceConfigMap.put(serviceConfiguration.getServiceName(), serviceConfiguration); } } catch (Exception e) { throw e; } } /** * It sets the service deployment mode to given {@link ServiceConfiguration} instance. * * @param serviceDeploymentMode service deployment mode * @param serviceConfiguration instance of {@link ServiceConfiguration} * @throws Exception if occurred between validating service deployment mode. */ private void setDeployementMode(String serviceDeploymentMode, ServiceConfiguration serviceConfiguration) throws Exception { try { if (serviceDeploymentMode.equals(DeploymentMode.STANDALONE.name())) { serviceConfiguration.setMode(DeploymentMode.STANDALONE); } else if (serviceDeploymentMode.equals(DeploymentMode.CLUBBED.name())) { serviceConfiguration.setMode(DeploymentMode.CLUBBED); } else { throw new ServiceException("Invalid Deployment Mode :" + serviceDeploymentMode); } } catch (Exception e) { throw e; } } /** * It populates the configuration depending upon standalone mode. * * @param marshaller instance of {@link Marshaller} * @param configfile configuration file * @param slimConfigServiceName service name * @param serviceConfigMap map of service name vs its configuration * @param deploymentMode service deployment mode * @throws Exception If occurred while populating the service configuration map. */ private void populateStandaloneConfiguration(Marshaller marshaller, File configfile, String slimConfigServiceName, HashMap serviceConfigMap, DeploymentMode deploymentMode) throws Exception { try { String serviceconfigString = FileUtils.readFileToString(configfile, StandardCharsets.UTF_8); DescriptorType configDescriptorType = DescriptorType.fromExtension(configfile.getName()); SlimImplStructure slimImplConfig = marshaller.unmarshall(serviceconfigString, SlimImplStructure.class, configDescriptorType); ServiceConfiguration serviceConfiguration = populateServiceConfiguration(slimImplConfig, slimConfigServiceName, deploymentMode); serviceConfigMap.put(slimConfigServiceName, serviceConfiguration); } catch (Exception e) { throw e; } } /** * It populates the configuration depending upon clubbed mode. * * @param marshaller instance of {@link Marshaller} * @param configfile configuration file * @param implConfigServiceName service name * @param serviceConfigMap map of service name vs its configuration * @param deploymentMode service deployment mode * @throws Exception If occurred while populating the service configuration map. */ private void populateClubbedConfiguration(Marshaller marshaller, File configfile, String implConfigServiceName, HashMap serviceConfigMap, DeploymentMode deploymentMode) throws Exception { try { String serviceconfigString = FileUtils.readFileToString(configfile, StandardCharsets.UTF_8); DescriptorType configDescriptorType = DescriptorType.fromExtension(configfile.getName()); SlimImplStructure slimImplConfig = marshaller.unmarshall(serviceconfigString, SlimImplStructure.class, configDescriptorType); ServiceConfiguration serviceConfiguration = populateServiceConfiguration(slimImplConfig, implConfigServiceName, deploymentMode); serviceConfigMap.put(implConfigServiceName, serviceConfiguration); } catch (Exception e) { throw e; } } /** * It populates the {@link ServiceConfiguration} instance using given configuration and return it. * * @param slimImplConfig instance of {@link SlimImplStructure} * @param slimImplServiceName service name of given config file * @param deploymentMode service deployment mode * @return populated instance of {@link ServiceConfiguration} * @throws Exception If occurred between populating the {@link ServiceConfiguration} instance */ private ServiceConfiguration populateServiceConfiguration(SlimImplStructure slimImplConfig, String slimImplServiceName, DeploymentMode deploymentMode) throws Exception { try { if (slimImplConfig != null) { ServiceConfiguration serviceConfiguration = new ServiceConfiguration(); serviceConfiguration.setAnnotationClass(Class.forName(slimImplConfig.getAnnotationClass())); serviceConfiguration.setServiceConfig(slimImplConfig.getConfig()); serviceConfiguration.setServiceName(slimImplServiceName); if (deploymentMode.equals(DeploymentMode.STANDALONE)) { ModuleConfig slimModduleConfig = new ModuleConfig(); slimModduleConfig.setSlimModules(slimImplConfig.getModules()); serviceConfiguration.setModules(slimModduleConfig); } else if (deploymentMode.equals(DeploymentMode.CLUBBED)) { ModuleConfig implModuleConfig = new ModuleConfig(); implModuleConfig.setImplModules(slimImplConfig.getModules()); serviceConfiguration.setModules(implModuleConfig); } else { throw new DeploymentException("Deployment mode not matched " + deploymentMode.name()); } return serviceConfiguration; } } catch (Exception e) { throw e; } return null; } /** * It checks whether given config file name ends with impl or not and return appropriate result. * * @param configFileName configuration file name * @return true, if file name ends with impl.yml otherwise false */ private boolean isImplYml(String configFileName) { if (configFileName.endsWith("impl.yml")) { return true; } return false; } /** * @return base injector with core modules */ private static Injector createBaseInjector() { if (BASE_INJECTOR == null) { List modules = new ArrayList<>(); modules.add(new ConfigServiceModule()); modules.add(new MarshallerModule()); BASE_INJECTOR = Guice.createInjector(modules); } return BASE_INJECTOR; } /** * Initializes the services. * * @param services services configuration * @param appInjector app injector * @param entryPointConfig service entry point configuration * @param currentProfile current profile * @param profileRoot profile root */ private void initializeServices(Map services, Injector appInjector, ServiceConfiguration entryPointConfig, String currentProfile, String profileRoot) { ClassPathAnalyser classPathAnalyser = new ClassPathAnalyser(entryPointConfig.getPackageToScan()); Collection> initializers = classPathAnalyser.subTypesOf(ServiceInitializer.class); String currentService = entryPointConfig.getServiceName(); String baseConfigPath = profileRoot + currentProfile; try { initializeService(currentService, entryPointConfig, appInjector, initializers, baseConfigPath, entryPointConfig.getMode(), true); for (String serviceName : services.keySet()) { if (serviceName.contentEquals(currentService)) { continue; } ServiceConfiguration config = services.get(serviceName); initializeService(serviceName, config, appInjector, initializers, baseConfigPath, entryPointConfig.getMode(), false); } } catch (Exception e) { throw e; } } /** * It Initialize the service using given service configuration. * * @param serviceName name of the service * @param config instance of {@link ServiceConfiguration} * @param appInjector app injector * @param initializers service initializers * @param baseConfigPath base config path * @param deploymentMode mode of deployment * @param isCurrentService is the service is running service or not */ private static void initializeService(String serviceName, ServiceConfiguration config, Injector appInjector, Collection> initializers, String baseConfigPath, DeploymentMode deploymentMode, boolean isCurrentService) { baseConfigPath = baseConfigPath.endsWith("/") ? baseConfigPath : baseConfigPath + "/"; File ymlConfig = new File(baseConfigPath + serviceName + "/"); if (ymlConfig.exists()) { if (ymlConfig.isDirectory()) { loadConfig(serviceName, ymlConfig, appInjector, deploymentMode, isCurrentService); } else { System.out.println("Warning : Configuration for " + serviceName + " does not exist on path -> " + ymlConfig.getPath()); } } Class serviceAnnotation = (Class) config.getAnnotationClass(); for (Class initializer : initializers) { if (initializer.isAnnotationPresent(serviceAnnotation)) { appInjector.getInstance(CurrentRunningServiceContext.class).setCurrentRunningService(serviceName); appInjector.getInstance(initializer).initialize(serviceName, config, serviceAnnotation); initializers.remove(initializer); break; } } } /** * Load the configuration into {@link ConfigurationStore} * * @param serviceName name of the service * @param ymlConfig configuration file path * @param appInjector app injector * @param deploymentMode mode of deployment * @param isCurrentService is the service is running service or not */ private static void loadConfig(String serviceName, File ymlConfig, Injector appInjector, DeploymentMode deploymentMode, boolean isCurrentService) { for (File ymlFile : ymlConfig.listFiles()) { if (DeploymentMode.STANDALONE.equals(deploymentMode) && !isCurrentService && ymlFile.getName().contentEquals("impl.yml")) continue; appInjector.getInstance(ConfigurationLoader.class).loadConfigurationsFromFile(serviceName, ymlFile); } } /** * It creates the app injector using given entry poine and other service configuration and return * it. * * @param BASE_INJECTOR base injector * @param services service and its configuration * @param mode deployment mode * @param entryPoint entry point service configuration * @return populated app injector */ private static Injector createAppInjector(Injector BASE_INJECTOR, Map services, DeploymentMode mode, ServiceConfiguration entryPoint) { ModuleConfig finalConfig = new ModuleConfig(); for (String serviceName : services.keySet()) { if (!entryPoint.getServiceName().equals(serviceName)) { finalConfig.merge(services.get(serviceName).getModules()); } } Set finalModules = new LinkedHashSet<>(); finalModules.addAll(finalConfig.enabledModules(mode)); finalModules.addAll(getEntryPointServiceModules(entryPoint)); finalModules.add(new ServiceBaseModule()); finalModules.add(new JettyWebServiceModule()); return BASE_INJECTOR.createChildInjector(finalModules); } /** * It returns the module list from given service configuration. * * @param entryPoint entry point of configurations * @return modules list from given entry point */ private static Collection getEntryPointServiceModules( ServiceConfiguration entryPoint) { ModuleConfig moduleConfig = entryPoint.getModules(); return moduleConfig.instantiateModules(moduleConfig.getImplModules(), null); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy