io.fabric8.devops.ProjectConfigs Maven / Gradle / Ivy
/**
* Copyright 2005-2015 Red Hat, Inc.
*
* Red Hat licenses this file to you under the Apache License, version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package io.fabric8.devops;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import io.fabric8.utils.Maps;
import io.fabric8.utils.Strings;
import io.fabric8.utils.Systems;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* A helper class for loading and saving the {@link ProjectConfig}
*/
public class ProjectConfigs {
private static final transient Logger LOG = LoggerFactory.getLogger(ProjectConfigs.class);
public static final String FILE_NAME = "fabric8.yml";
public static final String LOCAL_FLOW_FILE_NAME = "Jenkinsfile";
public static String toYaml(Object dto) throws JsonProcessingException {
ObjectMapper mapper = createObjectMapper();
return mapper.writeValueAsString(dto);
}
/**
* Returns the configuration from the {@link #FILE_NAME} in the given folder or returns the default configuration
*/
public static ProjectConfig loadFromFolder(File folder) {
File projectConfigFile = new File(folder, FILE_NAME);
if (projectConfigFile != null && projectConfigFile.exists() && projectConfigFile.isFile()) {
LOG.debug("Parsing fabric8 devops project configuration from: " + projectConfigFile.getName());
try {
return ProjectConfigs.parseProjectConfig(projectConfigFile);
} catch (IOException e) {
LOG.warn("Failed to parse " + projectConfigFile + ". " + e, e);
}
}
return new ProjectConfig();
}
/**
* Tries to find the project configuration from the current directory or a parent folder.
*
* If no fabric8.yml file can be found just return an empty configuration
*/
public static ProjectConfig findFromFolder(File folder) {
if (folder.isDirectory()) {
File projectConfigFile = new File(folder, FILE_NAME);
if (projectConfigFile != null && projectConfigFile.exists() && projectConfigFile.isFile()) {
return loadFromFolder(folder);
}
File parentFile = folder.getParentFile();
if (parentFile != null) {
return findFromFolder(parentFile);
}
}
return new ProjectConfig();
}
/**
* Returns the project config from the given url if it exists or null
*/
public static ProjectConfig loadFromUrl(String url) {
if (Strings.isNotBlank(url)) {
try {
return loadFromUrl(new URL(url));
} catch (MalformedURLException e) {
LOG.warn("Failed to create URL from: " + url + ". " + e, e);
}
}
return null;
}
/**
* Returns the project config from the given url if it exists or null
*/
public static ProjectConfig loadFromUrl(URL url) {
InputStream input = null;
try {
input = url.openStream();
} catch (FileNotFoundException e) {
LOG.info("No fabric8.yml at URL: " + url);
} catch (IOException e) {
LOG.warn("Failed to open fabric8.yml file at URL: " + url + ". " + e, e);
}
if (input != null) {
try {
LOG.info("Parsing " + ProjectConfigs.FILE_NAME + " from " + url);
return ProjectConfigs.parseProjectConfig(input);
} catch (IOException e) {
LOG.warn("Failed to parse " + ProjectConfigs.FILE_NAME + " from " + url + ". " + e, e);
}
}
return null;
}
/**
* Returns true if the given folder has a configuration file called {@link #FILE_NAME}
*/
public static boolean hasConfigFile(File folder) {
File projectConfigFile = new File(folder, FILE_NAME);
return projectConfigFile != null && projectConfigFile.exists() && projectConfigFile.isFile();
}
/**
* Creates a configured Jackson object mapper for parsing YAML
*/
public static ObjectMapper createObjectMapper() {
return new ObjectMapper(new YAMLFactory());
}
public static ProjectConfig parseProjectConfig(File file) throws IOException {
return parseYaml(file, ProjectConfig.class);
}
public static ProjectConfig parseProjectConfig(InputStream input) throws IOException {
return parseYaml(input, ProjectConfig.class);
}
public static ProjectConfig parseProjectConfig(String yaml) throws IOException {
return parseYaml(yaml, ProjectConfig.class);
}
private static T parseYaml(File file, Class clazz) throws IOException {
ObjectMapper mapper = createObjectMapper();
return mapper.readValue(file, clazz);
}
static List parseYamlValues(File file, Class clazz) throws IOException {
ObjectMapper mapper = createObjectMapper();
MappingIterator iter = mapper.readerFor(clazz).readValues(file);
List answer = new ArrayList<>();
while (iter.hasNext()) {
answer.add(iter.next());
}
return answer;
}
private static T parseYaml(InputStream inputStream, Class clazz) throws IOException {
ObjectMapper mapper = createObjectMapper();
return mapper.readValue(inputStream, clazz);
}
private static T parseYaml(String yaml, Class clazz) throws IOException {
ObjectMapper mapper = createObjectMapper();
return mapper.readValue(yaml, clazz);
}
/**
* Saves the fabric8.yml file to the given project directory
*/
public static boolean saveToFolder(File basedir, ProjectConfig config, boolean overwriteIfExists) throws IOException {
File file = new File(basedir, ProjectConfigs.FILE_NAME);
if (file.exists()) {
if (!overwriteIfExists) {
LOG.warn("Not generating " + file + " as it already exists");
return false;
}
}
return saveConfig(config, file);
}
/**
* Saves the configuration as YAML in the given file
*/
public static boolean saveConfig(ProjectConfig config, File file) throws IOException {
createObjectMapper().writeValue(file, config);
return true;
}
/**
* Configures the given {@link ProjectConfig} with a map of key value pairs from
* something like a JBoss Forge command
*/
public static void configureProperties(ProjectConfig config, Map map) {
Class extends ProjectConfig> clazz = config.getClass();
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(clazz);
} catch (IntrospectionException e) {
LOG.warn("Could not introspect " + clazz.getName() + ". " + e, e);
}
if (beanInfo != null) {
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors) {
Method writeMethod = descriptor.getWriteMethod();
if (writeMethod != null) {
String name = descriptor.getName();
Object value = map.get(name);
if (value != null) {
Object safeValue = null;
Class> propertyType = descriptor.getPropertyType();
if (propertyType.isInstance(value)) {
safeValue = value;
} else {
PropertyEditor editor = descriptor.createPropertyEditor(config);
if (editor == null) {
editor = PropertyEditorManager.findEditor(propertyType);
}
if (editor != null) {
String text = value.toString();
editor.setAsText(text);
safeValue = editor.getValue();
} else {
LOG.warn("Cannot update property " + name
+ " with value " + value
+ " of type " + propertyType.getName()
+ " on " + clazz.getName());
}
}
if (safeValue != null) {
try {
writeMethod.invoke(config, safeValue);
} catch (Exception e) {
LOG.warn("Failed to set property " + name
+ " with value " + value
+ " on " + clazz.getName() + " " + config + ". " + e, e);
}
}
}
}
}
}
String flow = null;
Object flowValue = map.get("pipeline");
if (flowValue == null) {
flowValue = map.get("flow");
}
if (flowValue != null) {
flow = flowValue.toString();
}
config.setPipeline(flow);
}
/**
* If no environments have been configured lets default them from the `FABRIC8_DEFAULT_ENVIRONMENTS` environment variable
*/
public static void defaultEnvironments(ProjectConfig config) {
if (config != null) {
String buildName = config.getBuildName();
if (Strings.isNotBlank(buildName) && Maps.isNullOrEmpty(config.getEnvironments())) {
// lets default the environments from env var
String defaultEnvironmentsText = Systems.getEnvVarOrSystemProperty("FABRIC8_DEFAULT_ENVIRONMENTS", "Testing=${buildName}-testing,Staging=${buildName}-staging,Production=${buildName}-prod");
String text = Strings.replaceAllWithoutRegex(defaultEnvironmentsText, "${buildName}", buildName);
LinkedHashMap environments = Maps.parseMap(text);
config.setEnvironments(environments);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy