Skip to content

Commit

Permalink
feat(SpelHelpers): Support parsing multi-document yaml strings (#3973)
Browse files Browse the repository at this point in the history
* feat(SpelHelpers): Support parsing multi-document yaml strings

* Amend review sugestions

* Fix naming
  • Loading branch information
amanya committed Oct 22, 2020
1 parent 198c99a commit a3d5193
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -80,7 +77,11 @@ public Functions getFunctions() {
new FunctionParameter(String.class, "value", "A String containing JSON text")),
new FunctionDefinition(
"readYaml",
"Parses YAML from a string to be accessed, parsed JSON can be accessed as an object",
"Parses YAML from a string to be accessed, parsed YAML can be accessed as an object",
new FunctionParameter(String.class, "value", "A String containing YAML text")),
new FunctionDefinition(
"readAllYaml",
"Parses multi-doc YAML from a string to be accessed, list of parsed YAML can be accessed as objects",
new FunctionParameter(String.class, "value", "A String containing YAML text")));
}

Expand Down Expand Up @@ -136,6 +137,26 @@ public static Object readYaml(String text) {
}
}

/**
* Attempts to read a multi-doc yaml from a text String. Will throw a parsing exception on bad
* yaml
*
* @param text text to read as yaml
* @return a list of the object representations of the yaml text
*/
public static Object readAllYaml(String text) {
try {
List<Object> yamlDocs = new ArrayList<>();
Iterable<Object> iterable = new Yaml().loadAll(text);
for (Object o : iterable) {
yamlDocs.add(o);
}
return yamlDocs;
} catch (Exception e) {
throw new SpelHelperFunctionException(format("#readAllYaml(%s) failed", text), e);
}
}

/**
* Reads a properties file stored at a url
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2020 Adevinta, Inc.
*
* Licensed 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 com.netflix.spinnaker.orca.pipeline.expressions.functions

import com.netflix.spinnaker.kork.expressions.SpelHelperFunctionException
import spock.lang.Specification
import spock.lang.Unroll

class UrlExpressionFunctionProviderSpec extends Specification {

@Unroll
def "test readYaml"() {
expect:
UrlExpressionFunctionProvider.readYaml(currentYaml) == expectedYaml

where:
currentYaml || expectedYaml
"a: 1\nb: 2\n" || [a: 1, b: 2]
"---\na: 1\nb: 2\n" || [a: 1, b: 2]
}

def "readYaml returns exception on multi-doc YAML"() {
when:
UrlExpressionFunctionProvider.readYaml("a: 1\nb: 2\n---\nc: 3\n")

then:
thrown(SpelHelperFunctionException)
}

@Unroll
def "test readAllYaml"() {
expect:
UrlExpressionFunctionProvider.readAllYaml(currentYaml) == expectedYaml

where:
currentYaml || expectedYaml
"a: 1\nb: 2\n" || [[a: 1, b: 2]]
"---\na: 1\nb: 2\n" || [[a: 1, b: 2]]
"a: 1\nb: 2\n---\nc: 3\n" || [[a: 1, b: 2],[c: 3]]
}
}

0 comments on commit a3d5193

Please sign in to comment.