mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
YAML model repository: supports only version 1 with elements as map (#4807)
* YAML model repository: supports only version 1 with elements as map Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
+49
-175
@@ -29,7 +29,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -61,7 +60,6 @@ import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
@@ -75,7 +73,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
|
||||
*
|
||||
* @author Laurent Garnier - Initial contribution
|
||||
* @author Jan N. Klug - Refactored for multiple types per file and add modifying possibility
|
||||
* @author Laurent Garnier - Introduce version 2 using map instead of table
|
||||
* @author Laurent Garnier - Map used instead of table
|
||||
* @author Laurent Garnier - Added basic version management
|
||||
* @author Laurent Garnier - Added method generateSyntaxFromElements + new parameters
|
||||
* for method isValid
|
||||
@@ -83,7 +81,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true)
|
||||
public class YamlModelRepositoryImpl implements WatchService.WatchEventListener, YamlModelRepository {
|
||||
private static final int DEFAULT_MODEL_VERSION = 2;
|
||||
private static final int DEFAULT_MODEL_VERSION = 1;
|
||||
private static final String VERSION = "version";
|
||||
private static final String READ_ONLY = "readOnly";
|
||||
private static final Set<String> KNOWN_ELEMENTS = Set.of( //
|
||||
@@ -208,27 +206,19 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
newElementNames.add(elementName);
|
||||
JsonNode node = element.getValue();
|
||||
|
||||
List<JsonNode> newNodeV1Elements = new ArrayList<>();
|
||||
JsonNode newNodeElements = null;
|
||||
|
||||
if (modelVersion == 1) {
|
||||
if (!node.isArray()) {
|
||||
// all processable sub-elements are arrays
|
||||
logger.trace("Element {} in model {} is not an array, ignoring it", elementName, modelName);
|
||||
continue;
|
||||
}
|
||||
node.elements().forEachRemaining(newNodeV1Elements::add);
|
||||
} else {
|
||||
if (!node.isContainerNode() || node.isArray()) {
|
||||
// all processable sub-elements are container nodes (not array)
|
||||
logger.trace("Element {} in model {} is not a container object, ignoring it", elementName,
|
||||
if (!node.isContainerNode() || node.isArray()) {
|
||||
// all processable sub-elements are container nodes (not array)
|
||||
logger.trace("Element {} in model {} is not a container object, ignoring it", elementName,
|
||||
modelName);
|
||||
if (getElementName(YamlSemanticTagDTO.class).equals(elementName) && node.isArray()) {
|
||||
logger.warn(
|
||||
"Your YAML model {} contains custom tags with an old and now unsupported syntax. An upgrade of this model is required to upgrade to the new syntax. This can be done by running the upgrade tool.",
|
||||
modelName);
|
||||
continue;
|
||||
}
|
||||
newNodeElements = node;
|
||||
continue;
|
||||
}
|
||||
JsonNode newNodeElements = node;
|
||||
|
||||
List<JsonNode> oldNodeV1Elements = model.getNodesV1().getOrDefault(elementName, List.of());
|
||||
JsonNode oldNodeElements = model.getNodes().get(elementName);
|
||||
|
||||
for (YamlModelListener<?> elementListener : getElementListeners(elementName, modelVersion)) {
|
||||
@@ -238,9 +228,9 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
List<String> warnings = new ArrayList<>();
|
||||
|
||||
Map<String, ? extends YamlElement> oldElements = listToMap(
|
||||
parseJsonNodes(oldNodeV1Elements, oldNodeElements, elementClass, null, null));
|
||||
parseJsonMapNode(oldNodeElements, elementClass, null, null));
|
||||
Map<String, ? extends YamlElement> newElements = listToMap(
|
||||
parseJsonNodes(newNodeV1Elements, newNodeElements, elementClass, errors, warnings));
|
||||
parseJsonMapNode(newNodeElements, elementClass, errors, warnings));
|
||||
|
||||
errors.forEach(error -> {
|
||||
logger.warn("YAML model {}: {}", modelName, error);
|
||||
@@ -276,47 +266,23 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
}
|
||||
|
||||
// replace cache
|
||||
if (modelVersion == 1) {
|
||||
model.getNodesV1().put(elementName, newNodeV1Elements);
|
||||
} else {
|
||||
model.getNodes().put(elementName, newNodeElements);
|
||||
}
|
||||
model.getNodes().put(elementName, newNodeElements);
|
||||
}
|
||||
|
||||
// remove removed elements
|
||||
if (modelVersion == 1) {
|
||||
model.getNodesV1().entrySet().removeIf(e -> {
|
||||
String elementName = e.getKey();
|
||||
if (newElementNames.contains(elementName)) {
|
||||
return false;
|
||||
}
|
||||
model.getNodes().entrySet().removeIf(e -> {
|
||||
String elementName = e.getKey();
|
||||
if (newElementNames.contains(elementName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<JsonNode> removedNodes = e.getValue();
|
||||
if (removedNodes != null) {
|
||||
getElementListeners(elementName, modelVersion).forEach(listener -> {
|
||||
List removedElements = parseJsonNodesV1(removedNodes, listener.getElementClass(), null,
|
||||
null);
|
||||
listener.removedModel(modelName, removedElements);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
JsonNode removedNode = e.getValue();
|
||||
getElementListeners(elementName, modelVersion).forEach(listener -> {
|
||||
List removedElements = parseJsonMapNode(removedNode, listener.getElementClass(), null, null);
|
||||
listener.removedModel(modelName, removedElements);
|
||||
});
|
||||
} else {
|
||||
model.getNodes().entrySet().removeIf(e -> {
|
||||
String elementName = e.getKey();
|
||||
if (newElementNames.contains(elementName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonNode removedNode = e.getValue();
|
||||
getElementListeners(elementName, modelVersion).forEach(listener -> {
|
||||
List removedElements = parseJsonMapNode(removedNode, listener.getElementClass(), null,
|
||||
null);
|
||||
listener.removedModel(modelName, removedElements);
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
checkElementNames(modelName, model);
|
||||
} else {
|
||||
@@ -335,16 +301,6 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
}
|
||||
logger.info("Removing YAML model {}", modelName);
|
||||
int version = removedModel.getVersion();
|
||||
for (Map.Entry<String, List<JsonNode>> modelEntry : removedModel.getNodesV1().entrySet()) {
|
||||
String elementName = modelEntry.getKey();
|
||||
List<JsonNode> removedNodes = modelEntry.getValue();
|
||||
if (!removedNodes.isEmpty()) {
|
||||
getElementListeners(elementName, version).forEach(listener -> {
|
||||
List removedElements = parseJsonNodesV1(removedNodes, listener.getElementClass(), null, null);
|
||||
listener.removedModel(modelName, removedElements);
|
||||
});
|
||||
}
|
||||
}
|
||||
for (Map.Entry<String, @Nullable JsonNode> modelEntry : removedModel.getNodes().entrySet()) {
|
||||
String elementName = modelEntry.getKey();
|
||||
JsonNode removedMapNode = modelEntry.getValue();
|
||||
@@ -376,14 +332,13 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
"Element {} in model {} version {} is still supported but deprecated, please consider migrating your model to a more recent version",
|
||||
elementName, modelName, modelVersion);
|
||||
}
|
||||
List<JsonNode> modelNodes = model.getNodesV1().getOrDefault(elementName, List.of());
|
||||
JsonNode modelMapNode = model.getNodes().get(elementName);
|
||||
if (modelNodes.isEmpty() && modelMapNode == null) {
|
||||
if (modelMapNode == null) {
|
||||
return;
|
||||
}
|
||||
List<String> errors = new ArrayList<>();
|
||||
List<String> warnings = new ArrayList<>();
|
||||
List modelElements = parseJsonNodes(modelNodes, modelMapNode, elementClass, errors, warnings);
|
||||
List modelElements = parseJsonMapNode(modelMapNode, elementClass, errors, warnings);
|
||||
errors.forEach(error -> {
|
||||
logger.warn("YAML model {}: {}", modelName, error);
|
||||
});
|
||||
@@ -406,8 +361,7 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
private void checkElementNames(String modelName, YamlModelWrapper model) {
|
||||
Set<String> elementListenerNames = elementListeners.keySet();
|
||||
if (elementListenerNames.containsAll(KNOWN_ELEMENTS)) {
|
||||
Set<String> modelElementNames = model.getVersion() == 1 ? model.getNodesV1().keySet()
|
||||
: model.getNodes().keySet();
|
||||
Set<String> modelElementNames = model.getNodes().keySet();
|
||||
modelElementNames.stream().filter(e -> !KNOWN_ELEMENTS.contains(e)).forEach(unknownElement -> {
|
||||
logger.warn("Element '{}' in model {} is unknown.", unknownElement, modelName);
|
||||
});
|
||||
@@ -435,29 +389,19 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
return;
|
||||
}
|
||||
|
||||
List<JsonNode> addedNodes = new ArrayList<>();
|
||||
JsonNode mapAddedNode = null;
|
||||
if (model.getVersion() == 1) {
|
||||
List<JsonNode> modelNodes = Objects
|
||||
.requireNonNull(model.getNodesV1().computeIfAbsent(elementName, k -> new CopyOnWriteArrayList<>()));
|
||||
JsonNode newNode = objectMapper.convertValue(element, JsonNode.class);
|
||||
modelNodes.add(newNode);
|
||||
addedNodes.add(newNode);
|
||||
JsonNode mapAddedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
JsonNode modelMapNode = model.getNodes().get(elementName);
|
||||
if (modelMapNode == null) {
|
||||
model.getNodes().put(elementName, mapAddedNode);
|
||||
} else {
|
||||
mapAddedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
JsonNode modelMapNode = model.getNodes().get(elementName);
|
||||
if (modelMapNode == null) {
|
||||
model.getNodes().put(elementName, mapAddedNode);
|
||||
} else {
|
||||
JsonNode newNode = objectMapper.convertValue(element.cloneWithoutId(), JsonNode.class);
|
||||
((ObjectNode) modelMapNode).set(id, newNode);
|
||||
}
|
||||
JsonNode newNode = objectMapper.convertValue(element.cloneWithoutId(), JsonNode.class);
|
||||
((ObjectNode) modelMapNode).set(id, newNode);
|
||||
}
|
||||
// notify listeners
|
||||
for (YamlModelListener<?> l : getElementListeners(elementName, model.getVersion())) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
List<String> warnings = new ArrayList<>();
|
||||
List newElements = parseJsonNodes(addedNodes, mapAddedNode, l.getElementClass(), errors, warnings);
|
||||
List newElements = parseJsonMapNode(mapAddedNode, l.getElementClass(), errors, warnings);
|
||||
errors.forEach(error -> {
|
||||
logger.warn("YAML model {}: {}", modelName, error);
|
||||
});
|
||||
@@ -487,31 +431,21 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
return;
|
||||
}
|
||||
|
||||
List<JsonNode> modelNodes = model.getNodesV1().get(elementName);
|
||||
JsonNode modelMapNode = model.getNodes().get(elementName);
|
||||
if (modelNodes == null && modelMapNode == null) {
|
||||
if (modelMapNode == null) {
|
||||
logger.warn("Failed to remove {} from model {} because type {} is not known in the model.", element,
|
||||
modelName, elementName);
|
||||
return;
|
||||
}
|
||||
JsonNode toRemove = modelNodes == null ? null : findNodeById(modelNodes, element.getClass(), id);
|
||||
boolean found = modelMapNode == null ? false : modelMapNode.has(id);
|
||||
if (toRemove == null && !found) {
|
||||
if (!modelMapNode.has(id)) {
|
||||
logger.warn("Failed to remove {} from model {} because element is not in model.", element, modelName);
|
||||
return;
|
||||
}
|
||||
List<JsonNode> removedNodes = new ArrayList<>();
|
||||
JsonNode mapRemovedNode = null;
|
||||
if (toRemove != null) {
|
||||
modelNodes.remove(toRemove);
|
||||
removedNodes.add(toRemove);
|
||||
} else if (found) {
|
||||
((ObjectNode) modelMapNode).remove(id);
|
||||
mapRemovedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
}
|
||||
((ObjectNode) modelMapNode).remove(id);
|
||||
JsonNode mapRemovedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
// notify listeners
|
||||
for (YamlModelListener<?> l : getElementListeners(elementName, model.getVersion())) {
|
||||
List oldElements = parseJsonNodes(removedNodes, mapRemovedNode, l.getElementClass(), null, null);
|
||||
List oldElements = parseJsonMapNode(mapRemovedNode, l.getElementClass(), null, null);
|
||||
if (!oldElements.isEmpty()) {
|
||||
l.removedModel(modelName, oldElements);
|
||||
}
|
||||
@@ -535,35 +469,24 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
return;
|
||||
}
|
||||
|
||||
List<JsonNode> modelNodes = model.getNodesV1().get(elementName);
|
||||
JsonNode modelMapNode = model.getNodes().get(elementName);
|
||||
if (modelNodes == null && modelMapNode == null) {
|
||||
if (modelMapNode == null) {
|
||||
logger.warn("Failed to update {} in model {} because type {} is not known in the model.", element,
|
||||
modelName, elementName);
|
||||
return;
|
||||
}
|
||||
JsonNode oldElement = modelNodes == null ? null : findNodeById(modelNodes, element.getClass(), id);
|
||||
boolean found = modelMapNode == null ? false : modelMapNode.has(id);
|
||||
if (oldElement == null && !found) {
|
||||
if (!modelMapNode.has(id)) {
|
||||
logger.warn("Failed to update {} in model {} because element is not in model.", element, modelName);
|
||||
return;
|
||||
}
|
||||
List<JsonNode> updatedNodes = new ArrayList<>();
|
||||
JsonNode mapUpdatedNode = null;
|
||||
if (oldElement != null) {
|
||||
JsonNode newNode = objectMapper.convertValue(element, JsonNode.class);
|
||||
modelNodes.set(modelNodes.indexOf(oldElement), newNode);
|
||||
updatedNodes.add(newNode);
|
||||
} else if (found) {
|
||||
JsonNode newNode = objectMapper.convertValue(element.cloneWithoutId(), JsonNode.class);
|
||||
((ObjectNode) modelMapNode).set(id, newNode);
|
||||
mapUpdatedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
}
|
||||
JsonNode newNode = objectMapper.convertValue(element.cloneWithoutId(), JsonNode.class);
|
||||
((ObjectNode) modelMapNode).set(id, newNode);
|
||||
JsonNode mapUpdatedNode = objectMapper.valueToTree(Map.of(id, element.cloneWithoutId()));
|
||||
// notify listeners
|
||||
for (YamlModelListener<?> l : getElementListeners(elementName, model.getVersion())) {
|
||||
List<String> errors = new ArrayList<>();
|
||||
List<String> warnings = new ArrayList<>();
|
||||
List newElements = parseJsonNodes(updatedNodes, mapUpdatedNode, l.getElementClass(), errors, warnings);
|
||||
List newElements = parseJsonMapNode(mapUpdatedNode, l.getElementClass(), errors, warnings);
|
||||
errors.forEach(error -> {
|
||||
logger.warn("YAML model {}: {}", modelName, error);
|
||||
});
|
||||
@@ -596,17 +519,9 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
|
||||
rootNode.put(VERSION, model.getVersion());
|
||||
rootNode.put(READ_ONLY, model.isReadOnly());
|
||||
if (model.getVersion() == 1) {
|
||||
for (Map.Entry<String, List<JsonNode>> elementNodes : model.getNodesV1().entrySet()) {
|
||||
ArrayNode arrayNode = nodeFactory.arrayNode();
|
||||
elementNodes.getValue().forEach(arrayNode::add);
|
||||
rootNode.set(elementNodes.getKey(), arrayNode);
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, @Nullable JsonNode> elementNodes : model.getNodes().entrySet()) {
|
||||
if (elementNodes.getValue() != null) {
|
||||
rootNode.set(elementNodes.getKey(), elementNodes.getValue());
|
||||
}
|
||||
for (Map.Entry<String, @Nullable JsonNode> elementNodes : model.getNodes().entrySet()) {
|
||||
if (elementNodes.getValue() != null) {
|
||||
rootNode.set(elementNodes.getKey(), elementNodes.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -668,42 +583,10 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
return getElementListeners(elementName).stream().filter(l -> l.isVersionSupported(version)).toList();
|
||||
}
|
||||
|
||||
// To be used only for version 1
|
||||
private <T extends YamlElement> @Nullable JsonNode findNodeById(List<JsonNode> nodes, Class<T> elementClass,
|
||||
String id) {
|
||||
return nodes.stream().filter(node -> {
|
||||
Optional<T> parsedNode = parseJsonNode(node, elementClass, null, null);
|
||||
return parsedNode.filter(yamlDTO -> id.equals(yamlDTO.getId())).isPresent();
|
||||
}).findAny().orElse(null);
|
||||
}
|
||||
|
||||
private Map<String, ? extends YamlElement> listToMap(List<? extends YamlElement> elements) {
|
||||
return elements.stream().collect(Collectors.toMap(YamlElement::getId, e -> e));
|
||||
}
|
||||
|
||||
// To be used only for version 1
|
||||
private <T extends YamlElement> List<T> parseJsonNodesV1(List<JsonNode> nodes, Class<T> elementClass,
|
||||
@Nullable List<String> errors, @Nullable List<String> warnings) {
|
||||
return nodes.stream().map(nE -> parseJsonNode(nE, elementClass, errors, warnings)).flatMap(Optional::stream)
|
||||
.filter(elt -> elt.isValid(errors, warnings)).toList();
|
||||
}
|
||||
|
||||
// To be used only for version 1
|
||||
private <T extends YamlElement> Optional<T> parseJsonNode(JsonNode node, Class<T> elementClass,
|
||||
@Nullable List<String> errors, @Nullable List<String> warnings) {
|
||||
try {
|
||||
return Optional.of(objectMapper.treeToValue(node, elementClass));
|
||||
} catch (JsonProcessingException e) {
|
||||
if (errors != null) {
|
||||
String msg = e.getMessage();
|
||||
errors.add("Could not parse element %s to %s: %s".formatted(node.toPrettyString(),
|
||||
elementClass.getSimpleName(), msg == null ? "" : msg.replace(UNWANTED_EXCEPTION_TEXT, "")));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// To be not used for version 1
|
||||
private <T extends YamlElement> List<T> parseJsonMapNode(@Nullable JsonNode mapNode, Class<T> elementClass,
|
||||
@Nullable List<String> errors, @Nullable List<String> warnings) {
|
||||
List<T> elements = new ArrayList<>();
|
||||
@@ -744,13 +627,4 @@ public class YamlModelRepositoryImpl implements WatchService.WatchEventListener,
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
// Usable whatever the format version
|
||||
private <T extends YamlElement> List<T> parseJsonNodes(List<JsonNode> nodes, @Nullable JsonNode mapNode,
|
||||
Class<T> elementClass, @Nullable List<String> errors, @Nullable List<String> warnings) {
|
||||
List<T> elements = new ArrayList<>();
|
||||
elements.addAll(parseJsonNodesV1(nodes, elementClass, errors, warnings));
|
||||
elements.addAll(parseJsonMapNode(mapNode, elementClass, errors, warnings));
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-23
@@ -12,7 +12,6 @@
|
||||
*/
|
||||
package org.openhab.core.model.yaml.internal;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -25,19 +24,12 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
* The {@link YamlModelWrapper} is used to store the information read from a model in the model cache.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
* @author Laurent Garnier - Introduce version 2 using map instead of table
|
||||
* @author Laurent Garnier - Map used instead of table
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class YamlModelWrapper {
|
||||
private final int version;
|
||||
private final boolean readOnly;
|
||||
/**
|
||||
* Nodes as a list in version 1
|
||||
*/
|
||||
private final Map<String, List<JsonNode>> nodesV1 = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* Nodes as a map in version >= 2
|
||||
*/
|
||||
private final Map<String, @Nullable JsonNode> nodes = new ConcurrentHashMap<>();
|
||||
|
||||
public YamlModelWrapper(int version, boolean readOnly) {
|
||||
@@ -53,20 +45,6 @@ public class YamlModelWrapper {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nodes for version 1
|
||||
*
|
||||
* @return the nodes
|
||||
*/
|
||||
public Map<String, List<JsonNode>> getNodesV1() {
|
||||
return nodesV1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the nodes for version >= 2
|
||||
*
|
||||
* @return the nodes
|
||||
*/
|
||||
public Map<String, @Nullable JsonNode> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ public class YamlThingProvider extends AbstractProvider<Thing>
|
||||
|
||||
@Override
|
||||
public boolean isVersionSupported(int version) {
|
||||
return version >= 2;
|
||||
return version >= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+29
-203
@@ -60,13 +60,10 @@ public class YamlModelRepositoryImplTest {
|
||||
private static final Path SOURCE_PATH = Path.of("src/test/resources/model");
|
||||
private static final String MODEL_NAME = "model.yaml";
|
||||
private static final Path MODEL_PATH = Path.of(MODEL_NAME);
|
||||
private static final String MODEL2_NAME = "model2.yaml";
|
||||
private static final Path MODEL2_PATH = Path.of(MODEL2_NAME);
|
||||
|
||||
private @Mock @NonNullByDefault({}) WatchService watchServiceMock;
|
||||
private @TempDir @NonNullByDefault({}) Path watchPath;
|
||||
private @NonNullByDefault({}) Path fullModelPath;
|
||||
private @NonNullByDefault({}) Path fullModel2Path;
|
||||
|
||||
private @Mock @NonNullByDefault({}) YamlModelListener<@NonNull FirstTypeDTO> firstTypeListener;
|
||||
private @Mock @NonNullByDefault({}) YamlModelListener<@NonNull SecondTypeDTO> secondTypeListener1;
|
||||
@@ -79,7 +76,6 @@ public class YamlModelRepositoryImplTest {
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
fullModelPath = watchPath.resolve(MODEL_PATH);
|
||||
fullModel2Path = watchPath.resolve(MODEL2_PATH);
|
||||
when(watchServiceMock.getWatchPath()).thenReturn(watchPath);
|
||||
|
||||
when(firstTypeListener.getElementClass()).thenReturn(FirstTypeDTO.class);
|
||||
@@ -96,7 +92,6 @@ public class YamlModelRepositoryImplTest {
|
||||
@Test
|
||||
public void testFileAddedAfterListeners() throws IOException {
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileAddedOrRemoved.yaml"), fullModel2Path);
|
||||
|
||||
YamlModelRepositoryImpl modelRepository = new YamlModelRepositoryImpl(watchServiceMock);
|
||||
modelRepository.addYamlModelListener(firstTypeListener);
|
||||
@@ -104,27 +99,23 @@ public class YamlModelRepositoryImplTest {
|
||||
modelRepository.addYamlModelListener(secondTypeListener2);
|
||||
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
|
||||
verify(firstTypeListener).addedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL2_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener1, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener2).addedModel(eq(MODEL_NAME), secondTypeCaptor2.capture());
|
||||
verify(secondTypeListener2).addedModel(eq(MODEL2_NAME), secondTypeCaptor2.capture());
|
||||
verify(secondTypeListener2, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener2, never()).removedModel(any(), any());
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
assertThat(firstTypeCaptorValues, hasSize(1));
|
||||
List<Collection<SecondTypeDTO>> secondTypeCaptor1Values = secondTypeCaptor1.getAllValues();
|
||||
assertThat(secondTypeCaptor1Values, hasSize(2));
|
||||
assertThat(secondTypeCaptor1Values, hasSize(1));
|
||||
List<Collection<SecondTypeDTO>> secondTypeCaptor2Values = secondTypeCaptor2.getAllValues();
|
||||
assertThat(secondTypeCaptor2Values, hasSize(2));
|
||||
assertThat(secondTypeCaptor2Values, hasSize(1));
|
||||
|
||||
Collection<FirstTypeDTO> firstTypeElements = firstTypeCaptorValues.getFirst();
|
||||
Collection<SecondTypeDTO> secondTypeElements1 = secondTypeCaptor1Values.getFirst();
|
||||
@@ -137,53 +128,36 @@ public class YamlModelRepositoryImplTest {
|
||||
assertThat(secondTypeElements1, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
assertThat(secondTypeElements2, hasSize(1));
|
||||
assertThat(secondTypeElements2, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
|
||||
firstTypeElements = firstTypeCaptorValues.get(1);
|
||||
secondTypeElements1 = secondTypeCaptor1Values.get(1);
|
||||
secondTypeElements2 = secondTypeCaptor2Values.get(1);
|
||||
|
||||
assertThat(firstTypeElements, hasSize(2));
|
||||
assertThat(firstTypeElements,
|
||||
containsInAnyOrder(new FirstTypeDTO("First1", "Description1"), new FirstTypeDTO("First2", null)));
|
||||
assertThat(secondTypeElements1, hasSize(1));
|
||||
assertThat(secondTypeElements1, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
assertThat(secondTypeElements2, hasSize(1));
|
||||
assertThat(secondTypeElements2, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileAddedBeforeListeners() throws IOException {
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileAddedOrRemoved.yaml"), fullModel2Path);
|
||||
|
||||
YamlModelRepositoryImpl modelRepository = new YamlModelRepositoryImpl(watchServiceMock);
|
||||
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
|
||||
modelRepository.addYamlModelListener(firstTypeListener);
|
||||
modelRepository.addYamlModelListener(secondTypeListener1);
|
||||
modelRepository.addYamlModelListener(secondTypeListener2);
|
||||
|
||||
verify(firstTypeListener).addedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL2_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener1, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener2).addedModel(eq(MODEL_NAME), secondTypeCaptor2.capture());
|
||||
verify(secondTypeListener2).addedModel(eq(MODEL2_NAME), secondTypeCaptor2.capture());
|
||||
verify(secondTypeListener2, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener2, never()).removedModel(any(), any());
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
assertThat(firstTypeCaptorValues, hasSize(1));
|
||||
List<Collection<SecondTypeDTO>> secondTypeCaptor1Values = secondTypeCaptor1.getAllValues();
|
||||
assertThat(secondTypeCaptor1Values, hasSize(2));
|
||||
assertThat(secondTypeCaptor1Values, hasSize(1));
|
||||
List<Collection<SecondTypeDTO>> secondTypeCaptor2Values = secondTypeCaptor2.getAllValues();
|
||||
assertThat(secondTypeCaptor2Values, hasSize(2));
|
||||
assertThat(secondTypeCaptor2Values, hasSize(1));
|
||||
|
||||
Collection<FirstTypeDTO> firstTypeElements = firstTypeCaptorValues.getFirst();
|
||||
Collection<SecondTypeDTO> secondTypeElements1 = secondTypeCaptor1Values.getFirst();
|
||||
@@ -196,18 +170,6 @@ public class YamlModelRepositoryImplTest {
|
||||
assertThat(secondTypeElements1, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
assertThat(secondTypeElements2, hasSize(1));
|
||||
assertThat(secondTypeElements2, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
|
||||
firstTypeElements = firstTypeCaptorValues.get(1);
|
||||
secondTypeElements1 = secondTypeCaptor1Values.get(1);
|
||||
secondTypeElements2 = secondTypeCaptor2Values.get(1);
|
||||
|
||||
assertThat(firstTypeElements, hasSize(2));
|
||||
assertThat(firstTypeElements,
|
||||
containsInAnyOrder(new FirstTypeDTO("First1", "Description1"), new FirstTypeDTO("First2", null)));
|
||||
assertThat(secondTypeElements1, hasSize(1));
|
||||
assertThat(secondTypeElements1, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
assertThat(secondTypeElements2, hasSize(1));
|
||||
assertThat(secondTypeElements2, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -215,7 +177,6 @@ public class YamlModelRepositoryImplTest {
|
||||
YamlModelRepositoryImpl modelRepository = new YamlModelRepositoryImpl(watchServiceMock);
|
||||
modelRepository.addYamlModelListener(firstTypeListener);
|
||||
|
||||
// File in v1 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileUpdatePost.yaml"), fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL_NAME), any());
|
||||
@@ -226,88 +187,43 @@ public class YamlModelRepositoryImplTest {
|
||||
verify(firstTypeListener).updatedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener).removedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
|
||||
// File in v2 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileUpdatePost.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), any());
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileUpdatePre.yaml"), fullModel2Path,
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.MODIFY, fullModel2Path);
|
||||
verify(firstTypeListener, times(2)).addedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener).updatedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener).removedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(8));
|
||||
assertThat(firstTypeCaptorValues, hasSize(4));
|
||||
|
||||
// added originally - first file
|
||||
// added originally
|
||||
assertThat(firstTypeCaptorValues.getFirst(), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
// added by update - first file
|
||||
// added by update
|
||||
assertThat(firstTypeCaptorValues.get(1), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(1), contains(new FirstTypeDTO("Fourth", "Fourth original")));
|
||||
// updated by update - first file
|
||||
// updated by update
|
||||
assertThat(firstTypeCaptorValues.get(2), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(2), contains(new FirstTypeDTO("Second", "Second modified")));
|
||||
// removed by update - first file
|
||||
// removed by update
|
||||
assertThat(firstTypeCaptorValues.get(3), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(3), contains(new FirstTypeDTO("Third", "Third original")));
|
||||
|
||||
// added originally -second file
|
||||
assertThat(firstTypeCaptorValues.get(4), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.get(4), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
// added by update -second file
|
||||
assertThat(firstTypeCaptorValues.get(5), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(5), contains(new FirstTypeDTO("Fourth", "Fourth original")));
|
||||
// updated by update -second file
|
||||
assertThat(firstTypeCaptorValues.get(6), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(6), contains(new FirstTypeDTO("Second", "Second modified")));
|
||||
// removed by update -second file
|
||||
assertThat(firstTypeCaptorValues.get(7), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(7), contains(new FirstTypeDTO("Third", "Third original")));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({ //
|
||||
"modelFileUpdateRemovedElements.yaml,modelV2FileUpdateRemovedElements.yaml",
|
||||
"modelFileUpdateRenamedElements.yaml,modelV2FileUpdateRenamedElements.yaml",
|
||||
"modelFileUpdateRemovedVersion.yaml,modelV2FileUpdateRemovedVersion.yaml" //
|
||||
"modelFileUpdateRemovedElements.yaml", "modelFileUpdateRenamedElements.yaml",
|
||||
"modelFileUpdateRemovedVersion.yaml" //
|
||||
})
|
||||
public void testFileRemovedElements(String v1File, String v2File) throws IOException {
|
||||
public void testFileRemovedElements(String file) throws IOException {
|
||||
YamlModelRepositoryImpl modelRepository = new YamlModelRepositoryImpl(watchServiceMock);
|
||||
modelRepository.addYamlModelListener(firstTypeListener);
|
||||
|
||||
// File in v1 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileUpdatePost.yaml"), fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL_NAME), any());
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve(v1File), fullModelPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
Files.copy(SOURCE_PATH.resolve(file), fullModelPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.MODIFY, fullModelPath);
|
||||
verify(firstTypeListener).removedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
|
||||
Collection<FirstTypeDTO> firstTypeElements = firstTypeCaptor.getAllValues().getFirst();
|
||||
|
||||
// Check that the elements were removed
|
||||
assertThat(firstTypeElements, hasSize(3));
|
||||
assertThat(firstTypeElements, containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
|
||||
// File in v2 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileUpdatePost.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), any());
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve(v2File), fullModel2Path, StandardCopyOption.REPLACE_EXISTING);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.MODIFY, fullModel2Path);
|
||||
verify(firstTypeListener).removedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
|
||||
assertThat(firstTypeCaptor.getAllValues(), hasSize(2));
|
||||
firstTypeElements = firstTypeCaptor.getAllValues().getLast();
|
||||
|
||||
// Check that the elements were removed
|
||||
assertThat(firstTypeElements, hasSize(3));
|
||||
assertThat(firstTypeElements, containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
@@ -320,7 +236,6 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
modelRepository.addYamlModelListener(firstTypeListener);
|
||||
|
||||
// File in v1 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileUpdatePost.yaml"), fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.DELETE, fullModelPath);
|
||||
@@ -329,35 +244,17 @@ public class YamlModelRepositoryImplTest {
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener).removedModel(eq(MODEL_NAME), firstTypeCaptor.capture());
|
||||
|
||||
// File in v2 format
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileUpdatePost.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.DELETE, fullModel2Path);
|
||||
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener).removedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(4));
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
|
||||
// all are added - first file
|
||||
// all are added
|
||||
assertThat(firstTypeCaptorValues.getFirst(), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
// all are removed - first file
|
||||
// all are removed
|
||||
assertThat(firstTypeCaptorValues.get(1), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.get(1), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
|
||||
// all are added - second file
|
||||
assertThat(firstTypeCaptorValues.get(2), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.get(2), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
// all are removed - second file
|
||||
assertThat(firstTypeCaptorValues.get(3), hasSize(3));
|
||||
assertThat(firstTypeCaptorValues.get(3), containsInAnyOrder(new FirstTypeDTO("First", "First original"),
|
||||
new FirstTypeDTO("Second", "Second original"), new FirstTypeDTO("Third", "Third original")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -387,35 +284,15 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modifyModelV2InitialContent.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
modelRepository.addElementToModel(MODEL2_NAME, added);
|
||||
modelRepository.addElementToModel(MODEL2_NAME, added2);
|
||||
verify(firstTypeListener, times(2)).addedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL2_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener1, never()).removedModel(any(), any());
|
||||
|
||||
actualFileContent = Files.readString(fullModel2Path);
|
||||
expectedFileContent = Files.readString(SOURCE_PATH.resolve("addToModelV2ExpectedContent.yaml"));
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(4));
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
assertThat(firstTypeCaptorValues.get(1), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(1), contains(new FirstTypeDTO("element3", "description3")));
|
||||
assertThat(firstTypeCaptorValues.get(3), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(3), contains(new FirstTypeDTO("element3", "description3")));
|
||||
|
||||
List<Collection<SecondTypeDTO>> secondTypeCaptor1Values = secondTypeCaptor1.getAllValues();
|
||||
assertThat(secondTypeCaptor1Values, hasSize(2));
|
||||
assertThat(secondTypeCaptor1Values, hasSize(1));
|
||||
assertThat(secondTypeCaptor1Values.getFirst(), hasSize(1));
|
||||
assertThat(secondTypeCaptor1Values.getFirst(), contains(new SecondTypeDTO("elt1", "My label")));
|
||||
assertThat(secondTypeCaptor1Values.get(1), hasSize(1));
|
||||
assertThat(secondTypeCaptor1Values.get(1), contains(new SecondTypeDTO("elt1", "My label")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -439,24 +316,10 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modifyModelV2InitialContent.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
modelRepository.updateElementInModel(MODEL2_NAME, updated);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), any());
|
||||
verify(firstTypeListener).updatedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
verify(firstTypeListener, never()).removedModel(any(), any());
|
||||
|
||||
actualFileContent = Files.readString(fullModel2Path);
|
||||
expectedFileContent = Files.readString(SOURCE_PATH.resolve("updateInModelV2ExpectedContent.yaml"));
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
assertThat(firstTypeCaptorValues, hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), contains(new FirstTypeDTO("element1", "newDescription1")));
|
||||
assertThat(firstTypeCaptorValues.get(1), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(1), contains(new FirstTypeDTO("element1", "newDescription1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -480,24 +343,10 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modifyModelV2InitialContent.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
modelRepository.removeElementFromModel(MODEL2_NAME, removed);
|
||||
verify(firstTypeListener).addedModel(eq(MODEL2_NAME), any());
|
||||
verify(firstTypeListener, never()).updatedModel(any(), any());
|
||||
verify(firstTypeListener).removedModel(eq(MODEL2_NAME), firstTypeCaptor.capture());
|
||||
|
||||
actualFileContent = Files.readString(fullModel2Path);
|
||||
expectedFileContent = Files.readString(SOURCE_PATH.resolve("removeFromModelV2ExpectedContent.yaml"));
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
List<Collection<FirstTypeDTO>> firstTypeCaptorValues = firstTypeCaptor.getAllValues();
|
||||
assertThat(firstTypeCaptorValues, hasSize(2));
|
||||
assertThat(firstTypeCaptorValues, hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.getFirst(), contains(new FirstTypeDTO("element1", "description1")));
|
||||
assertThat(firstTypeCaptorValues.get(1), hasSize(1));
|
||||
assertThat(firstTypeCaptorValues.get(1), contains(new FirstTypeDTO("element1", "description1")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -521,24 +370,12 @@ public class YamlModelRepositoryImplTest {
|
||||
Yaml yaml = new Yaml();
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileAddedOrRemoved.yaml"), fullModel2Path);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
modelRepository.addElementToModel(MODEL2_NAME, added);
|
||||
modelRepository.removeElementFromModel(MODEL2_NAME, removed);
|
||||
modelRepository.updateElementInModel(MODEL2_NAME, updated);
|
||||
|
||||
actualFileContent = Files.readString(fullModel2Path);
|
||||
expectedFileContent = Files.readString(SOURCE_PATH.resolve("modelV2FileAddedOrRemoved.yaml"));
|
||||
|
||||
assertThat(yaml.load(actualFileContent), equalTo(yaml.load(expectedFileContent)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistingProviderForVersion() throws IOException {
|
||||
// Provider supporting only version 1
|
||||
// Provider supports version 1
|
||||
when(firstTypeListener.isVersionSupported(eq(1))).thenReturn(true);
|
||||
when(firstTypeListener.isVersionSupported(eq(2))).thenReturn(false);
|
||||
when(firstTypeListener.isDeprecated()).thenReturn(false);
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
@@ -560,9 +397,8 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
@Test
|
||||
public void testExistingDeprecatedProviderForVersion() throws IOException {
|
||||
// Provider supporting only version 1 and deprecated
|
||||
// Provider supports version 1 as deprecated
|
||||
when(firstTypeListener.isVersionSupported(eq(1))).thenReturn(true);
|
||||
when(firstTypeListener.isVersionSupported(eq(2))).thenReturn(false);
|
||||
when(firstTypeListener.isDeprecated()).thenReturn(true);
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
@@ -584,9 +420,8 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
@Test
|
||||
public void testNoProviderForVersion() throws IOException {
|
||||
// Provider supporting only version 2
|
||||
// Provider does not support version 1
|
||||
when(firstTypeListener.isVersionSupported(eq(1))).thenReturn(false);
|
||||
when(firstTypeListener.isVersionSupported(eq(2))).thenReturn(true);
|
||||
when(firstTypeListener.isDeprecated()).thenReturn(false);
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
@@ -603,40 +438,31 @@ public class YamlModelRepositoryImplTest {
|
||||
|
||||
@Test
|
||||
public void testDifferentProvidersDependingOnVersion() throws IOException {
|
||||
// secondTypeListener1 supports version 1 only
|
||||
// secondTypeListener1 supports version 1
|
||||
when(secondTypeListener1.isVersionSupported(eq(1))).thenReturn(true);
|
||||
when(secondTypeListener1.isVersionSupported(eq(2))).thenReturn(false);
|
||||
when(secondTypeListener1.isDeprecated()).thenReturn(false);
|
||||
// secondTypeListener2 supports version 2 only
|
||||
// secondTypeListener2 does not supports version 1
|
||||
when(secondTypeListener2.isVersionSupported(eq(1))).thenReturn(false);
|
||||
when(secondTypeListener2.isVersionSupported(eq(2))).thenReturn(true);
|
||||
when(secondTypeListener2.isDeprecated()).thenReturn(false);
|
||||
|
||||
Files.copy(SOURCE_PATH.resolve("modelFileAddedOrRemoved.yaml"), fullModelPath);
|
||||
Files.copy(SOURCE_PATH.resolve("modelV2FileAddedOrRemoved.yaml"), fullModel2Path);
|
||||
|
||||
YamlModelRepositoryImpl modelRepository = new YamlModelRepositoryImpl(watchServiceMock);
|
||||
modelRepository.addYamlModelListener(secondTypeListener1);
|
||||
modelRepository.addYamlModelListener(secondTypeListener2);
|
||||
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModelPath);
|
||||
modelRepository.processWatchEvent(WatchService.Kind.CREATE, fullModel2Path);
|
||||
|
||||
verify(secondTypeListener1).addedModel(eq(MODEL_NAME), secondTypeCaptor1.capture());
|
||||
verify(secondTypeListener1, never()).addedModel(eq(MODEL2_NAME), any());
|
||||
verify(secondTypeListener1, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener1, never()).removedModel(any(), any());
|
||||
verify(secondTypeListener2).addedModel(eq(MODEL2_NAME), secondTypeCaptor2.capture());
|
||||
verify(secondTypeListener2, never()).addedModel(eq(MODEL_NAME), any());
|
||||
|
||||
verify(secondTypeListener2, never()).addedModel(any(), any());
|
||||
verify(secondTypeListener2, never()).updatedModel(any(), any());
|
||||
verify(secondTypeListener2, never()).removedModel(any(), any());
|
||||
|
||||
Collection<SecondTypeDTO> secondTypeElements = secondTypeCaptor1.getValue();
|
||||
assertThat(secondTypeElements, hasSize(1));
|
||||
assertThat(secondTypeElements, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
|
||||
secondTypeElements = secondTypeCaptor2.getValue();
|
||||
assertThat(secondTypeElements, hasSize(1));
|
||||
assertThat(secondTypeElements, contains(new SecondTypeDTO("Second1", "Label1")));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
version: 1
|
||||
readOnly: false
|
||||
firstType:
|
||||
- uid: element1
|
||||
element1:
|
||||
description: description1
|
||||
- uid: element2
|
||||
element2:
|
||||
description: description2
|
||||
- uid: element3
|
||||
element3:
|
||||
description: description3
|
||||
secondType:
|
||||
- id: elt1
|
||||
elt1:
|
||||
label: My label
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
version: 2
|
||||
readOnly: false
|
||||
firstType:
|
||||
element1:
|
||||
description: description1
|
||||
element2:
|
||||
description: description2
|
||||
element3:
|
||||
description: description3
|
||||
secondType:
|
||||
elt1:
|
||||
label: My label
|
||||
+4
-7
@@ -6,23 +6,20 @@ version: 1
|
||||
# known first type
|
||||
firstType:
|
||||
# a valid element with uid and description
|
||||
- uid: First1
|
||||
First1:
|
||||
description: Description1
|
||||
|
||||
# a valid element with uid only
|
||||
- uid: First2
|
||||
|
||||
# an invalid element (missing uid)
|
||||
- description: Description3
|
||||
First2:
|
||||
|
||||
# known second type
|
||||
secondType:
|
||||
# a valid element with id and label
|
||||
- id: Second1
|
||||
Second1:
|
||||
label: Label1
|
||||
|
||||
# unknown third type
|
||||
thirdType:
|
||||
- foo: Bar
|
||||
Foobar:
|
||||
|
||||
nonArrayElement: Test
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
version: 1
|
||||
|
||||
firstType:
|
||||
- uid: First
|
||||
First:
|
||||
description: First original
|
||||
- uid: Second
|
||||
Second:
|
||||
description: Second original
|
||||
- uid: Third
|
||||
Third:
|
||||
description: Third original
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
version: 1
|
||||
|
||||
firstType:
|
||||
- uid: First
|
||||
First:
|
||||
description: First original
|
||||
- uid: Second
|
||||
Second:
|
||||
description: Second modified
|
||||
- uid: Fourth
|
||||
Fourth:
|
||||
description: Fourth original
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
# A YAML test file for updating the model
|
||||
|
||||
version: 1
|
||||
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
# version: 1 => removed in this update
|
||||
|
||||
firstType:
|
||||
- uid: First
|
||||
First:
|
||||
description: First original
|
||||
- uid: Second
|
||||
Second:
|
||||
description: Second original
|
||||
- uid: Third
|
||||
Third:
|
||||
description: Third original
|
||||
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
version: 1
|
||||
|
||||
firstTypeRenamed:
|
||||
- uid: First
|
||||
First:
|
||||
description: First original
|
||||
- uid: Second
|
||||
Second:
|
||||
description: Second original
|
||||
- uid: Third
|
||||
Third:
|
||||
description: Third original
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
# A YAML test file in version 2 with different types
|
||||
# The structure is valid but also contains invalid elements
|
||||
|
||||
version: 2
|
||||
|
||||
# known first type
|
||||
firstType:
|
||||
# a valid element with uid and description
|
||||
First1:
|
||||
description: Description1
|
||||
|
||||
# a valid element with uid only
|
||||
First2:
|
||||
|
||||
# known second type
|
||||
secondType:
|
||||
# a valid element with id and label
|
||||
Second1:
|
||||
label: Label1
|
||||
|
||||
# unknown third type
|
||||
thirdType:
|
||||
Foobar:
|
||||
|
||||
nonArrayElement: Test
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
# A YAML test file in version 2 for updating the model
|
||||
|
||||
version: 2
|
||||
|
||||
firstType:
|
||||
First:
|
||||
description: First original
|
||||
Second:
|
||||
description: Second original
|
||||
Third:
|
||||
description: Third original
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
# A YAML test file in version 2 for updating the model
|
||||
|
||||
version: 2
|
||||
|
||||
firstType:
|
||||
First:
|
||||
description: First original
|
||||
Second:
|
||||
description: Second modified
|
||||
Fourth:
|
||||
description: Fourth original
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
# A YAML test file for updating the model
|
||||
|
||||
version: 2
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
# A YAML test file in version 2 for updating the model
|
||||
|
||||
# version: 2 => removed
|
||||
|
||||
firstType:
|
||||
First:
|
||||
description: First original
|
||||
Second:
|
||||
description: Second original
|
||||
Third:
|
||||
description: Third original
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
# A YAML test file for updating the model
|
||||
|
||||
version: 2
|
||||
|
||||
firstTypeRenamed:
|
||||
First:
|
||||
description: First original
|
||||
Second:
|
||||
description: Second original
|
||||
Third:
|
||||
description: Third original
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
version: 1
|
||||
readOnly: false
|
||||
firstType:
|
||||
- uid: element1
|
||||
element1:
|
||||
description: description1
|
||||
- uid: element2
|
||||
element2:
|
||||
description: description2
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
version: 2
|
||||
readOnly: false
|
||||
firstType:
|
||||
element1:
|
||||
description: description1
|
||||
element2:
|
||||
description: description2
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
version: 1
|
||||
readOnly: false
|
||||
firstType:
|
||||
- uid: element2
|
||||
element2:
|
||||
description: description2
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
version: 2
|
||||
readOnly: false
|
||||
firstType:
|
||||
element2:
|
||||
description: description2
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
version: 1
|
||||
readOnly: false
|
||||
firstType:
|
||||
- uid: element1
|
||||
element1:
|
||||
description: newDescription1
|
||||
- uid: element2
|
||||
element2:
|
||||
description: description2
|
||||
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
version: 2
|
||||
readOnly: false
|
||||
firstType:
|
||||
element1:
|
||||
description: newDescription1
|
||||
element2:
|
||||
description: description2
|
||||
Reference in New Issue
Block a user