private void processSubsystemConfigInFeaturePack( ServerProvisioningFeaturePack provisioningFeaturePack, ServerProvisioning serverProvisioning, ArtifactFileResolver artifactFileResolver) throws IOException { File artifactFile = artifactFileResolver.getArtifactFile( provisioningFeaturePack.getFeaturePack().getArtifact()); // features packs themselves can contain a 'subsystem-templates' directory. Templates in the // feature pack override ones from modules serverProvisioning .getConfig() .getInputStreamSources() .addAllSubsystemFileSourcesFromZipFile(artifactFile); }
public void build() { final ServerProvisioning serverProvisioning = new ServerProvisioning(description); final List<String> errors = new ArrayList<>(); try { // create the feature packs for (ServerProvisioningDescription.FeaturePack serverProvisioningFeaturePackDescription : description.getFeaturePacks()) { final FeaturePack featurePack = FeaturePackFactory.createPack( serverProvisioningFeaturePackDescription.getArtifact(), artifactFileResolver, versionOverrideArtifactResolver); serverProvisioning .getFeaturePacks() .add( new ServerProvisioningFeaturePack( serverProvisioningFeaturePackDescription, featurePack, artifactFileResolver)); } // create output dir FileUtils.deleteRecursive(outputDirectory); outputDirectory.mkdirs(); // create schema output dir if needed final File schemaOutputDirectory; if (description.isExtractSchemas()) { schemaOutputDirectory = new File(outputDirectory, SUBSYSTEM_SCHEMA_TARGET_DIRECTORY); if (!schemaOutputDirectory.exists()) { schemaOutputDirectory.mkdirs(); } } else { schemaOutputDirectory = null; } final Set<String> filesProcessed = new HashSet<>(); // process server provisioning copy-artifacts processCopyArtifacts( serverProvisioning.getDescription().getCopyArtifacts(), versionOverrideArtifactResolver, outputDirectory, filesProcessed, artifactFileResolver, schemaOutputDirectory); // process modules (needs to be done for all feature packs before any config is processed, due // to subsystem template gathering) processModules( serverProvisioning, outputDirectory, filesProcessed, artifactFileResolver, schemaOutputDirectory); // process everything else for each feature pack for (ServerProvisioningFeaturePack provisioningFeaturePack : serverProvisioning.getFeaturePacks()) { processSubsystemConfigInFeaturePack( provisioningFeaturePack, serverProvisioning, artifactFileResolver); processFeaturePackCopyArtifacts( provisioningFeaturePack.getFeaturePack(), outputDirectory, filesProcessed, artifactFileResolver, schemaOutputDirectory, description.isExcludeDependencies()); processProvisioningFeaturePackContents( provisioningFeaturePack, outputDirectory, filesProcessed, description.isExcludeDependencies()); processFeaturePackFilePermissions( provisioningFeaturePack.getFeaturePack(), outputDirectory, description.isExcludeDependencies()); } // process the server config processConfig(serverProvisioning, outputDirectory, filesProcessed); } catch (Throwable e) { throw new RuntimeException(e); } finally { if (!errors.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("Some errors were encountered creating the feature pack\n"); for (String error : errors) { sb.append(error); sb.append("\n"); } throw new RuntimeException(sb.toString()); } } }
private void processConfig( ServerProvisioning serverProvisioning, File outputDirectory, Set<String> filesProcessed) throws IOException, XMLStreamException { ServerProvisioning.Config provisioningConfig = serverProvisioning.getConfig(); // 1. collect and merge each feature pack configs for (ServerProvisioningFeaturePack provisioningFeaturePack : serverProvisioning.getFeaturePacks()) { processFeaturePackConfig(provisioningFeaturePack, provisioningConfig); } // 2. assemble the merged configs for (ServerProvisioning.ConfigFile provisioningConfigFile : provisioningConfig.getDomainConfigFiles().values()) { if (provisioningConfigFile.getTemplateInputStreamSource() == null) { getLog() .debugf( "Skipping assembly of config file %s, template not set.", provisioningConfigFile.getOutputFile()); continue; } getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile()); filesProcessed.add(provisioningConfigFile.getOutputFile()); new ConfigurationAssembler( provisioningConfig.getInputStreamSources(), provisioningConfigFile.getTemplateInputStreamSource(), "domain", provisioningConfigFile.getSubsystems(), new File(outputDirectory, provisioningConfigFile.getOutputFile())) .assemble(); } for (ServerProvisioning.ConfigFile provisioningConfigFile : provisioningConfig.getStandaloneConfigFiles().values()) { if (provisioningConfigFile.getTemplateInputStreamSource() == null) { getLog() .debugf( "Skipping assembly of config file %s, template not set.", provisioningConfigFile.getOutputFile()); continue; } getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile()); filesProcessed.add(provisioningConfigFile.getOutputFile()); new ConfigurationAssembler( provisioningConfig.getInputStreamSources(), provisioningConfigFile.getTemplateInputStreamSource(), "server", provisioningConfigFile.getSubsystems(), new File(outputDirectory, provisioningConfigFile.getOutputFile())) .assemble(); } for (ServerProvisioning.ConfigFile provisioningConfigFile : provisioningConfig.getHostConfigFiles().values()) { if (provisioningConfigFile.getTemplateInputStreamSource() == null) { getLog() .debugf( "Skipping assembly of config file %s, template not set.", provisioningConfigFile.getOutputFile()); continue; } getLog().debugf("Assembling config file %s", provisioningConfigFile.getOutputFile()); filesProcessed.add(provisioningConfigFile.getOutputFile()); new ConfigurationAssembler( provisioningConfig.getInputStreamSources(), provisioningConfigFile.getTemplateInputStreamSource(), "host", provisioningConfigFile.getSubsystems(), new File(outputDirectory, provisioningConfigFile.getOutputFile())) .assemble(); } }
private void processFeaturePackModules( FeaturePack featurePack, List<FeaturePack.Module> includedModules, ServerProvisioning serverProvisioning, File outputDirectory, Set<String> filesProcessed, ArtifactFileResolver artifactFileResolver, File schemaOutputDirectory) throws IOException { final boolean thinServer = !serverProvisioning.getDescription().isCopyModuleArtifacts(); // create the module's artifact property replacer final BuildPropertyReplacer buildPropertyReplacer = thinServer ? new BuildPropertyReplacer( new ModuleArtifactPropertyResolver(featurePack.getArtifactResolver())) : null; // process each module file try (JarFile jar = new JarFile(featurePack.getFeaturePackFile())) { for (FeaturePack.Module module : includedModules) { // process the module file final String jarEntryName = module.getModuleFile(); filesProcessed.add(jarEntryName); File targetFile = new File(outputDirectory, jarEntryName); // ensure parent dirs exist targetFile.getParentFile().mkdirs(); // extract the module file FileUtils.extractFile(jar, jarEntryName, targetFile); // read module xml to string for content update String moduleXmlContents = FileUtils.readFile(targetFile); // parse the module xml ModuleParseResult result = module.getModuleParseResult(); // process module artifacts for (ModuleParseResult.ArtifactName artifactName : result.getArtifacts()) { String artifactCoords = artifactName.getArtifactCoords(); String options = artifactName.getOptions(); boolean jandex = false; if (options != null) { jandex = options.contains( "jandex"); // todo: eventually we may need options to have a proper query string // type syntax moduleXmlContents = moduleXmlContents.replace( artifactName.toString(), artifactCoords); // todo: all these replace calls are a bit yuck, we may need // proper solution if this gets more complex } Artifact artifact = featurePack.getArtifactResolver().getArtifact(artifactCoords); if (artifact == null) { throw new RuntimeException( "Could not resolve module resource artifact " + artifactName + " for feature pack " + featurePack.getFeaturePackFile()); } try { // process the module artifact File artifactFile = artifactFileResolver.getArtifactFile(artifact); // extract schemas if needed extractSchema(schemaOutputDirectory, artifact, artifactFile); if (jandex) { String baseName = artifactFile.getName().substring(0, artifactFile.getName().lastIndexOf(".")); String extension = artifactFile.getName().substring(artifactFile.getName().lastIndexOf(".")); File target = new File(targetFile.getParent(), baseName + "-jandex" + extension); JandexIndexer.createIndex(artifactFile, new FileOutputStream(target)); moduleXmlContents = moduleXmlContents.replaceAll( "(\\s*)<artifact\\s+name=\"\\$\\{" + artifactCoords + "\\}\"\\s*/>", "$1<artifact name=\"\\${" + artifactCoords + "}\" />$1<resource-root path=\"" + target.getName() + "\"/>"); // it's also possible that this is an element with nested content // this regex involves a good deal of backtracking but it seems to work moduleXmlContents = Pattern.compile( "(\\s*)<artifact\\s+name=\"\\$\\{" + artifactCoords + "\\}\"\\s*>(.*)</artifact>", Pattern.DOTALL) .matcher(moduleXmlContents) .replaceAll( "$1<artifact name=\"\\${" + artifactCoords + "}\">$2</artifact>$1<resource-root path=\"" + target.getName() + "\">$2</resource-root>"); } if (!thinServer) { // copy the artifact String artifactFileName = artifactFile.getName(); FileUtils.copyFile(artifactFile, new File(targetFile.getParent(), artifactFileName)); // update module xml content moduleXmlContents = moduleXmlContents.replaceAll( "<artifact\\s+name=\"\\$\\{" + artifactCoords + "\\}\"\\s*/>", "<resource-root path=\"" + artifactFileName + "\"/>"); // it's also possible that this is an element with nested content // this regex involves a good deal of backtracking but it seems to work moduleXmlContents = Pattern.compile( "<artifact\\s+name=\"\\$\\{" + artifactCoords + "\\}\"\\s*>(.*)</artifact>", Pattern.DOTALL) .matcher(moduleXmlContents) .replaceAll( "<resource-root path=\"" + artifactFileName + "\">$1</resource-root>"); } } catch (Throwable t) { throw new RuntimeException("Could not extract resources from " + artifactName, t); } } if (thinServer) { // replace artifact coords properties with the ones expected by jboss-modules moduleXmlContents = buildPropertyReplacer.replaceProperties(moduleXmlContents); } // write updated module xml content FileUtils.copyFile( new ByteArrayInputStream(moduleXmlContents.getBytes("UTF-8")), targetFile); // extract all other files in the module dir for (String moduleDirFile : module.getModuleDirFiles()) { filesProcessed.add(moduleDirFile); FileUtils.extractFile(jar, moduleDirFile, new File(outputDirectory, moduleDirFile)); } } } catch (Throwable e) { throw new RuntimeException( "Failed to process feature pack " + featurePack.getFeaturePackFile() + " modules", e); } }
private void processModules( ServerProvisioning serverProvisioning, File outputDirectory, Set<String> filesProcessed, ArtifactFileResolver artifactFileResolver, File schemaOutputDirectory) throws IOException, XMLStreamException { // 1. gather the modules for each feature pack final Map<FeaturePack, List<FeaturePack.Module>> featurePackModulesMap = new HashMap<>(); Set<ModuleIdentifier> moduleIdentifiers = new HashSet<>(); for (ServerProvisioningFeaturePack provisioningFeaturePack : serverProvisioning.getFeaturePacks()) { getLog() .debugf( "Gathering modules for provisioning feature pack %s", provisioningFeaturePack.getFeaturePack().getFeaturePackFile()); for (FeaturePack.Module module : provisioningFeaturePack .getModules( artifactFileResolver, serverProvisioning.getDescription().isExcludeDependencies()) .values()) { final ModuleIdentifier moduleIdentifier = module.getIdentifier(); if (moduleIdentifiers.add(moduleIdentifier)) { getLog() .debugf( "Adding module %s from feature pack %s", moduleIdentifier, module.getFeaturePack().getFeaturePackFile()); List<FeaturePack.Module> featurePackModules = featurePackModulesMap.get(module.getFeaturePack()); if (featurePackModules == null) { featurePackModules = new ArrayList<>(); featurePackModulesMap.put(module.getFeaturePack(), featurePackModules); } featurePackModules.add(module); } else { getLog() .debugf( "Skipping %s from feature pack %s. A module with such identifier is already in the provisioning module set.", moduleIdentifier, module.getFeaturePack().getFeaturePackFile()); } } // we always need to resolve all subsystem templates, regardless of the value of // exclude-dependencies for (FeaturePack.Module module : provisioningFeaturePack.getModules(artifactFileResolver, false).values()) { for (ModuleParseResult.ArtifactName artifactName : module.getModuleParseResult().getArtifacts()) { String artifactCoords = artifactName.getArtifactCoords(); String options = artifactName.getOptions(); Artifact artifact = module.getFeaturePack().getArtifactResolver().getArtifact(artifactCoords); if (artifact == null) { throw new RuntimeException( "Could not resolve module resource artifact " + artifactName + " for feature pack " + module.getFeaturePack().getFeaturePackFile()); } File artifactFile = artifactFileResolver.getArtifactFile(artifact); // add all subsystem templates serverProvisioning .getConfig() .getInputStreamSources() .addAllSubsystemFileSourcesFromZipFile(artifactFile); } } } // 2. provision each feature pack modules for (Map.Entry<FeaturePack, List<FeaturePack.Module>> mapEntry : featurePackModulesMap.entrySet()) { FeaturePack featurePack = mapEntry.getKey(); List<FeaturePack.Module> includedModules = mapEntry.getValue(); processFeaturePackModules( featurePack, includedModules, serverProvisioning, outputDirectory, filesProcessed, artifactFileResolver, schemaOutputDirectory); } }