/** * Find the prioritized stream of configurations for a given module (inclusive of the module itself). * * @param nodeName The name of the initial module whose dependency should be resolved * * @return A list of modules returned in the order of increasing precedence * * @throws SystemConfigException if the graph can't be resolved */ public Stream<String> preOrderRightToLeftTraversal(String nodeName) throws SystemConfigException { if (!moduleConfigurations.containsKey(nodeName)) { LOG.error(NO_SUCH_MODULE.logFormat(nodeName)); throw new SystemConfigException(NO_SUCH_MODULE.format(nodeName)); } return preOrderRightToLeftTraversal(nodeName, new ArrayList<>()); }
/** * Use a string to load a stream of all resources from the class path which match a given name. * * @param name The class path address of a resource ('/foo' means a resource named foo in the default package) * * @return A stream of all class path resources corresponding to a particular name * * @throws IOException if any resources cannot be read from the class path successfully. */ public Stream<Resource> loadResourcesWithName(String name) throws IOException { String resourceName = RESOURCE_LOADER_PREFIX + name; LOG.debug("Loading resources named '{}'", resourceName); return Arrays.stream(resolver.getResources(resourceName)) .peek(it -> LOG.debug(RESOURCE_LOAD_MESSAGE.logFormat(name, it))); }
/** * Build a configuration object from a resource, processing it as a properties file. * * @param resource The resource referring to a properties file * * @return a Configuration object containing a properties configuration */ public Configuration loadConfigFromResource(Resource resource) { PropertiesConfiguration result = new PropertiesConfiguration(); try { result.load(resource.getInputStream()); return result; } catch (ConfigurationException | IOException e) { String message = CONFIGURATION_LOAD_ERROR.format(resource.getFilename()); LOG.error(message, e); throw new SystemConfigException(message, e); } }
/** * Use a string to load a stream of all resources from the class path which match a given name. * * @param name The class path address of a resource ('/foo' means a resource named foo in the default package) * * @return A stream of all class path resources corresponding to a particular name * * @throws IOException if any resources cannot be read from the class path successfully. */ public Stream<Resource> loadResourcesWithName(String name) throws IOException { String resourceName = RESOURCE_LOADER_PREFIX + name; LOG.debug("Loading resources named '{}'", resourceName); return Arrays.stream(resolver.getResources(resourceName)) .peek(it -> LOG.debug(RESOURCE_LOAD_MESSAGE.logFormat(name, it))); }
/** * Build a configuration object from a resource, processing it as a properties file. * * @param resource The resource referring to a properties file * * @return a Configuration object containing a properties configuration */ public Configuration loadConfigFromResource(Resource resource) { PropertiesConfiguration result = new PropertiesConfiguration(); try { result.load(resource.getInputStream()); return result; } catch (ConfigurationException | IOException e) { String message = CONFIGURATION_LOAD_ERROR.format(resource.getFilename()); LOG.error(message, e); throw new SystemConfigException(message, e); } }
/** * Find the prioritized stream of configurations for a given module (inclusive of the module itself). * * @param nodeName The name of the initial module whose dependency should be resolved * * @return A list of modules returned in the order of increasing precedence * * @throws SystemConfigException if the graph can't be resolved */ public Stream<String> preOrderRightToLeftTraversal(String nodeName) throws SystemConfigException { if (!moduleConfigurations.containsKey(nodeName)) { LOG.error(NO_SUCH_MODULE.logFormat(nodeName)); throw new SystemConfigException(NO_SUCH_MODULE.format(nodeName)); } return preOrderRightToLeftTraversal(nodeName, new ArrayList<>()); }
/** * Find the prioritized stream of configurations for a given module (inclusive of the module itself). * * @param nodeName The name of the initial module whose dependencies to load (inclusively) * @param path The list of nodes back to the root of the tree parse * * @return A list of modules returned in the order of increasing precedence * * @throws SystemConfigException if there is a broken or circular dependency link */ protected Stream<String> preOrderRightToLeftTraversal(String nodeName, List<String> path) throws SystemConfigException { if (!moduleConfigurations.containsKey(nodeName)) { LOG.error(MISSING_DEPENDENCY.logFormat(nodeName, path)); throw new SystemConfigException(MISSING_DEPENDENCY.format(nodeName, path)); } if (path.contains(nodeName)) { LOG.error(CIRCULAR_DEPENDENCY.logFormat(nodeName, path)); throw new SystemConfigException(CIRCULAR_DEPENDENCY.format(nodeName, path)); } List<String> pathLocal = new ArrayList<>(path); pathLocal.add(nodeName); Stream<String> childrenStream = moduleDependencies.get(nodeName).stream() .flatMap(childNode -> preOrderRightToLeftTraversal(childNode, pathLocal)); return Stream.concat(Stream.of(nodeName), childrenStream); }
if (!configuration.containsKey(MODULE_NAME_KEY)) { LOG.warn(MODULE_NAME_MISSING.logFormat(configName)); return; nameValidator.accept(moduleName); LOG.debug(MODULE_FOUND_MESSAGE.logFormat(moduleName, configName)); if (moduleConfigurations.containsKey(moduleName)) { LOG.error(MODULE_NAME_DUPLICATION.format(configName, moduleName)); throw new SystemConfigException(MODULE_NAME_DUPLICATION.format(configName, moduleName)); LOG.debug(MODULE_DEPENDS_ON_MESSAGE.logFormat(moduleName, dependencies));
/** * Build the graph of configurations and dependencies. * * @return A graph whose vertices are Configurations and whose edges are dependencies between them. * * @throws SystemConfigException If any errors occur while parsing the configurations into a graph. */ private ConfigurationGraph loadConfigurationGraph() throws SystemConfigException { try { Map<Configuration, String> configurationFileNameMap = configResourceLoader .loadResourcesWithName(MODULE_CONFIG_FILE_NAME) .collect(Collectors.toMap(configResourceLoader::loadConfigFromResource, Resource::getDescription) ); return new ConfigurationGraph(configurationFileNameMap, ModuleLoader::validateModuleName); } catch (IOException e) { LOG.error(MODULE_IO_EXCEPTION.logFormat(e.getMessage())); throw new SystemConfigException(MODULE_IO_EXCEPTION.format(e.getMessage()), e); } }
if (!configuration.containsKey(MODULE_NAME_KEY)) { LOG.warn(MODULE_NAME_MISSING.logFormat(configName)); return; nameValidator.accept(moduleName); LOG.debug(MODULE_FOUND_MESSAGE.logFormat(moduleName, configName)); if (moduleConfigurations.containsKey(moduleName)) { LOG.error(MODULE_NAME_DUPLICATION.format(configName, moduleName)); throw new SystemConfigException(MODULE_NAME_DUPLICATION.format(configName, moduleName)); LOG.debug(MODULE_DEPENDS_ON_MESSAGE.logFormat(moduleName, dependencies));
/** * Build the graph of configurations and dependencies. * * @return A graph whose vertices are Configurations and whose edges are dependencies between them. * * @throws SystemConfigException If any errors occur while parsing the configurations into a graph. */ private ConfigurationGraph loadConfigurationGraph() throws SystemConfigException { try { Map<Configuration, String> configurationFileNameMap = configResourceLoader .loadResourcesWithName(MODULE_CONFIG_FILE_NAME) .collect(Collectors.toMap(configResourceLoader::loadConfigFromResource, Resource::getDescription) ); return new ConfigurationGraph(configurationFileNameMap, ModuleLoader::validateModuleName); } catch (IOException e) { LOG.error(MODULE_IO_EXCEPTION.logFormat(e.getMessage())); throw new SystemConfigException(MODULE_IO_EXCEPTION.format(e.getMessage()), e); } }
/** * Find the prioritized stream of configurations for a given module (inclusive of the module itself). * * @param nodeName The name of the initial module whose dependencies to load (inclusively) * @param path The list of nodes back to the root of the tree parse * * @return A list of modules returned in the order of increasing precedence * * @throws SystemConfigException if there is a broken or circular dependency link */ protected Stream<String> preOrderRightToLeftTraversal(String nodeName, List<String> path) throws SystemConfigException { if (!moduleConfigurations.containsKey(nodeName)) { LOG.error(MISSING_DEPENDENCY.logFormat(nodeName, path)); throw new SystemConfigException(MISSING_DEPENDENCY.format(nodeName, path)); } if (path.contains(nodeName)) { LOG.error(CIRCULAR_DEPENDENCY.logFormat(nodeName, path)); throw new SystemConfigException(CIRCULAR_DEPENDENCY.format(nodeName, path)); } List<String> pathLocal = new ArrayList<>(path); pathLocal.add(nodeName); Stream<String> childrenStream = moduleDependencies.get(nodeName).stream() .flatMap(childNode -> preOrderRightToLeftTraversal(childNode, pathLocal)); return Stream.concat(Stream.of(nodeName), childrenStream); }
LOG.error(INVALID_MODULE_CONFIGURATION.logFormat(MODULE_NAME_IS_TOO_SHORT, name)); throw new SystemConfigException(INVALID_MODULE_CONFIGURATION.format(MODULE_NAME_IS_TOO_SHORT, name)); LOG.error(INVALID_MODULE_NAME.logFormat(name, message)); throw new SystemConfigException(INVALID_MODULE_NAME.logFormat(name, message));
LOG.error(INVALID_MODULE_CONFIGURATION.logFormat(MODULE_NAME_IS_TOO_SHORT, name)); throw new SystemConfigException(INVALID_MODULE_CONFIGURATION.format(MODULE_NAME_IS_TOO_SHORT, name)); LOG.error(INVALID_MODULE_NAME.logFormat(name, message)); throw new SystemConfigException(INVALID_MODULE_NAME.logFormat(name, message));
List<Resource> resources = loader.loadResourcesWithName(USER_CONFIG_FILE_NAME) .collect(Collectors.toList()); LOG.error(TOO_MANY_USER_CONFIGS.logFormat(resources.toString())); throw new SystemConfigException(TOO_MANY_USER_CONFIGS.format(resources.size())); List<Resource> resources = loader.loadResourcesWithName(APPLICATION_CONFIG_FILE_NAME) .collect(Collectors.toList()); LOG.error(TOO_MANY_APPLICATION_CONFIGS.logFormat(resources.toString())); throw new SystemConfigException(TOO_MANY_APPLICATION_CONFIGS.format(resources.size()));
List<Resource> resources = loader.loadResourcesWithName(USER_CONFIG_FILE_NAME) .collect(Collectors.toList()); LOG.error(TOO_MANY_USER_CONFIGS.logFormat(resources.toString())); throw new SystemConfigException(TOO_MANY_USER_CONFIGS.format(resources.size())); List<Resource> resources = loader.loadResourcesWithName(APPLICATION_CONFIG_FILE_NAME) .collect(Collectors.toList()); LOG.error(TOO_MANY_APPLICATION_CONFIGS.logFormat(resources.toString())); throw new SystemConfigException(TOO_MANY_APPLICATION_CONFIGS.format(resources.size()));