io.radanalytics.operator.resource.HasDataHelper Maven / Gradle / Ivy
/*
* Copyright 2018
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html).
*/
package io.radanalytics.operator.resource;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.radanalytics.operator.common.EntityInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.error.YAMLException;
/**
* A helper for parsing the data section inside the K8s resource (ConfigMap).
* Type parameter T represents the concrete EntityInfo that captures the configuration obout the
* objects in the clusters we are interested in, be it spark clusters, http servers, certificates, etc.
*
* One can create arbitrarily deep configurations by nesting the types in Class<T>
and using
* the Snake yaml or other library as for conversions between YAML and Java objects.
*/
public class HasDataHelper {
private static final Logger log = LoggerFactory.getLogger(HasDataHelper.class.getName());
public static T parseYaml(Class clazz, String yamlDoc, String name) {
LoaderOptions options = new LoaderOptions();
Yaml snake = new Yaml(new Constructor(clazz));
T entity = null;
try {
entity = snake.load(yamlDoc);
} catch (YAMLException ex) {
String msg = "Unable to parse yaml definition of configmap, check if you don't have typo: \n'\n" +
yamlDoc + "\n'\n";
log.error(msg);
throw new IllegalStateException(ex);
}
if (entity == null) {
String msg = "Unable to parse yaml definition of configmap, check if you don't have typo: \n'\n" +
yamlDoc + "\n'\n";
log.error(msg);
try {
entity = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (entity != null && entity.getName() == null) {
entity.setName(name);
}
return entity;
}
/**
*
* @param clazz concrete class of type T that extends the EntityInfo.
* This is the resulting type, we are convertion into.
* @param cm input config map that will be converted into T.
* We assume there is a multi-line section in the config map called config and it
* contains a YAML structure that represents the object of type T. In other words the
* keys in the yaml should be the same as the field names in the class T and the name of the
* configmap will be assigned to the name of the object T. One can create arbitrarily deep
* configuration by nesting the types in T and using the Snake yaml as the conversion library.
* @param type parameter (T must extend {@link io.radanalytics.operator.common.EntityInfo})
* @return Java object of type T
*/
public static T parseCM(Class clazz, ConfigMap cm) {
String yaml = cm.getData().get("config");
T entity = parseYaml(clazz, yaml, cm.getMetadata().getName());
return entity;
}
}