mirror of https://github.com/halo-dev/halo
feat: add yaml unstructured loader (#2122)
parent
3c856d04af
commit
9a05942bc4
|
@ -212,7 +212,7 @@ public class WebSecurityConfig {
|
||||||
// It'll be deleted next time
|
// It'll be deleted next time
|
||||||
UserDetails user = User.withUsername("user")
|
UserDetails user = User.withUsername("user")
|
||||||
.password(passwordEncoder().encode("123456"))
|
.password(passwordEncoder().encode("123456"))
|
||||||
.authorities("readPostRole")
|
.authorities("role-template-view-posts", "role-template-manage-posts")
|
||||||
.build();
|
.build();
|
||||||
return new InMemoryUserDetailsManager(user);
|
return new InMemoryUserDetailsManager(user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,29 @@
|
||||||
package run.halo.app.infra;
|
package run.halo.app.infra;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import run.halo.app.extension.ExtensionClient;
|
import run.halo.app.extension.ExtensionClient;
|
||||||
import run.halo.app.extension.Metadata;
|
|
||||||
import run.halo.app.extension.Schemes;
|
import run.halo.app.extension.Schemes;
|
||||||
|
import run.halo.app.extension.Unstructured;
|
||||||
import run.halo.app.identity.apitoken.PersonalAccessToken;
|
import run.halo.app.identity.apitoken.PersonalAccessToken;
|
||||||
import run.halo.app.identity.apitoken.PersonalAccessTokenType;
|
import run.halo.app.identity.apitoken.PersonalAccessTokenType;
|
||||||
import run.halo.app.identity.apitoken.PersonalAccessTokenUtils;
|
import run.halo.app.identity.apitoken.PersonalAccessTokenUtils;
|
||||||
import run.halo.app.identity.authentication.OAuth2Authorization;
|
import run.halo.app.identity.authentication.OAuth2Authorization;
|
||||||
import run.halo.app.identity.authentication.OAuth2AuthorizationService;
|
import run.halo.app.identity.authentication.OAuth2AuthorizationService;
|
||||||
import run.halo.app.identity.authorization.PolicyRule;
|
|
||||||
import run.halo.app.identity.authorization.Role;
|
import run.halo.app.identity.authorization.Role;
|
||||||
import run.halo.app.infra.utils.HaloUtils;
|
import run.halo.app.infra.utils.HaloUtils;
|
||||||
|
import run.halo.app.infra.utils.YamlUnstructuredLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author guqing
|
* @author guqing
|
||||||
|
@ -42,30 +46,12 @@ public class SchemeInitializer implements ApplicationListener<ApplicationStarted
|
||||||
public void onApplicationEvent(ApplicationStartedEvent event) {
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
Schemes.INSTANCE.register(Role.class);
|
Schemes.INSTANCE.register(Role.class);
|
||||||
|
|
||||||
|
// TODO The read location of the configuration file needs to be considered later
|
||||||
|
createUnstructured();
|
||||||
|
|
||||||
// TODO These test only methods will be removed in the future
|
// TODO These test only methods will be removed in the future
|
||||||
initRoleForTesting();
|
|
||||||
initPersonalAccessTokenForTesting();
|
initPersonalAccessTokenForTesting();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void initRoleForTesting() {
|
|
||||||
Role role = new Role();
|
|
||||||
role.setApiVersion("v1alpha1");
|
|
||||||
role.setKind("Role");
|
|
||||||
Metadata metadata = new Metadata();
|
|
||||||
metadata.setName("readPostRole");
|
|
||||||
role.setMetadata(metadata);
|
|
||||||
List<PolicyRule> rules = List.of(
|
|
||||||
new PolicyRule.Builder().apiGroups("").resources("posts").verbs("list", "get")
|
|
||||||
.build(),
|
|
||||||
new PolicyRule.Builder().apiGroups("").resources("categories").verbs("*")
|
|
||||||
.build(),
|
|
||||||
new PolicyRule.Builder().nonResourceURLs("/healthy").verbs("get", "post", "head")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
role.setRules(rules);
|
|
||||||
|
|
||||||
extensionClient.create(role);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPersonalAccessTokenForTesting() {
|
private void initPersonalAccessTokenForTesting() {
|
||||||
|
@ -74,7 +60,8 @@ public class SchemeInitializer implements ApplicationListener<ApplicationStarted
|
||||||
String tokenValue =
|
String tokenValue =
|
||||||
PersonalAccessTokenUtils.generate(PersonalAccessTokenType.ADMIN_TOKEN, secretKey);
|
PersonalAccessTokenUtils.generate(PersonalAccessTokenType.ADMIN_TOKEN, secretKey);
|
||||||
|
|
||||||
Set<String> roles = Set.of("readPostRole");
|
Set<String> roles =
|
||||||
|
Set.of("role-template-view-categories", "role-template-view-nonresources");
|
||||||
OAuth2AccessToken personalAccessToken =
|
OAuth2AccessToken personalAccessToken =
|
||||||
new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, tokenValue, Instant.now(),
|
new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, tokenValue, Instant.now(),
|
||||||
Instant.now().plus(2, ChronoUnit.HOURS), roles);
|
Instant.now().plus(2, ChronoUnit.HOURS), roles);
|
||||||
|
@ -91,4 +78,29 @@ public class SchemeInitializer implements ApplicationListener<ApplicationStarted
|
||||||
.build();
|
.build();
|
||||||
oauth2AuthorizationService.save(authorization);
|
oauth2AuthorizationService.save(authorization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createUnstructured() {
|
||||||
|
try {
|
||||||
|
List<Unstructured> unstructuredList = loadClassPathResourcesToUnstructured();
|
||||||
|
for (Unstructured unstructured : unstructuredList) {
|
||||||
|
extensionClient.create(unstructured);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Unstructured> loadClassPathResourcesToUnstructured() throws IOException {
|
||||||
|
PathMatchingResourcePatternResolver resourcePatternResolver =
|
||||||
|
new PathMatchingResourcePatternResolver();
|
||||||
|
// Gets yaml resources
|
||||||
|
Resource[] yamlResources =
|
||||||
|
resourcePatternResolver.getResources("classpath*:extensions/*.yaml");
|
||||||
|
Resource[] ymlResources =
|
||||||
|
resourcePatternResolver.getResources("classpath*:extensions/*.yml");
|
||||||
|
|
||||||
|
YamlUnstructuredLoader yamlUnstructuredLoader =
|
||||||
|
new YamlUnstructuredLoader(ArrayUtils.addAll(ymlResources, yamlResources));
|
||||||
|
return yamlUnstructuredLoader.load();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
package run.halo.app.infra.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Json utilities.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @see JavaTimeModule
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public class JsonUtils {
|
||||||
|
public static final ObjectMapper DEFAULT_JSON_MAPPER = createDefaultJsonMapper();
|
||||||
|
|
||||||
|
private JsonUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default json mapper.
|
||||||
|
*
|
||||||
|
* @return object mapper
|
||||||
|
*/
|
||||||
|
public static ObjectMapper createDefaultJsonMapper() {
|
||||||
|
return createDefaultJsonMapper(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default json mapper.
|
||||||
|
*
|
||||||
|
* @param strategy property naming strategy
|
||||||
|
* @return object mapper
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static ObjectMapper createDefaultJsonMapper(@Nullable PropertyNamingStrategy strategy) {
|
||||||
|
// Create object mapper
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
// Configure
|
||||||
|
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
mapper.registerModule(new JavaTimeModule());
|
||||||
|
// Set property naming strategy
|
||||||
|
if (strategy != null) {
|
||||||
|
mapper.setPropertyNamingStrategy(strategy);
|
||||||
|
}
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a map to the object specified type.
|
||||||
|
*
|
||||||
|
* @param sourceMap source map must not be empty
|
||||||
|
* @param type object type must not be null
|
||||||
|
* @param <T> target object type
|
||||||
|
* @return the object specified type
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static <T> T mapToObject(@NonNull Map<String, ?> sourceMap, @NonNull Class<T> type) {
|
||||||
|
return DEFAULT_JSON_MAPPER.convertValue(sourceMap, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts object to json format.
|
||||||
|
*
|
||||||
|
* @param source source object must not be null
|
||||||
|
* @return json format of the source object
|
||||||
|
* @throws JsonProcessingException throws when fail to convert
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static String objectToJson(@NonNull Object source)
|
||||||
|
throws JsonProcessingException {
|
||||||
|
Assert.notNull(source, "Source object must not be null");
|
||||||
|
|
||||||
|
return DEFAULT_JSON_MAPPER.writeValueAsString(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to deserialize JSON content from given JSON content String.
|
||||||
|
*
|
||||||
|
* @param json json content
|
||||||
|
* @param toValueType object type to convert
|
||||||
|
* @param <T> real type to convert
|
||||||
|
* @return converted object
|
||||||
|
*/
|
||||||
|
public static <T> T jsonToObject(String json, Class<T> toValueType) {
|
||||||
|
try {
|
||||||
|
return DEFAULT_JSON_MAPPER.readValue(json, toValueType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package run.halo.app.infra.utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.beans.factory.config.YamlProcessor;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import run.halo.app.extension.Unstructured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Process the content in yaml that matches the {@link DocumentMatcher} and convert it to an
|
||||||
|
* unstructured list.</p>
|
||||||
|
* <p>Multiple resources can be processed at one time.</p>
|
||||||
|
* <p>The following specified key must be included before the resource can be processed:
|
||||||
|
* <pre>
|
||||||
|
* apiVersion
|
||||||
|
* kind
|
||||||
|
* metadata.name
|
||||||
|
* </pre>
|
||||||
|
* Otherwise, skip it and continue to read the next resource.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public class YamlUnstructuredLoader extends YamlProcessor {
|
||||||
|
|
||||||
|
private static final DocumentMatcher DEFAULT_UNSTRUCTURED_MATCHER = properties -> {
|
||||||
|
if (properties.containsKey("apiVersion")
|
||||||
|
&& properties.containsKey("kind")
|
||||||
|
&& properties.containsKey("metadata.name")) {
|
||||||
|
return YamlProcessor.MatchStatus.FOUND;
|
||||||
|
}
|
||||||
|
return MatchStatus.NOT_FOUND;
|
||||||
|
};
|
||||||
|
|
||||||
|
public YamlUnstructuredLoader(Resource... resources) {
|
||||||
|
setResources(resources);
|
||||||
|
setDocumentMatchers(DEFAULT_UNSTRUCTURED_MATCHER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Unstructured> load() {
|
||||||
|
List<Unstructured> unstructuredList = new ArrayList<>();
|
||||||
|
process((properties, map) -> {
|
||||||
|
Unstructured unstructured = JsonUtils.mapToObject(map, Unstructured.class);
|
||||||
|
unstructuredList.add(unstructured);
|
||||||
|
});
|
||||||
|
return unstructuredList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: role-template-view-categories
|
||||||
|
labels:
|
||||||
|
halo.run/role-template: "true"
|
||||||
|
annotations:
|
||||||
|
halo.run/module: "Categories Management"
|
||||||
|
halo.run/alias-name: "Categories View"
|
||||||
|
rules:
|
||||||
|
- apiGroups: [ "" ]
|
||||||
|
resources: [ "categories" ]
|
||||||
|
verbs: [ "get", "list" ]
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: role-template-manage-categories
|
||||||
|
labels:
|
||||||
|
halo.run/role-template: "true"
|
||||||
|
annotations:
|
||||||
|
halo.run/dependencies: '[ "role-template-view-categories" ]'
|
||||||
|
halo.run/module: "Categories Management"
|
||||||
|
halo.run/alias-name: "Categories Management"
|
||||||
|
rules:
|
||||||
|
- apiGroups: [ "" ]
|
||||||
|
resources: [ "categories" ]
|
||||||
|
verbs: [ "create", "delete", "deletecollection", "patch", "update" ]
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: role-template-view-posts
|
||||||
|
labels:
|
||||||
|
halo.run/role-template: "true"
|
||||||
|
annotations:
|
||||||
|
halo.run/module: "Posts Management"
|
||||||
|
halo.run/alias-name: "Posts View"
|
||||||
|
rules:
|
||||||
|
- apiGroups: [ "" ]
|
||||||
|
resources: [ "posts", "categories", "tags" ]
|
||||||
|
verbs: [ "get", "list" ]
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: role-template-manage-posts
|
||||||
|
labels:
|
||||||
|
halo.run/role-template: "true"
|
||||||
|
annotations:
|
||||||
|
halo.run/module: "Posts Management"
|
||||||
|
halo.run/alias-name: "Posts Management"
|
||||||
|
rules:
|
||||||
|
- apiGroups: [ "" ]
|
||||||
|
resources: [ "posts", "categories", "tags" ]
|
||||||
|
verbs: [ "create", "delete", "deletecollection", "patch", "update" ]
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: role-template-view-nonresources
|
||||||
|
labels:
|
||||||
|
halo.run/role-template: "true"
|
||||||
|
annotations:
|
||||||
|
halo.run/module: "Other"
|
||||||
|
halo.run/alias-name: "Non Resources View"
|
||||||
|
rules:
|
||||||
|
- nonResourceURLs: ["/healthy", "/static/*"]
|
||||||
|
verbs: ["get", "post"]
|
|
@ -0,0 +1,36 @@
|
||||||
|
package run.halo.app.infra.utils;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link JsonUtils}.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public class JsonUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializerTime() throws JsonProcessingException {
|
||||||
|
Instant now = Instant.now();
|
||||||
|
String instantStr = JsonUtils.objectToJson(now);
|
||||||
|
assertThat(instantStr).isNotNull();
|
||||||
|
|
||||||
|
String localDateTimeStr = JsonUtils.objectToJson(LocalDateTime.now());
|
||||||
|
assertThat(localDateTimeStr).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void deserializerArrayString() {
|
||||||
|
String s = "[\"hello\", \"world\"]";
|
||||||
|
List list = JsonUtils.jsonToObject(s, List.class);
|
||||||
|
assertThat(list).isEqualTo(List.of("hello", "world"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package run.halo.app.infra.utils;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.security.util.InMemoryResource;
|
||||||
|
import run.halo.app.extension.Unstructured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link YamlUnstructuredLoader}.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
class YamlUnstructuredLoaderTest {
|
||||||
|
|
||||||
|
private List<InMemoryResource> yamlResources;
|
||||||
|
private String notSpecYaml;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
String viewCategoriesRoleYaml = """
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Fake
|
||||||
|
metadata:
|
||||||
|
name: test1
|
||||||
|
hello:
|
||||||
|
world: halo
|
||||||
|
""";
|
||||||
|
|
||||||
|
String multipleRoleYaml = """
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Fake
|
||||||
|
metadata:
|
||||||
|
name: test2
|
||||||
|
hello:
|
||||||
|
world: haha
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: Fake
|
||||||
|
metadata:
|
||||||
|
name: test2
|
||||||
|
hello:
|
||||||
|
world: bang
|
||||||
|
""";
|
||||||
|
|
||||||
|
notSpecYaml = """
|
||||||
|
server:
|
||||||
|
port: 8090
|
||||||
|
spring:
|
||||||
|
jackson:
|
||||||
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
|
""";
|
||||||
|
|
||||||
|
yamlResources = Stream.of(viewCategoriesRoleYaml, multipleRoleYaml, notSpecYaml)
|
||||||
|
.map(InMemoryResource::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadTest() throws JsonProcessingException {
|
||||||
|
Resource[] resources = yamlResources.toArray(Resource[]::new);
|
||||||
|
YamlUnstructuredLoader yamlUnstructuredLoader = new YamlUnstructuredLoader(resources);
|
||||||
|
List<Unstructured> unstructuredList = yamlUnstructuredLoader.load();
|
||||||
|
assertThat(unstructuredList).isNotNull();
|
||||||
|
assertThat(unstructuredList).hasSize(3);
|
||||||
|
|
||||||
|
assertThat(JsonUtils.objectToJson(unstructuredList)).isEqualToIgnoringWhitespace("""
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"apiVersion": "v1alpha1",
|
||||||
|
"kind": "Fake",
|
||||||
|
"metadata": {
|
||||||
|
"name": "test1"
|
||||||
|
},
|
||||||
|
"hello": {
|
||||||
|
"world": "halo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"apiVersion": "v1alpha1",
|
||||||
|
"kind": "Fake",
|
||||||
|
"metadata": {
|
||||||
|
"name": "test2"
|
||||||
|
},
|
||||||
|
"hello": {
|
||||||
|
"world": "haha"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"apiVersion": "v1alpha1",
|
||||||
|
"kind": "Fake",
|
||||||
|
"metadata": {
|
||||||
|
"name": "test2"
|
||||||
|
},
|
||||||
|
"hello": {
|
||||||
|
"world": "bang"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void loadIgnore() {
|
||||||
|
InMemoryResource resource = new InMemoryResource(notSpecYaml);
|
||||||
|
YamlUnstructuredLoader yamlUnstructuredLoader = new YamlUnstructuredLoader(resource);
|
||||||
|
List<Unstructured> unstructuredList = yamlUnstructuredLoader.load();
|
||||||
|
assertThat(unstructuredList).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue