Search in sources :

Example 1 with ConfiguratorException

use of io.jenkins.plugins.casc.ConfiguratorException in project configuration-as-code-plugin by jenkinsci.

the class ErrorOnConflictMergeStrategy method merge.

@Override
public void merge(Node root, Node node, String source) throws ConfiguratorException {
    if (root.getNodeId() != node.getNodeId()) {
        // means one of those yaml file doesn't conform to JCasC schema
        throw new ConfiguratorException(String.format("Found incompatible configuration elements %s %s", source, node.getStartMark()));
    }
    switch(root.getNodeId()) {
        case sequence:
            SequenceNode seq = (SequenceNode) root;
            SequenceNode seq2 = (SequenceNode) node;
            seq.getValue().addAll(seq2.getValue());
            return;
        case mapping:
            MappingNode map = (MappingNode) root;
            MappingNode map2 = (MappingNode) node;
            // merge common entries
            final Iterator<NodeTuple> it = map2.getValue().iterator();
            while (it.hasNext()) {
                NodeTuple t2 = it.next();
                for (NodeTuple tuple : map.getValue()) {
                    final Node key = tuple.getKeyNode();
                    final Node key2 = t2.getKeyNode();
                    if (key.getNodeId() == NodeId.scalar) {
                        // We don't support merge for more complex cases (yet)
                        if (((ScalarNode) key).getValue().equals(((ScalarNode) key2).getValue())) {
                            merge(tuple.getValueNode(), t2.getValueNode(), source);
                            it.remove();
                        }
                    } else {
                        throw new ConfiguratorException(String.format("Found non-mergeable configuration keys %s %s)", source, node.getEndMark()));
                    }
                }
            }
            // .. and add others
            map.getValue().addAll(map2.getValue());
            return;
        default:
            new OverrideMergeStrategy().merge(root, node, source);
    }
}
Also used : MappingNode(org.yaml.snakeyaml.nodes.MappingNode) Node(org.yaml.snakeyaml.nodes.Node) SequenceNode(org.yaml.snakeyaml.nodes.SequenceNode) ScalarNode(org.yaml.snakeyaml.nodes.ScalarNode) MappingNode(org.yaml.snakeyaml.nodes.MappingNode) ConfiguratorException(io.jenkins.plugins.casc.ConfiguratorException) NodeTuple(org.yaml.snakeyaml.nodes.NodeTuple) SequenceNode(org.yaml.snakeyaml.nodes.SequenceNode)

Example 2 with ConfiguratorException

use of io.jenkins.plugins.casc.ConfiguratorException in project configuration-as-code-plugin by jenkinsci.

the class DataBoundConfiguratorTest method packageParametersAreNonnullByDefault.

@Test
public void packageParametersAreNonnullByDefault() {
    Mapping config = new Mapping();
    ConfiguratorRegistry registry = ConfiguratorRegistry.get();
    String expectedMessage = "string is required to configure class io.jenkins.plugins.casc.impl.configurators.nonnull.nonnullparampackage.PackageParametersAreNonnullByDefault";
    ConfiguratorException exception = assertThrows(ConfiguratorException.class, () -> registry.lookupOrFail(PackageParametersAreNonnullByDefault.class).configure(config, new ConfigurationContext(registry)));
    assertThat(exception.getMessage(), is(expectedMessage));
}
Also used : ConfiguratorRegistry(io.jenkins.plugins.casc.ConfiguratorRegistry) ConfigurationContext(io.jenkins.plugins.casc.ConfigurationContext) Mapping(io.jenkins.plugins.casc.model.Mapping) ConfiguratorException(io.jenkins.plugins.casc.ConfiguratorException) Test(org.junit.Test)

Example 3 with ConfiguratorException

use of io.jenkins.plugins.casc.ConfiguratorException in project configuration-as-code-plugin by jenkinsci.

the class DataBoundConfigurator method tryConstructor.

private T tryConstructor(Constructor<T> constructor, Mapping config, ConfigurationContext context) throws ConfiguratorException {
    final Parameter[] parameters = constructor.getParameters();
    final String[] names = ClassDescriptor.loadParameterNames(constructor);
    Object[] args = new Object[names.length];
    if (parameters.length > 0) {
        for (int i = 0; i < names.length; i++) {
            final CNode value = config.get(names[i]);
            final Class t = parameters[i].getType();
            Class<?> clazz = constructor.getDeclaringClass();
            if (value == null && (parameters[i].isAnnotationPresent(Nonnull.class) || constructor.isAnnotationPresent(ParametersAreNonnullByDefault.class) || clazz.isAnnotationPresent(ParametersAreNonnullByDefault.class) || clazz.getPackage().isAnnotationPresent(ParametersAreNonnullByDefault.class) && !parameters[i].isAnnotationPresent(CheckForNull.class))) {
                if (Set.class.isAssignableFrom(t)) {
                    LOGGER.log(Level.FINER, "The parameter to be set is @Nonnull but is not present; " + "setting equal to empty set.");
                    args[i] = Collections.emptySet();
                } else if (List.class.isAssignableFrom(t)) {
                    LOGGER.log(Level.FINER, "The parameter to be set is @Nonnull but is not present; " + "setting equal to empty list.");
                    args[i] = Collections.emptyList();
                } else {
                    throw new ConfiguratorException(names[i] + " is required to configure " + target);
                }
                continue;
            }
            if (value != null) {
                if (Collection.class.isAssignableFrom(t)) {
                    final Type pt = parameters[i].getParameterizedType();
                    final Configurator lookup = context.lookupOrFail(pt);
                    final Collection<Object> collection;
                    if (Set.class.isAssignableFrom(t)) {
                        collection = new HashSet<>();
                    } else {
                        collection = new ArrayList<>();
                    }
                    for (CNode o : value.asSequence()) {
                        collection.add(lookup.configure(o, context));
                    }
                    args[i] = collection;
                } else {
                    final Type pt = parameters[i].getParameterizedType();
                    final Type k = pt != null ? pt : t;
                    final Configurator configurator = context.lookupOrFail(k);
                    args[i] = configurator.configure(value, context);
                }
                if (LOGGER.isLoggable(Level.FINE)) {
                    LOGGER.log(Level.FINE, "Setting {0}.{1} = {2}", new Object[] { target, names[i], t == Secret.class || Attribute.calculateIfSecret(target, names[i]) ? "****" : value });
                }
            } else if (t.isPrimitive()) {
                args[i] = defaultPrimitiveValue(t);
            }
        }
    }
    final T object;
    try {
        object = constructor.newInstance(args);
    } catch (IllegalArgumentException | InstantiationException | InvocationTargetException | IllegalAccessException ex) {
        List<String> argumentTypes = new ArrayList<>(args.length);
        for (Object arg : args) {
            argumentTypes.add(arg != null ? arg.getClass().getName() : "null");
        }
        List<String> parameterTypes = new ArrayList<>(parameters.length);
        for (Parameter parameter : parameters) {
            parameterTypes.add(parameter.getParameterizedType().getTypeName());
        }
        List<String> expectedParamList = new ArrayList<>(parameters.length);
        for (int i = 0; i < parameters.length; i++) {
            expectedParamList.add(names[i] + " " + parameterTypes.get(i));
        }
        throw new ConfiguratorException(this, "Failed to construct instance of " + target + ".\n Constructor: " + constructor + ".\n Arguments: " + argumentTypes + ".\n Expected Parameters: " + String.join(", ", expectedParamList), ex);
    }
    // constructor was successful, so let's removed configuration elements we have consumed doing so.
    for (String name : names) {
        config.remove(name);
    }
    return object;
}
Also used : BaseConfigurator(io.jenkins.plugins.casc.BaseConfigurator) Configurator(io.jenkins.plugins.casc.Configurator) ParametersAreNonnullByDefault(javax.annotation.ParametersAreNonnullByDefault) ConfiguratorException(io.jenkins.plugins.casc.ConfiguratorException) CheckForNull(javax.annotation.CheckForNull) ArrayList(java.util.ArrayList) List(java.util.List) Nonnull(javax.annotation.Nonnull) InvocationTargetException(java.lang.reflect.InvocationTargetException) CNode(io.jenkins.plugins.casc.model.CNode) Secret(hudson.util.Secret) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Parameter(java.lang.reflect.Parameter)

Example 4 with ConfiguratorException

use of io.jenkins.plugins.casc.ConfiguratorException in project configuration-as-code-plugin by jenkinsci.

the class ConfigurableConfigurator method check.

@Override
public T check(CNode config, ConfigurationContext context) throws ConfiguratorException {
    try {
        final T instance = target.getDeclaredConstructor().newInstance();
        instance.check(config);
        return instance;
    } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
        throw new ConfiguratorException("Cannot instantiate Configurable " + target + " with default constructor", e);
    }
}
Also used : ConfiguratorException(io.jenkins.plugins.casc.ConfiguratorException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 5 with ConfiguratorException

use of io.jenkins.plugins.casc.ConfiguratorException in project configuration-as-code-plugin by jenkinsci.

the class YamlUtils method merge.

public static Node merge(List<YamlSource> sources, ConfigurationContext context) throws ConfiguratorException {
    Node root = null;
    MergeStrategy mergeStrategy = MergeStrategyFactory.getMergeStrategyOrDefault(context.getMergeStrategy());
    for (YamlSource<?> source : sources) {
        try (Reader reader = reader(source)) {
            final Node node = read(source, reader, context);
            if (root == null) {
                root = node;
            } else {
                if (node != null) {
                    mergeStrategy.merge(root, node, source.toString());
                }
            }
        } catch (IOException io) {
            throw new ConfiguratorException("Failed to read " + source, io);
        }
    }
    return root;
}
Also used : Node(org.yaml.snakeyaml.nodes.Node) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) IOException(java.io.IOException) ConfiguratorException(io.jenkins.plugins.casc.ConfiguratorException)

Aggregations

ConfiguratorException (io.jenkins.plugins.casc.ConfiguratorException)9 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Node (org.yaml.snakeyaml.nodes.Node)3 ConfigurationContext (io.jenkins.plugins.casc.ConfigurationContext)2 ConfiguratorRegistry (io.jenkins.plugins.casc.ConfiguratorRegistry)2 Mapping (io.jenkins.plugins.casc.model.Mapping)2 Test (org.junit.Test)2 MappingNode (org.yaml.snakeyaml.nodes.MappingNode)2 NodeTuple (org.yaml.snakeyaml.nodes.NodeTuple)2 ScalarNode (org.yaml.snakeyaml.nodes.ScalarNode)2 SequenceNode (org.yaml.snakeyaml.nodes.SequenceNode)2 NonNull (edu.umd.cs.findbugs.annotations.NonNull)1 Secret (hudson.util.Secret)1 BaseConfigurator (io.jenkins.plugins.casc.BaseConfigurator)1 Configurator (io.jenkins.plugins.casc.Configurator)1 ConfiguratorConflictException (io.jenkins.plugins.casc.ConfiguratorConflictException)1 CNode (io.jenkins.plugins.casc.model.CNode)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1