diff --git a/CHANGELOG.md b/CHANGELOG.md index 4573cae12..c614ee4b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refactor CSV data sources [#716](https://github.com/ie3-institute/PowerSystemDataModel/issues/716) - Deleted parameter initFiles, set parameter append to false by default [#791](https://github.com/ie3-institute/PowerSystemDataModel/issues/791) - Use nio paths instead of strings for file path [#723](https://github.com/ie3-institute/PowerSystemDataModel/issues/723) +- Data source will throw an exceptions instead of returning an empty optionals [#707](https://github.com/ie3-institute/PowerSystemDataModel/issues/707) ## [3.0.0] - 2023-02-16 diff --git a/src/main/java/edu/ie3/datamodel/exceptions/FailureException.java b/src/main/java/edu/ie3/datamodel/exceptions/FailureException.java new file mode 100644 index 000000000..7c1f257a2 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/FailureException.java @@ -0,0 +1,20 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +public class FailureException extends Exception { + public FailureException(String message, Throwable throwable) { + super(message, throwable); + } + + public FailureException(String message) { + super(message); + } + + public FailureException(Throwable throwable) { + super(throwable); + } +} diff --git a/src/main/java/edu/ie3/datamodel/exceptions/GraphicSourceException.java b/src/main/java/edu/ie3/datamodel/exceptions/GraphicSourceException.java new file mode 100644 index 000000000..91d6958c7 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/GraphicSourceException.java @@ -0,0 +1,14 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +import java.util.List; + +public class GraphicSourceException extends SourceException { + public GraphicSourceException(String message, List exceptions) { + super(message, exceptions); + } +} diff --git a/src/main/java/edu/ie3/datamodel/exceptions/RawGridException.java b/src/main/java/edu/ie3/datamodel/exceptions/RawGridException.java new file mode 100644 index 000000000..629232220 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/RawGridException.java @@ -0,0 +1,14 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +import java.util.List; + +public class RawGridException extends SourceException { + public RawGridException(String message, List exceptions) { + super(message, exceptions); + } +} diff --git a/src/main/java/edu/ie3/datamodel/exceptions/SourceException.java b/src/main/java/edu/ie3/datamodel/exceptions/SourceException.java index 65d2f1cff..2a5a19030 100644 --- a/src/main/java/edu/ie3/datamodel/exceptions/SourceException.java +++ b/src/main/java/edu/ie3/datamodel/exceptions/SourceException.java @@ -5,6 +5,9 @@ */ package edu.ie3.datamodel.exceptions; +import edu.ie3.datamodel.utils.ExceptionUtils; +import java.util.List; + /** * Exception that should be used whenever an error occurs in a instance of a {@link * edu.ie3.datamodel.io.source.DataSource} @@ -27,4 +30,8 @@ public SourceException(final Throwable cause) { public SourceException(final String message) { super(message); } + + public SourceException(String message, List exceptions) { + super(message + " " + ExceptionUtils.getMessages(exceptions), exceptions.get(0)); + } } diff --git a/src/main/java/edu/ie3/datamodel/exceptions/SystemParticipantsException.java b/src/main/java/edu/ie3/datamodel/exceptions/SystemParticipantsException.java new file mode 100644 index 000000000..7c97dadf7 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/SystemParticipantsException.java @@ -0,0 +1,14 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +import java.util.List; + +public class SystemParticipantsException extends SourceException { + public SystemParticipantsException(String message, List exceptions) { + super(message, exceptions); + } +} diff --git a/src/main/java/edu/ie3/datamodel/exceptions/TryException.java b/src/main/java/edu/ie3/datamodel/exceptions/TryException.java new file mode 100644 index 000000000..61d134d0f --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/exceptions/TryException.java @@ -0,0 +1,12 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.exceptions; + +public class TryException extends RuntimeException { + public TryException(String message, Throwable throwable) { + super(message, throwable); + } +} diff --git a/src/main/java/edu/ie3/datamodel/io/factory/Factory.java b/src/main/java/edu/ie3/datamodel/io/factory/Factory.java index 8a64f0ea7..759fa9e4d 100644 --- a/src/main/java/edu/ie3/datamodel/io/factory/Factory.java +++ b/src/main/java/edu/ie3/datamodel/io/factory/Factory.java @@ -6,6 +6,8 @@ package edu.ie3.datamodel.io.factory; import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.*; import java.util.function.IntFunction; import java.util.stream.Collectors; @@ -39,27 +41,40 @@ public List> getSupportedClasses() { * data * * @param data EntityData (or subclass) containing the data - * @return An entity wrapped in Option if successful, an empty option otherwise + * @return An entity wrapped in a {@link Success} if successful, or an exception wrapped in a + * {@link Failure} */ - public Optional get(D data) { + public Try get(D data) { isSupportedClass(data.getTargetClass()); // magic: case-insensitive get/set calls on set strings final List> allFields = getFields(data); - validateParameters(data, allFields.toArray((IntFunction[]>) Set[]::new)); - try { + validateParameters(data, allFields.toArray((IntFunction[]>) Set[]::new)); + // build the model - return Optional.of(buildModel(data)); + return new Success<>(buildModel(data)); } catch (FactoryException e) { - // only catch FactoryExceptions, as more serious exceptions should be handled elsewhere - log.error( - "An error occurred when creating instance of {}.class.", - data.getTargetClass().getSimpleName(), - e); + return new Failure<>( + new FactoryException( + "An error occurred when creating instance of " + + data.getTargetClass().getSimpleName() + + ".class.", + e)); } - return Optional.empty(); + } + + /** + * Builds entity with data from given EntityData object after doing all kinds of checks on the + * data + * + * @param data EntityData (or subclass) containing the data wrapped in a {@link Try} + * @return An entity wrapped in a {@link Success} if successful, or an exception wrapped in a + * {@link Failure} + */ + public Try get(Try data) { + return data.transformF(FactoryException::new).flatMap(this::get); } /** diff --git a/src/main/java/edu/ie3/datamodel/io/source/EntitySource.java b/src/main/java/edu/ie3/datamodel/io/source/EntitySource.java index 4f1f89c63..eec826f97 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/EntitySource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/EntitySource.java @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.SimpleEntityData; import edu.ie3.datamodel.io.factory.input.AssetInputEntityData; @@ -14,10 +16,9 @@ import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.*; import edu.ie3.datamodel.models.result.ResultEntity; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.*; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.LongAdder; -import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import org.slf4j.Logger; @@ -38,50 +39,16 @@ public abstract class EntitySource { // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - /** - * Returns a predicate that can be used to filter optionals of {@link UniqueEntity}s and keep - * track on the number of elements that have been empty optionals. This filter let only pass - * optionals that are non-empty. Example usage: - * - *
{@code
-   * Collection.stream().filter(isPresentCollectIfNot(NodeInput.class, new ConcurrentHashMap<>()))
-   * }
- * - * @param entityClass entity class that should be used as they key in the provided counter map - * @param invalidElementsCounterMap a map that counts the number of empty optionals and maps it to - * the provided entity clas - * @param the type of the entity - * @return a predicate that can be used to filter and count empty optionals - */ - protected Predicate> isPresentCollectIfNot( - Class entityClass, - ConcurrentMap, LongAdder> invalidElementsCounterMap) { - return o -> { - if (o.isPresent()) { - return true; - } else { - invalidElementsCounterMap.computeIfAbsent(entityClass, k -> new LongAdder()).increment(); - return false; - } - }; - } - - protected void printInvalidElementInformation( - Class entityClass, LongAdder noOfInvalidElements) { - log.error( - "{} entities of type '{}' are missing required elements!", - noOfInvalidElements, - entityClass.getSimpleName()); - } - - protected void logSkippingWarning( + protected String buildSkippingMessage( String entityDesc, String entityUuid, String entityId, String missingElementsString) { - log.warn( - "Skipping '{}' with uuid '{}' and id '{}'. Not all required entities found or map is missing entity key!\nMissing elements:\n{}", - entityDesc, - entityUuid, - entityId, - missingElementsString); + return "Skipping " + + entityDesc + + " with uuid " + + entityUuid + + " and id " + + entityId + + ". Not all required entities found or map is missing entity key!\nMissing elements:\n" + + missingElementsString; } protected String safeMapGet(Map map, String key, String mapName) { @@ -115,16 +82,16 @@ protected Optional findFirstEntityByUuid( * Checks if the requested type of an asset can be found in the provided collection of types based * on the provided fields to values mapping. The provided fields to values mapping needs to have * one and only one field with key {@link #TYPE} and a corresponding UUID value. If the type can - * be found in the provided collection based on the UUID it is returned wrapped in an optional. - * Otherwise an empty optional is returned and a warning is logged. + * be found in the provided collection based on the UUID it is returned wrapped in a {@link + * Success}. Otherwise a {@link Failure} is returned and a warning is logged. * * @param types a collection of types that should be used for searching * @param fieldsToAttributes the field name to value mapping incl. the key {@link #TYPE} * @param skippedClassString debug string of the class that will be skipping * @param the type of the resulting type instance - * @return either an optional containing the type or an empty optional if the type cannot be found + * @return a {@link Success} containing the type or a {@link Failure} if the type cannot be found */ - protected Optional getAssetType( + protected Try getAssetType( Collection types, Map fieldsToAttributes, String skippedClassString) { Optional assetType = @@ -134,13 +101,15 @@ protected Optional getAssetType( // if the type is not present we return an empty element and // log a warning if (assetType.isEmpty()) { - logSkippingWarning( - skippedClassString, - safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), - safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), - TYPE + ": " + safeMapGet(fieldsToAttributes, TYPE, FIELDS_TO_VALUES_MAP)); + String skippingMessage = + buildSkippingMessage( + skippedClassString, + safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), + safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), + TYPE + ": " + safeMapGet(fieldsToAttributes, TYPE, FIELDS_TO_VALUES_MAP)); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } - return assetType; + return new Success<>(assetType.get()); } /** @@ -149,11 +118,12 @@ protected Optional getAssetType( * @param untypedEntityData Untyped entity data to enrich * @param availableTypes Yet available asset types * @param Type of the asset type - * @return Option to enhanced data + * @return {@link Try} to enhanced data */ - protected Optional> findAndAddType( - ConnectorInputEntityData untypedEntityData, Collection availableTypes) { - Optional assetTypeOption = + protected + Try, SourceException> findAndAddType( + ConnectorInputEntityData untypedEntityData, Collection availableTypes) { + Try assetTypeOption = getAssetType( availableTypes, untypedEntityData.getFieldsToValues(), @@ -224,17 +194,16 @@ protected OperatorInput getFirstOrDefaultOperator( } /** - * Returns a stream of optional {@link NodeAssetInputEntityData} that can be used to build + * Returns a stream of tries of {@link NodeAssetInputEntityData} that can be used to build * instances of several subtypes of {@link UniqueEntity} by a corresponding {@link EntityFactory} * that consumes this data. param assetInputEntityDataStream * * @param assetInputEntityDataStream a stream consisting of {@link AssetInputEntityData} that is * enriched with {@link NodeInput} data * @param nodes a collection of {@link NodeInput} entities that should be used to build the data - * @return stream of optionals of the entity data or empty optionals of the node required for the - * data cannot be found + * @return stream of the entity data wrapped in a {@link Try} */ - protected Stream> nodeAssetInputEntityDataStream( + protected Stream> nodeAssetInputEntityDataStream( Stream assetInputEntityDataStream, Collection nodes) { return assetInputEntityDataStream .parallel() @@ -249,18 +218,19 @@ protected Stream> nodeAssetInputEntityDataStr // if the node is not present we return an empty element and // log a warning if (node.isEmpty()) { - logSkippingWarning( - assetInputEntityData.getTargetClass().getSimpleName(), - fieldsToAttributes.get("uuid"), - fieldsToAttributes.get("id"), - NODE + ": " + nodeUuid); - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + assetInputEntityData.getTargetClass().getSimpleName(), + fieldsToAttributes.get("uuid"), + fieldsToAttributes.get("id"), + NODE + ": " + nodeUuid); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor fieldsToAttributes.keySet().remove(NODE); - return Optional.of( + return new Success<>( new NodeAssetInputEntityData( fieldsToAttributes, assetInputEntityData.getTargetClass(), @@ -278,8 +248,7 @@ protected Stream> nodeAssetInputEntityDataStr * @param operators a collection of {@link OperatorInput} entities that should be used to build * the data * @param type of the entity that should be build - * @return stream of optionals of the entity data or empty optionals of the operator required for - * the data cannot be found + * @return stream of the entity data wrapped in a {@link Try} */ protected Stream assetInputEntityDataStream( Class entityClass, Collection operators) { @@ -325,7 +294,7 @@ protected Stream simpleEntityDataStre .map(fieldsToAttributes -> new SimpleEntityData(fieldsToAttributes, entityClass)); } - protected Stream> assetInputEntityStream( + protected Stream> assetInputEntityStream( Class entityClass, EntityFactory factory, Collection operators) { @@ -333,7 +302,7 @@ protected Stream> assetInputEntityStream( } /** - * Returns a stream of optional entities that can be build by using {@link + * Returns a stream of {@link Try} entities that can be build by using {@link * NodeAssetInputEntityData} and their corresponding factory. * * @param entityClass the entity class that should be build @@ -343,61 +312,45 @@ protected Stream> assetInputEntityStream( * @param operators a collection of {@link OperatorInput} entities should be used to build the * entities * @param Type of the {@link AssetInput} to expect - * @return stream of optionals of the entities that has been built by the factor or empty - * optionals if the entity could not have been build + * @return stream of tries of the entities that has been built by the factory */ - protected Stream> nodeAssetEntityStream( + protected Stream> nodeAssetEntityStream( Class entityClass, EntityFactory factory, Collection nodes, Collection operators) { return nodeAssetInputEntityDataStream(assetInputEntityDataStream(entityClass, operators), nodes) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - public Set buildNodeAssetEntities( - Class entityClass, - EntityFactory factory, - Collection nodes, - Collection operators, - ConcurrentMap, LongAdder> nonBuildEntities) { - return nodeAssetEntityStream(entityClass, factory, nodes, operators) - .filter(isPresentCollectIfNot(entityClass, nonBuildEntities)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - public Set buildNodeAssetEntities( + public Set> buildNodeAssetEntities( Class entityClass, EntityFactory factory, Collection nodes, Collection operators) { return nodeAssetEntityStream(entityClass, factory, nodes, operators) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } - public Set buildAssetInputEntities( + public Set> buildAssetInputEntities( Class entityClass, EntityFactory factory, Collection operators) { - return assetInputEntityStream(entityClass, factory, operators) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); + return assetInputEntityStream(entityClass, factory, operators).collect(Collectors.toSet()); } - public Set buildEntities( + @SuppressWarnings("unchecked") + public Set> buildEntities( Class entityClass, EntityFactory factory) { return dataSource .getSourceData(entityClass) .map( fieldsToAttributes -> { SimpleEntityData data = new SimpleEntityData(fieldsToAttributes, entityClass); - return (Optional) factory.get(data); + return (Try) factory.get(data); }) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/GraphicSource.java b/src/main/java/edu/ie3/datamodel/io/source/GraphicSource.java index 8bc0c0e60..7cdc097ca 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/GraphicSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/GraphicSource.java @@ -5,30 +5,29 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.GraphicSourceException; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputEntityData; import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputFactory; import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputEntityData; import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputFactory; -import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.NodeInput; import edu.ie3.datamodel.models.input.OperatorInput; import edu.ie3.datamodel.models.input.connector.LineInput; import edu.ie3.datamodel.models.input.connector.type.LineTypeInput; import edu.ie3.datamodel.models.input.container.GraphicElements; +import edu.ie3.datamodel.models.input.graphics.GraphicInput; import edu.ie3.datamodel.models.input.graphics.LineGraphicInput; import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.LongAdder; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; /** - * Interface that provides the capability to build entities of type {@link - * edu.ie3.datamodel.models.input.graphics.GraphicInput} from different data sources e.g. .csv files - * or databases + * Implementation that provides the capability to build entities of type {@link GraphicInput} from + * different data sources e.g. .csv files or databases * * @version 0.1 * @since 08.04.20 @@ -51,8 +50,8 @@ public GraphicSource(TypeSource typeSource, RawGridSource rawGridSource, DataSou this.nodeGraphicInputFactory = new NodeGraphicInputFactory(); } - /** Returns the graphic elements of the grid as a option */ - public Optional getGraphicElements() { + /** Returns the graphic elements of the grid or throws a {@link SourceException} */ + public GraphicElements getGraphicElements() throws SourceException { // read all needed entities /// start with types and operators @@ -62,68 +61,64 @@ public Optional getGraphicElements() { Set nodes = rawGridSource.getNodes(operators); Set lines = rawGridSource.getLines(nodes, lineTypes, operators); - // start with the entities needed for a GraphicElements entity - /// as we want to return a working grid, keep an eye on empty optionals - ConcurrentHashMap, LongAdder> nonBuildEntities = - new ConcurrentHashMap<>(); - - Set nodeGraphics = - buildNodeGraphicEntityData(nodes) - .map(dataOpt -> dataOpt.flatMap(nodeGraphicInputFactory::get)) - .filter(isPresentCollectIfNot(NodeGraphicInput.class, nonBuildEntities)) - .map(Optional::get) - .collect(Collectors.toSet()); - - Set lineGraphics = - buildLineGraphicEntityData(lines) - .map(dataOpt -> dataOpt.flatMap(lineGraphicInputFactory::get)) - .filter(isPresentCollectIfNot(LineGraphicInput.class, nonBuildEntities)) - .map(Optional::get) - .collect(Collectors.toSet()); - - // if we found invalid elements return an empty optional and log the problems - if (!nonBuildEntities.isEmpty()) { - nonBuildEntities.forEach(this::printInvalidElementInformation); - return Optional.empty(); + Try, SourceException> nodeGraphics = + Try.of(() -> getNodeGraphicInput(nodes), SourceException.class); + Try, SourceException> lineGraphics = + Try.of(() -> getLineGraphicInput(lines), SourceException.class); + + List exceptions = Try.getExceptions(List.of(nodeGraphics, lineGraphics)); + + if (!exceptions.isEmpty()) { + throw new GraphicSourceException( + exceptions.size() + "error(s) occurred while initializing graphic elements. ", + exceptions); + } else { + // if everything is fine, return a GraphicElements instance + // getOrThrow should not throw an exception in this context, because all exception are + // filtered and thrown before + return new GraphicElements(nodeGraphics.getOrThrow(), lineGraphics.getOrThrow()); } - - // if everything is fine, return a GraphicElements instance - return Optional.of(new GraphicElements(nodeGraphics, lineGraphics)); } /** * If the set of {@link NodeInput} entities is not exhaustive for all available {@link - * NodeGraphicInput} entities or if an error during the building process occurs, all entities that - * has been able to be built are returned and the not-built ones are ignored (= filtered out). + * NodeGraphicInput} entities or if an error during the building process occurs a {@link + * SourceException} is thrown, else all entities that has been able to be built are returned. */ - public Set getNodeGraphicInput() { + public Set getNodeGraphicInput() throws SourceException { return getNodeGraphicInput(rawGridSource.getNodes(typeSource.getOperators())); } - public Set getNodeGraphicInput(Set nodes) { - return buildNodeGraphicEntityData(nodes) - .map(dataOpt -> dataOpt.flatMap(nodeGraphicInputFactory::get)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); + public Set getNodeGraphicInput(Set nodes) throws SourceException { + return Try.scanCollection( + buildNodeGraphicEntityData(nodes) + .map(nodeGraphicInputFactory::get) + .collect(Collectors.toSet()), + NodeGraphicInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** * If the set of {@link LineInput} entities is not exhaustive for all available {@link - * LineGraphicInput} entities or if an error during the building process occurs, all entities that - * has been able to be built are returned and the not-built ones are ignored (= filtered out). + * LineGraphicInput} entities or if an error during the building process occurs a {@link + * SourceException} is thrown, else all entities that has been able to be built are returned. */ - public Set getLineGraphicInput() { + public Set getLineGraphicInput() throws SourceException { Set operators = typeSource.getOperators(); return getLineGraphicInput( rawGridSource.getLines( rawGridSource.getNodes(operators), typeSource.getLineTypes(), operators)); } - public Set getLineGraphicInput(Set lines) { - return buildLineGraphicEntityData(lines) - .map(dataOpt -> dataOpt.flatMap(lineGraphicInputFactory::get)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); + public Set getLineGraphicInput(Set lines) throws SourceException { + return Try.scanCollection( + buildLineGraphicEntityData(lines) + .map(lineGraphicInputFactory::get) + .collect(Collectors.toSet()), + LineGraphicInput.class) + .transformF(SourceException::new) + .getOrThrow(); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -138,41 +133,42 @@ public Set getLineGraphicInput(Set lines) { * NodeInput} entity. Hence it is crucial to only pass over collections that are pre-checked for * the uniqueness of the UUIDs of the nodes they contain. No further sanity checks are included in * this method. If no UUID of a {@link NodeInput} entity can be found for a {@link - * NodeGraphicInputEntityData} instance, an empty optional is included in the stream and warning + * NodeGraphicInputEntityData} instance, a {@link Failure} is included in the stream and warning * is logged. * * @param nodes a set of nodes with unique uuids - * @return a stream of optional {@link NodeGraphicInput} entities + * @return a stream of tries of {@link NodeGraphicInput} entities */ - protected Stream> buildNodeGraphicEntityData( + protected Stream> buildNodeGraphicEntityData( Set nodes) { return dataSource .getSourceData(NodeGraphicInput.class) .map(fieldsToAttributes -> buildNodeGraphicEntityData(fieldsToAttributes, nodes)); } - protected Optional buildNodeGraphicEntityData( + protected Try buildNodeGraphicEntityData( Map fieldsToAttributes, Set nodes) { // get the node of the entity String nodeUuid = fieldsToAttributes.get(NODE); Optional node = findFirstEntityByUuid(nodeUuid, nodes); - // if the node is not present we return an empty element and + // if the node is not present we return a failure // log a warning if (node.isEmpty()) { - logSkippingWarning( - NodeGraphicInput.class.getSimpleName(), - fieldsToAttributes.get("uuid"), - "no id (graphic entities don't have one)", - NODE + ": " + nodeUuid); - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + NodeGraphicInput.class.getSimpleName(), + fieldsToAttributes.get("uuid"), + "no id (graphic entities don't have one)", + NODE + ": " + nodeUuid); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor fieldsToAttributes.keySet().remove(NODE); - return Optional.of(new NodeGraphicInputEntityData(fieldsToAttributes, node.get())); + return new Success<>(new NodeGraphicInputEntityData(fieldsToAttributes, node.get())); } /** @@ -184,20 +180,20 @@ protected Optional buildNodeGraphicEntityData( * LineInput} entity. Hence it is crucial to only pass over collections that are pre-checked for * the uniqueness of the UUIDs of the nodes they contain. No further sanity checks are included in * this method. If no UUID of a {@link LineInput} entity can be found for a {@link - * LineGraphicInputEntityData} instance, an empty optional is included in the stream and warning + * LineGraphicInputEntityData} instance, a {@link Failure} is included in the stream and warning * is logged. * * @param lines a set of lines with unique uuids - * @return a stream of optional {@link LineGraphicInput} entities + * @return a stream of tries of {@link LineGraphicInput} entities */ - protected Stream> buildLineGraphicEntityData( + protected Stream> buildLineGraphicEntityData( Set lines) { return dataSource .getSourceData(LineGraphicInput.class) .map(fieldsToAttributes -> buildLineGraphicEntityData(fieldsToAttributes, lines)); } - protected Optional buildLineGraphicEntityData( + protected Try buildLineGraphicEntityData( Map fieldsToAttributes, Set lines) { // get the node of the entity @@ -207,17 +203,18 @@ protected Optional buildLineGraphicEntityData( // if the node is not present we return an empty element and // log a warning if (line.isEmpty()) { - logSkippingWarning( - LineGraphicInput.class.getSimpleName(), - fieldsToAttributes.get("uuid"), - "no id (graphic entities don't have one)", - "line: " + lineUuid); - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + LineGraphicInput.class.getSimpleName(), + fieldsToAttributes.get("uuid"), + "no id (graphic entities don't have one)", + "line: " + lineUuid); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor fieldsToAttributes.keySet().remove("line"); - return Optional.of(new LineGraphicInputEntityData(fieldsToAttributes, line.get())); + return new Success<>(new LineGraphicInputEntityData(fieldsToAttributes, line.get())); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/RawGridSource.java b/src/main/java/edu/ie3/datamodel/io/source/RawGridSource.java index 3df06f41c..b06d55d4d 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/RawGridSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/RawGridSource.java @@ -5,24 +5,33 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.exceptions.RawGridException; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.input.*; -import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.*; +import edu.ie3.datamodel.models.input.MeasurementUnitInput; +import edu.ie3.datamodel.models.input.NodeInput; +import edu.ie3.datamodel.models.input.OperatorInput; import edu.ie3.datamodel.models.input.connector.*; +import edu.ie3.datamodel.models.input.connector.LineInput; +import edu.ie3.datamodel.models.input.connector.SwitchInput; +import edu.ie3.datamodel.models.input.connector.Transformer2WInput; +import edu.ie3.datamodel.models.input.connector.Transformer3WInput; import edu.ie3.datamodel.models.input.connector.type.LineTypeInput; import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput; import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput; import edu.ie3.datamodel.models.input.container.RawGridElements; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.LongAdder; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; /** - * Interface that provides the capability to build entities that are hold by a {@link + * Implementation that provides the capability to build entities that are hold by a {@link * RawGridElements} as well as the {@link RawGridElements} container as well from different data * sources e.g. .csv files or databases. * @@ -61,14 +70,14 @@ public RawGridSource(TypeSource typeSource, DataSource dataSource) { } /** - * Should return either a consistent instance of {@link RawGridElements} wrapped in {@link - * Optional} or an empty {@link Optional}. The decision to use {@link Optional} instead of - * returning the {@link RawGridElements} instance directly is motivated by the fact, that a {@link + * Should return either a consistent instance of {@link RawGridElements} or throw a {@link + * SourceException}. The decision to throw a {@link SourceException} instead of returning the + * incomplete {@link RawGridElements} instance is motivated by the fact, that a {@link * RawGridElements} is a container instance that depends on several other entities. Without being * complete, it is useless for further processing. * *

Hence, whenever at least one entity {@link RawGridElements} depends on cannot be provided, - * {@link Optional#empty()} should be returned and extensive logging should provide enough + * {@link SourceException} should be thrown. The thrown exception should provide enough * information to debug the error and fix the persistent data that has been failed to processed. * *

Furthermore, it is expected, that the specific implementation of this method ensures not @@ -76,9 +85,9 @@ public RawGridSource(TypeSource typeSource, DataSource dataSource) { * e.g. in the sense that not duplicate UUIDs exist within all entities contained in the returning * instance. * - * @return either a valid, complete {@link RawGridElements} optional or {@link Optional#empty()} + * @return either a valid, complete {@link RawGridElements} or throws a {@link SourceException} */ - public Optional getGridData() { + public RawGridElements getGridData() throws SourceException { /* read all needed entities start with the types and operators */ Set operators = typeSource.getOperators(); Set lineTypes = typeSource.getLineTypes(); @@ -87,59 +96,41 @@ public Optional getGridData() { /* assets */ Set nodes = getNodes(operators); - - /* start with the entities needed for a RawGridElement as we want to return a working grid, keep an eye on empty - * optionals which is equal to elements that have been unable to be built e.g. due to missing elements they depend - * on - */ - ConcurrentHashMap, LongAdder> nonBuildEntities = - new ConcurrentHashMap<>(); - - Set lineInputs = - buildTypedEntities( - LineInput.class, lineInputFactory, nodes, operators, lineTypes, nonBuildEntities); - Set transformer2WInputs = - buildTypedEntities( - Transformer2WInput.class, - transformer2WInputFactory, - nodes, - operators, - transformer2WTypeInputs, - nonBuildEntities); - Set transformer3WInputs = - buildTransformer3WEntities( - transformer3WInputFactory, nodes, transformer3WTypeInputs, operators); - Set switches = - buildUntypedConnectorInputEntities( - SwitchInput.class, switchInputFactory, nodes, operators, nonBuildEntities); - Set measurementUnits = - buildNodeAssetEntities( - MeasurementUnitInput.class, - measurementUnitInputFactory, - nodes, - operators, - nonBuildEntities); - - /* if we found non-build elements return an empty optional and log the problems */ - if (!nonBuildEntities.isEmpty()) { - nonBuildEntities.forEach(this::printInvalidElementInformation); - return Optional.empty(); + Try, SourceException> lineInputs = + Try.of(() -> getLines(nodes, lineTypes, operators), SourceException.class); + Try, SourceException> transformer2WInputs = + Try.of( + () -> get2WTransformers(nodes, transformer2WTypeInputs, operators), + SourceException.class); + Try, SourceException> transformer3WInputs = + Try.of( + () -> get3WTransformers(nodes, transformer3WTypeInputs, operators), + SourceException.class); + Try, SourceException> switches = + Try.of(() -> getSwitches(nodes, operators), SourceException.class); + Try, SourceException> measurementUnits = + Try.of(() -> getMeasurementUnits(nodes, operators), SourceException.class); + + List exceptions = + Try.getExceptions( + List.of( + lineInputs, transformer2WInputs, transformer3WInputs, switches, measurementUnits)); + + if (!exceptions.isEmpty()) { + throw new RawGridException( + exceptions.size() + " error(s) occurred while initializing raw grid. ", exceptions); + } else { + /* build and return the grid if it is not empty */ + // getOrThrow should not throw an exception in this context, because all exception are + // filtered and thrown before + return new RawGridElements( + nodes, + lineInputs.getOrThrow(), + transformer2WInputs.getOrThrow(), + transformer3WInputs.getOrThrow(), + switches.getOrThrow(), + measurementUnits.getOrThrow()); } - - // build the grid - RawGridElements gridElements = - new RawGridElements( - nodes, - lineInputs, - transformer2WInputs, - transformer3WInputs, - switches, - measurementUnits); - - // return the grid if it is not empty - return gridElements.allEntitiesAsList().isEmpty() - ? Optional.empty() - : Optional.of(gridElements); } /** @@ -151,7 +142,7 @@ public Optional getGridData() { * * @return a set of object and uuid unique {@link NodeInput} entities */ - public Set getNodes() { + public Set getNodes() throws SourceException { return getNodes(typeSource.getOperators()); } @@ -161,20 +152,26 @@ public Set getNodes() { * NodeInput} which has to be checked manually, as {@link NodeInput#equals(Object)} is NOT * restricted on the uuid of {@link NodeInput}. * - *

In contrast to {@link #getNodes} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes} this method provides the ability to pass in an already * existing set of {@link OperatorInput} entities, the {@link NodeInput} instances depend on. * Doing so, already loaded nodes can be recycled to improve performance and prevent unnecessary * loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @return a set of object and uuid unique {@link NodeInput} entities */ - public Set getNodes(Set operators) { - return buildNodeInputEntities(NodeInput.class, nodeInputFactory, operators); + public Set getNodes(Set operators) throws SourceException { + return Try.scanCollection( + assetInputEntityDataStream(NodeInput.class, operators) + .map(nodeInputFactory::get) + .collect(Collectors.toSet()), + NodeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -186,7 +183,7 @@ public Set getNodes(Set operators) { * * @return a set of object and uuid unique {@link LineInput} entities */ - public Set getLines() { + public Set getLines() throws SourceException { Set operators = typeSource.getOperators(); return getLines(getNodes(operators), typeSource.getLineTypes(), operators); } @@ -197,13 +194,13 @@ public Set getLines() { * LineInput} which has to be checked manually, as {@link LineInput#equals(Object)} is NOT * restricted on the uuid of {@link LineInput}. * - *

In contrast to {@link #getNodes} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes} this method provides the ability to pass in an already * existing set of {@link NodeInput}, {@link LineTypeInput} and {@link OperatorInput} entities, * the {@link LineInput} instances depend on. Doing so, already loaded nodes, line types and * operators can be recycled to improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -212,8 +209,14 @@ public Set getLines() { * @return a set of object and uuid unique {@link LineInput} entities */ public Set getLines( - Set nodes, Set lineTypeInputs, Set operators) { - return buildTypedEntities(LineInput.class, lineInputFactory, nodes, operators, lineTypeInputs); + Set nodes, Set lineTypeInputs, Set operators) + throws SourceException { + return Try.scanCollection( + typedEntityStream(LineInput.class, lineInputFactory, nodes, operators, lineTypeInputs) + .collect(Collectors.toSet()), + LineInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -226,7 +229,7 @@ public Set getLines( * * @return a set of object and uuid unique {@link Transformer2WInput} entities */ - public Set get2WTransformers() { + public Set get2WTransformers() throws SourceException { Set operators = typeSource.getOperators(); return get2WTransformers(getNodes(operators), typeSource.getTransformer2WTypes(), operators); } @@ -237,14 +240,14 @@ public Set get2WTransformers() { * {@link Transformer2WInput} which has to be checked manually, as {@link * Transformer2WInput#equals(Object)} is NOT restricted on the uuid of {@link Transformer2WInput}. * - *

In contrast to {@link #getNodes()} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes()} this method provides the ability to pass in an already * existing set of {@link NodeInput}, {@link Transformer2WTypeInput} and {@link OperatorInput} * entities, the {@link Transformer2WInput} instances depend on. Doing so, already loaded nodes, * line types and operators can be recycled to improve performance and prevent unnecessary loading * operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -256,9 +259,19 @@ public Set get2WTransformers() { public Set get2WTransformers( Set nodes, Set transformer2WTypes, - Set operators) { - return buildTypedEntities( - Transformer2WInput.class, transformer2WInputFactory, nodes, operators, transformer2WTypes); + Set operators) + throws SourceException { + return Try.scanCollection( + typedEntityStream( + Transformer2WInput.class, + transformer2WInputFactory, + nodes, + operators, + transformer2WTypes) + .collect(Collectors.toSet()), + Transformer2WInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -271,7 +284,7 @@ public Set get2WTransformers( * * @return a set of object and uuid unique {@link Transformer3WInput} entities */ - public Set get3WTransformers() { + public Set get3WTransformers() throws SourceException { Set operators = typeSource.getOperators(); return get3WTransformers(getNodes(operators), typeSource.getTransformer3WTypes(), operators); } @@ -282,14 +295,14 @@ public Set get3WTransformers() { * {@link Transformer3WInput} which has to be checked manually, as {@link * Transformer3WInput#equals(Object)} is NOT restricted on the uuid of {@link Transformer3WInput}. * - *

In contrast to {@link #getNodes()} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes()} this method provides the ability to pass in an already * existing set of {@link NodeInput}, {@link Transformer3WTypeInput} and {@link OperatorInput} * entities, the {@link Transformer3WInput} instances depend on. Doing so, already loaded nodes, * line types and operators can be recycled to improve performance and prevent unnecessary loading * operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -301,9 +314,14 @@ public Set get3WTransformers() { public Set get3WTransformers( Set nodes, Set transformer3WTypeInputs, - Set operators) { - return buildTransformer3WEntities( - transformer3WInputFactory, nodes, transformer3WTypeInputs, operators); + Set operators) + throws SourceException { + return Try.scanCollection( + buildTransformer3WEntities( + transformer3WInputFactory, nodes, transformer3WTypeInputs, operators), + Transformer3WInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -316,7 +334,7 @@ public Set get3WTransformers( * * @return a set of object and uuid unique {@link SwitchInput} entities */ - public Set getSwitches() { + public Set getSwitches() throws SourceException { Set operators = typeSource.getOperators(); return getSwitches(getNodes(operators), operators); } @@ -327,20 +345,21 @@ public Set getSwitches() { * {@link SwitchInput} which has to be checked manually, as {@link SwitchInput#equals(Object)} is * NOT restricted on the uuid of {@link SwitchInput}. * - *

In contrast to {@link #getNodes()} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes()} this method provides the ability to pass in an already * existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link SwitchInput} * instances depend on. Doing so, already loaded nodes, line types and operators can be recycled * to improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link SwitchInput} entities */ - public Set getSwitches(Set nodes, Set operators) { + public Set getSwitches(Set nodes, Set operators) + throws SourceException { return buildUntypedConnectorInputEntities( SwitchInput.class, switchInputFactory, nodes, operators); } @@ -355,7 +374,7 @@ public Set getSwitches(Set nodes, Set ope * * @return a set of object and uuid unique {@link MeasurementUnitInput} entities */ - public Set getMeasurementUnits() { + public Set getMeasurementUnits() throws SourceException { Set operators = typeSource.getOperators(); return getMeasurementUnits(getNodes(operators), operators); } @@ -367,13 +386,13 @@ public Set getMeasurementUnits() { * MeasurementUnitInput#equals(Object)} is NOT restricted on the uuid of {@link * MeasurementUnitInput}. * - *

In contrast to {@link #getNodes()} this interface provides the ability to pass in an already + *

In contrast to {@link #getNodes()} this method provides the ability to pass in an already * existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link * MeasurementUnitInput} instances depend on. Doing so, already loaded nodes, line types and * operators can be recycled to improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -381,31 +400,22 @@ public Set getMeasurementUnits() { * @return a set of object and uuid unique {@link MeasurementUnitInput} entities */ public Set getMeasurementUnits( - Set nodes, Set operators) { - return buildNodeAssetEntities( - MeasurementUnitInput.class, measurementUnitInputFactory, nodes, operators); + Set nodes, Set operators) throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities( + MeasurementUnitInput.class, measurementUnitInputFactory, nodes, operators), + MeasurementUnitInput.class) + .transformF(SourceException::new) + .getOrThrow(); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - public Set buildNodeInputEntities( + public Set> buildNodeInputEntities( Class entityClass, EntityFactory factory, Collection operators) { return assetInputEntityDataStream(entityClass, operators) .map(factory::get) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - public Set buildUntypedConnectorInputEntities( - Class entityClass, - EntityFactory factory, - Collection nodes, - Collection operators, - ConcurrentMap, LongAdder> nonBuildEntities) { - return untypedConnectorInputEntityStream(entityClass, factory, nodes, operators) - .filter(isPresentCollectIfNot(entityClass, nonBuildEntities)) - .map(Optional::get) .collect(Collectors.toSet()); } @@ -413,13 +423,17 @@ public Set buildUntypedConnectorInputEntities( Class entityClass, EntityFactory factory, Collection nodes, - Collection operators) { - return untypedConnectorInputEntityStream(entityClass, factory, nodes, operators) - .map(Optional::get) - .collect(Collectors.toSet()); + Collection operators) + throws SourceException { + return Try.scanCollection( + untypedConnectorInputEntityStream(entityClass, factory, nodes, operators) + .collect(Collectors.toSet()), + entityClass) + .transformF(SourceException::new) + .getOrThrow(); } - public Set buildTransformer3WEntities( + public Set> buildTransformer3WEntities( Transformer3WInputFactory transformer3WInputFactory, Collection nodes, Collection transformer3WTypeInputs, @@ -430,47 +444,33 @@ public Set buildTransformer3WEntities( assetInputEntityDataStream(Transformer3WInput.class, operators), nodes), transformer3WTypeInputs), nodes) - .map(dataOpt -> dataOpt.flatMap(transformer3WInputFactory::get)) - .flatMap(Optional::stream) + .map(transformer3WInputFactory::get) .collect(Collectors.toSet()); } - public Set buildTypedEntities( - Class entityClass, - EntityFactory> factory, - Collection nodes, - Collection operators, - Collection types, - ConcurrentMap, LongAdder> nonBuildEntities) { - return typedEntityStream(entityClass, factory, nodes, operators, types) - .filter(isPresentCollectIfNot(entityClass, nonBuildEntities)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - public Set buildTypedEntities( - Class entityClass, - EntityFactory> factory, - Collection nodes, - Collection operators, - Collection types) { + public + Set> buildTypedEntities( + Class entityClass, + EntityFactory> factory, + Collection nodes, + Collection operators, + Collection types) { return typedEntityStream(entityClass, factory, nodes, operators, types) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } /** * Enriches the given untyped entity data with the equivalent asset type. If this is not possible, - * an empty Optional is returned + * a {@link Failure} is returned. * * @param noTypeConnectorEntityDataStream Stream of untyped entity data * @param availableTypes Yet available asset types * @param Type of the asset type - * @return Stream of option to enhanced data + * @return Stream of {@link Try} to enhanced data */ protected - Stream>> buildTypedConnectorEntityData( - Stream> noTypeConnectorEntityDataStream, + Stream, SourceException>> buildTypedConnectorEntityData( + Stream> noTypeConnectorEntityDataStream, Collection availableTypes) { return noTypeConnectorEntityDataStream .parallel() @@ -486,10 +486,11 @@ Stream>> buildTypedConnectorEntityData * * @param assetInputEntityDataStream Input stream of {@link AssetInputEntityData} * @param nodes A collection of known nodes - * @return A stream on option to matching {@link ConnectorInputEntityData} + * @return A stream on {@link Try} to matching {@link ConnectorInputEntityData} */ - protected Stream> buildUntypedConnectorInputEntityData( - Stream assetInputEntityDataStream, Collection nodes) { + protected Stream> + buildUntypedConnectorInputEntityData( + Stream assetInputEntityDataStream, Collection nodes) { return assetInputEntityDataStream .parallel() .map( @@ -499,14 +500,14 @@ protected Stream> buildUntypedConnectorInputE /** * Converts a single given {@link AssetInputEntityData} in connection with a collection of known - * {@link NodeInput}s to {@link ConnectorInputEntityData}. If this is not possible, an empty - * option is given back. + * {@link NodeInput}s to {@link ConnectorInputEntityData}. If this is not possible, a {@link + * Failure}. * * @param assetInputEntityData Input entity data to convert * @param nodes A collection of known nodes - * @return An option to matching {@link ConnectorInputEntityData} + * @return A {@link Try} to matching {@link ConnectorInputEntityData} */ - protected Optional buildUntypedConnectorInputEntityData( + protected Try buildUntypedConnectorInputEntityData( AssetInputEntityData assetInputEntityData, Collection nodes) { // get the raw data Map fieldsToAttributes = assetInputEntityData.getFieldsToValues(); @@ -517,7 +518,7 @@ protected Optional buildUntypedConnectorInputEntityDat Optional nodeA = findFirstEntityByUuid(nodeAUuid, nodes); Optional nodeB = findFirstEntityByUuid(nodeBUuid, nodes); - // if nodeA or nodeB are not present we return an empty element and log a + // if nodeA or nodeB are not present we return a failure and log a // warning if (nodeA.isEmpty() || nodeB.isEmpty()) { String debugString = @@ -528,18 +529,20 @@ protected Optional buildUntypedConnectorInputEntityDat .map(AbstractMap.SimpleEntry::getValue) .collect(Collectors.joining("\n")); - logSkippingWarning( - assetInputEntityData.getTargetClass().getSimpleName(), - fieldsToAttributes.get("uuid"), - fieldsToAttributes.get("id"), - debugString); - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + assetInputEntityData.getTargetClass().getSimpleName(), + fieldsToAttributes.get("uuid"), + fieldsToAttributes.get("id"), + debugString); + + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor fieldsToAttributes.keySet().removeAll(new HashSet<>(Arrays.asList(NODE_A, NODE_B))); - return Optional.of( + return new Success<>( new ConnectorInputEntityData( fieldsToAttributes, assetInputEntityData.getTargetClass(), @@ -549,7 +552,7 @@ protected Optional buildUntypedConnectorInputEntityDat } private - Stream> typedEntityStream( + Stream> typedEntityStream( Class entityClass, EntityFactory> factory, Collection nodes, @@ -559,38 +562,40 @@ Stream> typedEntityStream( buildUntypedConnectorInputEntityData( assetInputEntityDataStream(entityClass, operators), nodes), types) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } - public Stream> untypedConnectorInputEntityStream( - Class entityClass, - EntityFactory factory, - Set nodes, - Set operators) { + public + Stream> untypedConnectorInputEntityStream( + Class entityClass, + EntityFactory factory, + Set nodes, + Set operators) { return buildUntypedConnectorInputEntityData( assetInputEntityDataStream(entityClass, operators), nodes) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } - private Stream> untypedConnectorInputEntityStream( - Class entityClass, - EntityFactory factory, - Collection nodes, - Collection operators) { + private + Stream> untypedConnectorInputEntityStream( + Class entityClass, + EntityFactory factory, + Collection nodes, + Collection operators) { return untypedConnectorInputEntityStream( - entityClass, factory, new HashSet(nodes), new HashSet(operators)); + entityClass, factory, new HashSet<>(nodes), new HashSet<>(operators)); } /** - * Enriches the Stream of options on {@link Transformer3WInputEntityData} with the information of - * the internal node + * Enriches the Stream of tries on {@link Transformer3WInputEntityData} with the information of + * the internal node. * * @param typedConnectorEntityDataStream Stream of already typed input entity data * @param nodes Yet available nodes - * @return A stream of options on enriched data + * @return A stream of {@link Try} on enriched data */ - protected Stream> buildTransformer3WEntityData( - Stream>> + protected Stream> buildTransformer3WEntityData( + Stream, SourceException>> typedConnectorEntityDataStream, Collection nodes) { return typedConnectorEntityDataStream @@ -602,13 +607,13 @@ protected Stream> buildTransformer3WEntit /** * Enriches the third node to the already typed entity data of a three winding transformer. If no - * matching node can be found, return an empty Optional. + * matching node can be found, return a {@link Failure}. * * @param typeEntityData Already typed entity data * @param nodes Yet available nodes - * @return An option to the enriched data + * @return a {@link Try} to the enriched data */ - protected Optional addThirdNode( + protected Try addThirdNode( TypedConnectorInputEntityData typeEntityData, Collection nodes) { @@ -619,21 +624,22 @@ protected Optional addThirdNode( String nodeCUuid = fieldsToAttributes.get("nodeC"); Optional nodeC = findFirstEntityByUuid(nodeCUuid, nodes); - // if nodeC is not present we return an empty element and + // if nodeC is not present we return a failure // log a warning if (nodeC.isEmpty()) { - logSkippingWarning( - typeEntityData.getTargetClass().getSimpleName(), - fieldsToAttributes.get("uuid"), - fieldsToAttributes.get("id"), - "nodeC: " + nodeCUuid); - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + typeEntityData.getTargetClass().getSimpleName(), + fieldsToAttributes.get("uuid"), + fieldsToAttributes.get("id"), + "nodeC: " + nodeCUuid); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor fieldsToAttributes.keySet().remove("nodeC"); - return Optional.of( + return new Success<>( new Transformer3WInputEntityData( fieldsToAttributes, typeEntityData.getTargetClass(), diff --git a/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java b/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java index 080d8fc75..87d9fcc21 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/ResultEntitySource.java @@ -321,7 +321,10 @@ private Set getResultEntities( return simpleEntityDataStream(entityClass) .map( entityData -> - factory.get(entityData).flatMap(loadResult -> cast(entityClass, loadResult))) + factory + .get(entityData) + .getData() + .flatMap(loadResult -> cast(entityClass, loadResult))) .flatMap(Optional::stream) .collect(Collectors.toSet()); } diff --git a/src/main/java/edu/ie3/datamodel/io/source/SystemParticipantSource.java b/src/main/java/edu/ie3/datamodel/io/source/SystemParticipantSource.java index c9396b640..3754362dd 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/SystemParticipantSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/SystemParticipantSource.java @@ -5,10 +5,12 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.exceptions.SourceException; +import edu.ie3.datamodel.exceptions.SystemParticipantsException; import edu.ie3.datamodel.io.factory.EntityFactory; import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData; import edu.ie3.datamodel.io.factory.input.participant.*; -import edu.ie3.datamodel.models.UniqueEntity; import edu.ie3.datamodel.models.input.NodeInput; import edu.ie3.datamodel.models.input.OperatorInput; import edu.ie3.datamodel.models.input.container.SystemParticipants; @@ -16,16 +18,16 @@ import edu.ie3.datamodel.models.input.system.type.*; import edu.ie3.datamodel.models.input.thermal.ThermalBusInput; import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.LongAdder; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; /** - * Interface that provides the capability to build entities of type {@link SystemParticipantInput} - * as well as {@link SystemParticipants} container. + * Implementation that provides the capability to build entities of type {@link + * SystemParticipantInput} as well as {@link SystemParticipants} container. */ public class SystemParticipantSource extends EntitySource { @@ -76,26 +78,24 @@ public SystemParticipantSource( } /** - * Should return either a consistent instance of {@link SystemParticipants} wrapped in {@link - * Optional} or an empty {@link Optional}. The decision to use {@link Optional} instead of - * returning the {@link SystemParticipants} instance directly is motivated by the fact, that a - * {@link SystemParticipants} is a container instance that depends on several other entities. - * Without being complete, it is useless for further processing. + * Should return either a consistent instance of {@link SystemParticipants} or throw a {@link + * SourceException}. The decision to throw a {@link SourceException} instead of returning the + * incomplete {@link SystemParticipants} instance is motivated by the fact, that a {@link + * SystemParticipants} is a container instance that depends on several other entities. Without + * being complete, it is useless for further processing. * *

Hence, whenever at least one entity {@link SystemParticipants} depends on cannot be - * provided, {@link Optional#empty()} should be returned and extensive logging should provide - * enough information to debug the error and fix the persistent data that has been failed to - * processed. + * provided, {@link SourceException} should be thrown. The thrown exception should provide enough + * information to debug the error and fix the persistent data that has been failed to processed. * *

Furthermore, it is expected, that the specific implementation of this method ensures not * only the completeness of the resulting {@link SystemParticipants} instance, but also its * validity e.g. in the sense that not duplicate UUIDs exist within all entities contained in the * returning instance. * - * @return either a valid, complete {@link SystemParticipants} optional or {@link - * Optional#empty()} + * @return either a valid, complete {@link SystemParticipants} or throws a {@link SourceException} */ - public Optional getSystemParticipants() { + public SystemParticipants getSystemParticipants() throws SourceException { // read all needed entities /// start with types and operators @@ -114,77 +114,67 @@ public Optional getSystemParticipants() { /// go on with the nodes Set nodes = rawGridSource.getNodes(operators); - - // start with the entities needed for SystemParticipants container - /// as we want to return a working grid, keep an eye on empty optionals which is equal to - // elements that - /// have been unable to be built e.g. due to missing elements they depend on - ConcurrentHashMap, LongAdder> nonBuildEntities = - new ConcurrentHashMap<>(); - - Set fixedFeedInInputs = - buildNodeAssetEntities( - FixedFeedInInput.class, fixedFeedInInputFactory, nodes, operators, nonBuildEntities); - Set pvInputs = - buildNodeAssetEntities(PvInput.class, pvInputFactory, nodes, operators, nonBuildEntities); - Set loads = - buildNodeAssetEntities( - LoadInput.class, loadInputFactory, nodes, operators, nonBuildEntities); - Set bmInputs = - buildSystemParticipantEntities( - BmInput.class, bmInputFactory, nodes, operators, bmTypes, nonBuildEntities); - Set storages = - buildSystemParticipantEntities( - StorageInput.class, - storageInputFactory, - nodes, - operators, - storageTypes, - nonBuildEntities); - Set wecInputs = - buildSystemParticipantEntities( - WecInput.class, wecInputFactory, nodes, operators, wecTypes, nonBuildEntities); - Set evs = - buildSystemParticipantEntities( - EvInput.class, evInputFactory, nodes, operators, evTypes, nonBuildEntities); - Set evcs = - buildNodeAssetEntities( - EvcsInput.class, evcsInputFactory, nodes, operators, nonBuildEntities); - Set chpInputs = - buildChpInputEntities( - chpInputFactory, - nodes, - operators, - chpTypes, - thermalBuses, - thermalStorages, - nonBuildEntities); - Set hpInputs = - buildHpInputEntities( - hpInputFactory, nodes, operators, hpTypes, thermalBuses, nonBuildEntities); - Set emInputs = - buildNodeAssetEntities(EmInput.class, emInputFactory, nodes, operators, nonBuildEntities); - - // if we found invalid elements return an empty optional and log the problems - if (!nonBuildEntities.isEmpty()) { - nonBuildEntities.forEach(this::printInvalidElementInformation); - return Optional.empty(); + Try, SourceException> fixedFeedInInputs = + Try.of(() -> getFixedFeedIns(nodes, operators), SourceException.class); + Try, SourceException> pvInputs = + Try.of(() -> getPvPlants(nodes, operators), SourceException.class); + Try, SourceException> loads = + Try.of(() -> getLoads(nodes, operators), SourceException.class); + Try, SourceException> bmInputs = + Try.of(() -> getBmPlants(nodes, operators, bmTypes), SourceException.class); + Try, SourceException> storages = + Try.of(() -> getStorages(nodes, operators, storageTypes), SourceException.class); + Try, SourceException> wecInputs = + Try.of(() -> getWecPlants(nodes, operators, wecTypes), SourceException.class); + Try, SourceException> evs = + Try.of(() -> getEvs(nodes, operators, evTypes), SourceException.class); + Try, SourceException> evcs = + Try.of(() -> getEvCS(nodes, operators), SourceException.class); + Try, SourceException> chpInputs = + Try.of( + () -> getChpPlants(nodes, operators, chpTypes, thermalBuses, thermalStorages), + SourceException.class); + Try, SourceException> hpInputs = + Try.of(() -> getHeatPumps(nodes, operators, hpTypes, thermalBuses), SourceException.class); + Try, SourceException> emInputs = + Try.of(() -> getEmSystems(nodes, operators), SourceException.class); + + List exceptions = + Try.getExceptions( + List.of( + fixedFeedInInputs, + pvInputs, + loads, + bmInputs, + storages, + wecInputs, + evs, + evcs, + chpInputs, + hpInputs, + emInputs)); + + if (!exceptions.isEmpty()) { + throw new SystemParticipantsException( + exceptions.size() + " error(s) occurred while initializing system participants. ", + exceptions); + } else { + // if everything is fine, return a system participants container + // getOrThrow should not throw an exception in this context, because all exception are + // filtered and thrown before + return new SystemParticipants( + bmInputs.getOrThrow(), + chpInputs.getOrThrow(), + evcs.getOrThrow(), + evs.getOrThrow(), + fixedFeedInInputs.getOrThrow(), + hpInputs.getOrThrow(), + loads.getOrThrow(), + pvInputs.getOrThrow(), + storages.getOrThrow(), + wecInputs.getOrThrow(), + emInputs.getOrThrow()); } - - // if everything is fine, return a system participants container - return Optional.of( - new SystemParticipants( - bmInputs, - chpInputs, - evcs, - evs, - fixedFeedInInputs, - hpInputs, - loads, - pvInputs, - storages, - wecInputs, - emInputs)); } /** @@ -197,7 +187,7 @@ public Optional getSystemParticipants() { * * @return a set of object and uuid unique {@link FixedFeedInInput} entities */ - public Set getFixedFeedIns() { + public Set getFixedFeedIns() throws SourceException { Set operators = typeSource.getOperators(); return getFixedFeedIns(rawGridSource.getNodes(operators), operators); } @@ -208,22 +198,27 @@ public Set getFixedFeedIns() { * {@link FixedFeedInInput} which has to be checked manually, as {@link * FixedFeedInInput#equals(Object)} is NOT restricted on the uuid of {@link FixedFeedInInput}. * - *

In contrast to {@link #getFixedFeedIns()} this interface provides the ability to pass in an + *

In contrast to {@link #getFixedFeedIns()} this method provides the ability to pass in an * already existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link * FixedFeedInInput} instances depend on. Doing so, already loaded nodes can be recycled to * improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link FixedFeedInInput} entities */ - public Set getFixedFeedIns(Set nodes, Set operators) { - return buildNodeAssetEntities( - FixedFeedInInput.class, fixedFeedInInputFactory, nodes, operators); + public Set getFixedFeedIns(Set nodes, Set operators) + throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities( + FixedFeedInInput.class, fixedFeedInInputFactory, nodes, operators), + FixedFeedInInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -235,7 +230,7 @@ public Set getFixedFeedIns(Set nodes, Set getPvPlants() { + public Set getPvPlants() throws SourceException { Set operators = typeSource.getOperators(); return getPvPlants(rawGridSource.getNodes(operators), operators); } @@ -246,21 +241,25 @@ public Set getPvPlants() { * PvInput} which has to be checked manually, as {@link PvInput#equals(Object)} is NOT restricted * on the uuid of {@link PvInput}. * - *

In contrast to {@link #getPvPlants()} this interface provides the ability to pass in an - * already existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link - * PvInput} instances depend on. Doing so, already loaded nodes can be recycled to improve - * performance and prevent unnecessary loading operations. + *

In contrast to {@link #getPvPlants()} this method provides the ability to pass in an already + * existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link PvInput} + * instances depend on. Doing so, already loaded nodes can be recycled to improve performance and + * prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link PvInput} entities */ - public Set getPvPlants(Set nodes, Set operators) { - return buildNodeAssetEntities(PvInput.class, pvInputFactory, nodes, operators); + public Set getPvPlants(Set nodes, Set operators) + throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities(PvInput.class, pvInputFactory, nodes, operators), PvInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -272,7 +271,7 @@ public Set getPvPlants(Set nodes, Set operato * * @return a set of object and uuid unique {@link LoadInput} entities */ - public Set getLoads() { + public Set getLoads() throws SourceException { Set operators = typeSource.getOperators(); return getLoads(rawGridSource.getNodes(operators), operators); } @@ -283,21 +282,26 @@ public Set getLoads() { * LoadInput} which has to be checked manually, as {@link LoadInput#equals(Object)} is NOT * restricted on the uuid of {@link LoadInput}. * - *

In contrast to {@link #getLoads()} this interface provides the ability to pass in an already + *

In contrast to {@link #getLoads()} this method provides the ability to pass in an already * existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link LoadInput} * instances depend on. Doing so, already loaded nodes can be recycled to improve performance and * prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link LoadInput} entities */ - public Set getLoads(Set nodes, Set operators) { - return buildNodeAssetEntities(LoadInput.class, loadInputFactory, nodes, operators); + public Set getLoads(Set nodes, Set operators) + throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities(LoadInput.class, loadInputFactory, nodes, operators), + LoadInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -309,7 +313,7 @@ public Set getLoads(Set nodes, Set operator * * @return a set of object and uuid unique {@link EvcsInput} entities */ - public Set getEvCS() { + public Set getEvCS() throws SourceException { Set operators = typeSource.getOperators(); return getEvCS(rawGridSource.getNodes(operators), operators); } @@ -320,21 +324,26 @@ public Set getEvCS() { * EvcsInput} which has to be checked manually, as {@link EvcsInput#equals(Object)} is NOT * restricted on the uuid of {@link EvcsInput}. * - *

In contrast to {@link #getEvCS()} this interface provides the ability to pass in an already + *

In contrast to {@link #getEvCS()} this method provides the ability to pass in an already * existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link EvcsInput} * instances depend on. Doing so, already loaded nodes can be recycled to improve performance and * prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link EvcsInput} entities */ - public Set getEvCS(Set nodes, Set operators) { - return buildNodeAssetEntities(EvcsInput.class, evcsInputFactory, nodes, operators); + public Set getEvCS(Set nodes, Set operators) + throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities(EvcsInput.class, evcsInputFactory, nodes, operators), + EvcsInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -346,7 +355,7 @@ public Set getEvCS(Set nodes, Set operators * * @return a set of object and uuid unique {@link BmInput} entities */ - public Set getBmPlants() { + public Set getBmPlants() throws SourceException { Set operators = typeSource.getOperators(); return getBmPlants(rawGridSource.getNodes(operators), operators, typeSource.getBmTypes()); } @@ -357,13 +366,13 @@ public Set getBmPlants() { * BmInput} which has to be checked manually, as {@link BmInput#equals(Object)} is NOT restricted * on the uuid of {@link BmInput}. * - *

In contrast to {@link #getBmPlants()} this interface provides the ability to pass in an - * already existing set of {@link NodeInput}, {@link BmTypeInput} and {@link OperatorInput} - * entities, the {@link BmInput} instances depend on. Doing so, already loaded nodes can be - * recycled to improve performance and prevent unnecessary loading operations. + *

In contrast to {@link #getBmPlants()} this method provides the ability to pass in an already + * existing set of {@link NodeInput}, {@link BmTypeInput} and {@link OperatorInput} entities, the + * {@link BmInput} instances depend on. Doing so, already loaded nodes can be recycled to improve + * performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -372,9 +381,14 @@ public Set getBmPlants() { * @return a set of object and uuid unique {@link BmInput} entities */ public Set getBmPlants( - Set nodes, Set operators, Set types) { - return buildTypedSystemParticipantEntities( - BmInput.class, bmInputFactory, nodes, operators, types); + Set nodes, Set operators, Set types) + throws SourceException { + return Try.scanCollection( + buildTypedSystemParticipantEntities( + BmInput.class, bmInputFactory, nodes, operators, types), + BmInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -387,7 +401,7 @@ public Set getBmPlants( * * @return a set of object and uuid unique {@link StorageInput} entities */ - public Set getStorages() { + public Set getStorages() throws SourceException { Set operators = typeSource.getOperators(); return getStorages(rawGridSource.getNodes(operators), operators, typeSource.getStorageTypes()); } @@ -398,13 +412,13 @@ public Set getStorages() { * {@link StorageInput} which has to be checked manually, as {@link StorageInput#equals(Object)} * is NOT restricted on the uuid of {@link StorageInput}. * - *

In contrast to {@link #getStorages()} this interface provides the ability to pass in an - * already existing set of {@link NodeInput}, {@link StorageTypeInput} and {@link OperatorInput} - * entities, the {@link StorageInput} instances depend on. Doing so, already loaded nodes can be - * recycled to improve performance and prevent unnecessary loading operations. + *

In contrast to {@link #getStorages()} this method provides the ability to pass in an already + * existing set of {@link NodeInput}, {@link StorageTypeInput} and {@link OperatorInput} entities, + * the {@link StorageInput} instances depend on. Doing so, already loaded nodes can be recycled to + * improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -413,9 +427,14 @@ public Set getStorages() { * @return a set of object and uuid unique {@link StorageInput} entities */ public Set getStorages( - Set nodes, Set operators, Set types) { - return buildTypedSystemParticipantEntities( - StorageInput.class, storageInputFactory, nodes, operators, types); + Set nodes, Set operators, Set types) + throws SourceException { + return Try.scanCollection( + buildTypedSystemParticipantEntities( + StorageInput.class, storageInputFactory, nodes, operators, types), + StorageInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -427,7 +446,7 @@ public Set getStorages( * * @return a set of object and uuid unique {@link WecInput} entities */ - public Set getWecPlants() { + public Set getWecPlants() throws SourceException { Set operators = typeSource.getOperators(); return getWecPlants(rawGridSource.getNodes(operators), operators, typeSource.getWecTypes()); } @@ -438,13 +457,13 @@ public Set getWecPlants() { * WecInput} which has to be checked manually, as {@link WecInput#equals(Object)} is NOT * restricted on the uuid of {@link WecInput}. * - *

In contrast to {@link #getWecPlants()} this interface provides the ability to pass in an + *

In contrast to {@link #getWecPlants()} this method provides the ability to pass in an * already existing set of {@link NodeInput}, {@link WecTypeInput} and {@link OperatorInput} * entities, the {@link WecInput} instances depend on. Doing so, already loaded nodes can be * recycled to improve performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -453,9 +472,14 @@ public Set getWecPlants() { * @return a set of object and uuid unique {@link WecInput} entities */ public Set getWecPlants( - Set nodes, Set operators, Set types) { - return buildTypedSystemParticipantEntities( - WecInput.class, wecInputFactory, nodes, operators, types); + Set nodes, Set operators, Set types) + throws SourceException { + return Try.scanCollection( + buildTypedSystemParticipantEntities( + WecInput.class, wecInputFactory, nodes, operators, types), + WecInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -467,7 +491,7 @@ public Set getWecPlants( * * @return a set of object and uuid unique {@link EvInput} entities */ - public Set getEvs() { + public Set getEvs() throws SourceException { Set operators = typeSource.getOperators(); return getEvs(rawGridSource.getNodes(operators), operators, typeSource.getEvTypes()); } @@ -478,13 +502,13 @@ public Set getEvs() { * EvInput} which has to be checked manually, as {@link EvInput#equals(Object)} is NOT restricted * on the uuid of {@link EvInput}. * - *

In contrast to {@link #getEvs()} this interface provides the ability to pass in an already + *

In contrast to {@link #getEvs()} this method provides the ability to pass in an already * existing set of {@link NodeInput}, {@link EvTypeInput} and {@link OperatorInput} entities, the * {@link EvInput} instances depend on. Doing so, already loaded nodes can be recycled to improve * performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances @@ -493,9 +517,14 @@ public Set getEvs() { * @return a set of object and uuid unique {@link EvInput} entities */ public Set getEvs( - Set nodes, Set operators, Set types) { - return buildTypedSystemParticipantEntities( - EvInput.class, evInputFactory, nodes, operators, types); + Set nodes, Set operators, Set types) + throws SourceException { + return Try.scanCollection( + buildTypedSystemParticipantEntities( + EvInput.class, evInputFactory, nodes, operators, types), + EvInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -507,7 +536,7 @@ public Set getEvs( * * @return a set of object and uuid unique {@link EmInput} entities */ - public Set getEmSystems() { + public Set getEmSystems() throws SourceException { Set operators = typeSource.getOperators(); return getEmSystems(rawGridSource.getNodes(operators), operators); } @@ -517,24 +546,28 @@ public Set getEmSystems() { * java.util.UUID} uniqueness of the provided {@link EmInput} which has to be checked manually, as * {@link EmInput#equals(Object)} is NOT restricted on the uuid of {@link EmInput}. * - *

In contrast to {@link #getHeatPumps()} this interface provides the ability to pass in an + *

In contrast to {@link #getHeatPumps()} this method provides the ability to pass in an * already existing set of {@link NodeInput} and {@link OperatorInput} entities, the {@link * EmInput} instances depend on. Doing so, already loaded nodes can be recycled to improve * performance and prevent unnecessary loading operations. * - *

If something fails during the creation process it's up to the concrete implementation of an - * empty set or a set with all entities that has been able to be build is returned. + *

If something fails during the creation process a {@link SourceException} is thrown, else a + * set with all entities that has been able to be build is returned. * * @param operators a set of object and uuid unique {@link OperatorInput} that should be used for * the returning instances * @param nodes a set of object and uuid unique {@link NodeInput} entities * @return a set of object and uuid unique {@link EmInput} entities */ - public Set getEmSystems(Set nodes, Set operators) { - return buildNodeAssetEntities(EmInput.class, emInputFactory, nodes, operators); + public Set getEmSystems(Set nodes, Set operators) + throws SourceException { + return Try.scanCollection( + buildNodeAssetEntities(EmInput.class, emInputFactory, nodes, operators), EmInput.class) + .transformF(SourceException::new) + .getOrThrow(); } - public Set getChpPlants() { + public Set getChpPlants() throws SourceException { Set operators = typeSource.getOperators(); Set thermalBuses = thermalSource.getThermalBuses(operators); return getChpPlants( @@ -549,9 +582,8 @@ public Set getChpPlants() { * If one of the sets of {@link NodeInput}, {@link ThermalBusInput}, {@link ThermalStorageInput} * or {@link ChpTypeInput} entities is not exhaustive for all available {@link ChpInput} entities * (e.g. a {@link NodeInput} or {@link ChpTypeInput} entity is missing) or if an error during the - * building process occurs, the entity that misses something will be skipped (which can be seen as - * a filtering functionality) but all entities that are able to be built will be returned anyway - * and the elements that couldn't have been built are logged. + * building process occurs a {@link SourceException} is thrown, else all entities that are able to + * be built will be returned. * *

If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set * to {@link OperatorInput#NO_OPERATOR_ASSIGNED} @@ -561,13 +593,17 @@ public Set getChpPlants( Set operators, Set types, Set thermalBuses, - Set thermalStorages) { - - return buildChpInputEntities( - chpInputFactory, nodes, operators, types, thermalBuses, thermalStorages); + Set thermalStorages) + throws SourceException { + return Try.scanCollection( + buildChpInputEntities( + chpInputFactory, nodes, operators, types, thermalBuses, thermalStorages), + ChpInput.class) + .transformF(SourceException::new) + .getOrThrow(); } - public Set getHeatPumps() { + public Set getHeatPumps() throws SourceException { Set operators = typeSource.getOperators(); return getHeatPumps( rawGridSource.getNodes(operators), @@ -579,10 +615,9 @@ public Set getHeatPumps() { /** * If one of the sets of {@link NodeInput}, {@link ThermalBusInput} or {@link HpTypeInput} * entities is not exhaustive for all available {@link HpInput} entities (e.g. a {@link NodeInput} - * or {@link HpTypeInput} entity is missing) or if an error during the building process occurs, - * the entity that misses something will be skipped (which can be seen as a filtering - * functionality) but all entities that are able to be built will be returned anyway and the - * elements that couldn't have been built are logged. + * or {@link HpTypeInput} entity is missing) or if an error during the building process occurs a + * {@link SourceException} is thrown, else all entities that are able to be built will be + * returned. * *

If the set with {@link OperatorInput} is not exhaustive, the corresponding operator is set * to {@link OperatorInput#NO_OPERATOR_ASSIGNED} @@ -591,39 +626,29 @@ public Set getHeatPumps( Set nodes, Set operators, Set types, - Set thermalBuses) { - return buildHpInputEntities(hpInputFactory, nodes, operators, types, thermalBuses); + Set thermalBuses) + throws SourceException { + return Try.scanCollection( + buildHpInputEntities(hpInputFactory, nodes, operators, types, thermalBuses), + HpInput.class) + .transformF(SourceException::new) + .getOrThrow(); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- private - Set buildSystemParticipantEntities( - Class entityClass, - EntityFactory> factory, - Collection nodes, - Collection operators, - Collection types, - ConcurrentMap, LongAdder> nonBuildEntities) { - return typedSystemParticipantEntityStream(entityClass, factory, nodes, operators, types) - .filter(isPresentCollectIfNot(entityClass, nonBuildEntities)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - private - Set buildTypedSystemParticipantEntities( + Set> buildTypedSystemParticipantEntities( Class entityClass, EntityFactory> factory, Collection nodes, Collection operators, Collection types) { return typedSystemParticipantEntityStream(entityClass, factory, nodes, operators, types) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } - private Set buildChpInputEntities( + private Set> buildChpInputEntities( ChpInputFactory factory, Collection nodes, Collection operators, @@ -631,52 +656,23 @@ private Set buildChpInputEntities( Collection thermalBuses, Collection thermalStorages) { return chpInputStream(factory, nodes, operators, chpTypes, thermalBuses, thermalStorages) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } - private Set buildChpInputEntities( - ChpInputFactory factory, - Collection nodes, - Collection operators, - Collection chpTypes, - Collection thermalBuses, - Collection thermalStorages, - ConcurrentMap, LongAdder> nonBuildEntities) { - return chpInputStream(factory, nodes, operators, chpTypes, thermalBuses, thermalStorages) - .filter(isPresentCollectIfNot(ChpInput.class, nonBuildEntities)) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - private Set buildHpInputEntities( + private Set> buildHpInputEntities( HpInputFactory factory, Collection nodes, Collection operators, Collection types, Collection thermalBuses) { return hpInputStream(factory, nodes, operators, types, thermalBuses) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - private Set buildHpInputEntities( - HpInputFactory factory, - Collection nodes, - Collection operators, - Collection types, - Collection thermalBuses, - ConcurrentMap, LongAdder> nonBuildEntities) { - return hpInputStream(factory, nodes, operators, types, thermalBuses) - .filter(isPresentCollectIfNot(ChpInput.class, nonBuildEntities)) - .flatMap(Optional::stream) .collect(Collectors.toSet()); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- /** - * Constructs a stream of {@link SystemParticipantInput} entities wrapped in {@link Optional}s. + * Constructs a stream of {@link SystemParticipantInput} entities wrapped in {@link Try}'s. * * @param entityClass the class of the entities that should be built * @param factory the corresponding factory that is capable of building this entities @@ -685,11 +681,11 @@ private Set buildHpInputEntities( * @param types the types that should be considered for these entities * @param the type of the resulting entity * @param the type of the type model of the resulting entity - * @return a stream of optionals being either empty or holding an instance of a {@link + * @return a stream of tries being either empty or holding an instance of a {@link * SystemParticipantInput} of the requested entity class */ private - Stream> typedSystemParticipantEntityStream( + Stream> typedSystemParticipantEntityStream( Class entityClass, EntityFactory> factory, Collection nodes, @@ -699,10 +695,10 @@ Stream> typedSystemParticipantEntityStream( nodeAssetInputEntityDataStream( assetInputEntityDataStream(entityClass, operators), nodes), types) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } - private Stream> chpInputStream( + private Stream> chpInputStream( ChpInputFactory factory, Collection nodes, Collection operators, @@ -716,10 +712,10 @@ private Stream> chpInputStream( types), thermalStorages, thermalBuses) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } - private Stream> hpInputStream( + private Stream> hpInputStream( HpInputFactory factory, Collection nodes, Collection operators, @@ -731,26 +727,27 @@ private Stream> hpInputStream( assetInputEntityDataStream(HpInput.class, operators), nodes), types), thermalBuses) - .map(dataOpt -> dataOpt.flatMap(factory::get)); + .map(factory::get); } /** - * Enriches a given stream of {@link NodeAssetInputEntityData} optionals with a type of {@link - * SystemParticipantTypeInput} based on the provided collection of types and the fields to values - * mapping that inside the already provided {@link NodeAssetInputEntityData} instance. + * Enriches a given stream of {@link NodeAssetInputEntityData} {@link Try} objects with a type of + * {@link SystemParticipantTypeInput} based on the provided collection of types and the fields to + * values mapping that inside the already provided {@link NodeAssetInputEntityData} instance. * - * @param nodeAssetEntityDataStream the data stream of {@link NodeAssetInputEntityData} optionals + * @param nodeAssetEntityDataStream the data stream of {@link NodeAssetInputEntityData} {@link + * Try} objects * @param types the types that should be used for enrichment and to build {@link * SystemParticipantTypedEntityData} from * @param the type of the provided entity types as well as the type parameter of the resulting * {@link SystemParticipantTypedEntityData} - * @return a stream of optional {@link SystemParticipantTypedEntityData} instances or empty - * optionals if the type couldn't be found + * @return a stream of tries of {@link SystemParticipantTypedEntityData} instances */ private - Stream>> buildTypedSystemParticipantEntityData( - Stream> nodeAssetEntityDataStream, - Collection types) { + Stream, SourceException>> + buildTypedSystemParticipantEntityData( + Stream> nodeAssetEntityDataStream, + Collection types) { return nodeAssetEntityDataStream .parallel() .map( @@ -761,8 +758,9 @@ Stream>> buildTypedSystemParticipan } protected - Optional> buildTypedSystemParticipantEntityData( - NodeAssetInputEntityData nodeAssetInputEntityData, Collection types) { + Try, SourceException> + buildTypedSystemParticipantEntityData( + NodeAssetInputEntityData nodeAssetInputEntityData, Collection types) { return getAssetType( types, nodeAssetInputEntityData.getFieldsToValues(), @@ -786,21 +784,20 @@ Optional> buildTypedSystemParticipantEntityD } /** - * Enriches a given stream of {@link NodeAssetInputEntityData} optionals with a type of {@link + * Enriches a given stream of {@link NodeAssetInputEntityData} tries with a type of {@link * SystemParticipantTypeInput} based on the provided collection of types and the fields to values * mapping that inside the already provided {@link NodeAssetInputEntityData} instance. * - * @param nodeAssetEntityDataStream the data stream of {@link NodeAssetInputEntityData} optionals + * @param nodeAssetEntityDataStream the data stream of {@link NodeAssetInputEntityData} tries * @param types the types that should be used for enrichment and to build {@link * SystemParticipantTypedEntityData} from * @param the type of the provided entity types as well as the type parameter of the resulting * {@link SystemParticipantTypedEntityData} - * @return a stream of optional {@link SystemParticipantTypedEntityData} instances or empty - * optionals if the type couldn't be found + * @return a stream of tries of {@link SystemParticipantTypedEntityData} instances */ private - Stream>> buildTypedEntityData( - Stream> nodeAssetEntityDataStream, + Stream, SourceException>> buildTypedEntityData( + Stream> nodeAssetEntityDataStream, Collection types) { return nodeAssetEntityDataStream .parallel() @@ -812,7 +809,7 @@ Stream>> buildTypedEntityData( } protected - Optional> buildTypedEntityData( + Try, SourceException> buildTypedEntityData( NodeAssetInputEntityData nodeAssetInputEntityData, Collection types) { return getAssetType( types, @@ -837,19 +834,18 @@ Optional> buildTypedEntityData( } /** - * Enriches a given stream of {@link SystemParticipantTypedEntityData} optionals with a type of - * {@link ThermalBusInput} based on the provided collection of buses and the fields to values - * mapping inside the already provided {@link SystemParticipantTypedEntityData} instance. + * Enriches a given stream of {@link SystemParticipantTypedEntityData} tries with a type of {@link + * ThermalBusInput} based on the provided collection of buses and the fields to values mapping + * inside the already provided {@link SystemParticipantTypedEntityData} instance. * - * @param typedEntityDataStream the data stream of {@link SystemParticipantTypedEntityData} - * optionals + * @param typedEntityDataStream the data stream of {@link SystemParticipantTypedEntityData} tries * @param thermalBuses the thermal buses that should be used for enrichment and to build {@link * HpInputEntityData} - * @return stream of optional {@link HpInputEntityData} instances or empty optionals if they - * thermal bus couldn't be found + * @return stream of tries of {@link HpInputEntityData} instances */ - private Stream> buildHpEntityData( - Stream>> typedEntityDataStream, + private Stream> buildHpEntityData( + Stream, SourceException>> + typedEntityDataStream, Collection thermalBuses) { return typedEntityDataStream @@ -860,7 +856,7 @@ private Stream> buildHpEntityData( typedEntityData -> buildHpEntityData(typedEntityData, thermalBuses))); } - protected Optional buildHpEntityData( + protected Try buildHpEntityData( SystemParticipantTypedEntityData typedEntityData, Collection thermalBuses) { // get the raw data @@ -893,18 +889,21 @@ protected Optional buildHpEntityData( // if the requested entity is not present we return an empty element and // log a warning if (hpInputEntityDataOpt.isEmpty()) { - logSkippingWarning( - typedEntityData.getTargetClass().getSimpleName(), - safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), - safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), - "thermalBus: " + safeMapGet(fieldsToAttributes, THERMAL_BUS, FIELDS_TO_VALUES_MAP)); + String skippingMessage = + buildSkippingMessage( + typedEntityData.getTargetClass().getSimpleName(), + safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), + safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), + "thermalBus: " + safeMapGet(fieldsToAttributes, THERMAL_BUS, FIELDS_TO_VALUES_MAP)); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } - return hpInputEntityDataOpt; + return new Success<>(hpInputEntityDataOpt.get()); } - private Stream> buildChpEntityData( - Stream>> typedEntityDataStream, + private Stream> buildChpEntityData( + Stream, SourceException>> + typedEntityDataStream, Collection thermalStorages, Collection thermalBuses) { @@ -917,7 +916,7 @@ private Stream> buildChpEntityData( buildChpEntityData(typedEntityData, thermalStorages, thermalBuses))); } - protected Optional buildChpEntityData( + protected Try buildChpEntityData( SystemParticipantTypedEntityData typedEntityData, Collection thermalStorages, Collection thermalBuses) { @@ -938,24 +937,24 @@ protected Optional buildChpEntityData( // if the thermal storage or the thermal bus are not present we return an // empty element and log a warning - if (!thermalStorage.isPresent() || !thermalBus.isPresent()) { + if (thermalStorage.isEmpty() || thermalBus.isEmpty()) { StringBuilder sB = new StringBuilder(); - if (!thermalStorage.isPresent()) { + if (thermalStorage.isEmpty()) { sB.append("thermalStorage: ") .append(safeMapGet(fieldsToAttributes, THERMAL_STORAGE, FIELDS_TO_VALUES_MAP)); } - if (!thermalBus.isPresent()) { + if (thermalBus.isEmpty()) { sB.append("\nthermalBus: ") .append(safeMapGet(fieldsToAttributes, THERMAL_BUS, FIELDS_TO_VALUES_MAP)); } - logSkippingWarning( - typedEntityData.getTargetClass().getSimpleName(), - safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), - safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), - sB.toString()); - - return Optional.empty(); + String skippingMessage = + buildSkippingMessage( + typedEntityData.getTargetClass().getSimpleName(), + safeMapGet(fieldsToAttributes, "uuid", FIELDS_TO_VALUES_MAP), + safeMapGet(fieldsToAttributes, "id", FIELDS_TO_VALUES_MAP), + sB.toString()); + return new Failure<>(new SourceException("Failure due to: " + skippingMessage)); } // remove fields that are passed as objects to constructor @@ -963,7 +962,7 @@ protected Optional buildChpEntityData( .keySet() .removeAll(new HashSet<>(Arrays.asList("thermalBus", "thermalStorage"))); - return Optional.of( + return new Success<>( new ChpInputEntityData( fieldsToAttributes, typedEntityData.getOperatorInput(), diff --git a/src/main/java/edu/ie3/datamodel/io/source/ThermalSource.java b/src/main/java/edu/ie3/datamodel/io/source/ThermalSource.java index f1d5ef6f6..48384565f 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/ThermalSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/ThermalSource.java @@ -5,12 +5,17 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.exceptions.FailureException; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.input.*; import edu.ie3.datamodel.models.input.OperatorInput; import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput; import edu.ie3.datamodel.models.input.thermal.ThermalBusInput; import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput; import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -51,7 +56,7 @@ public ThermalSource(TypeSource typeSource, DataSource dataSource) { * * @return a set of object and uuid unique {@link ThermalBusInput} entities */ - public Set getThermalBuses() { + public Set getThermalBuses() throws SourceException { return getThermalBuses(typeSource.getOperators()); } @@ -73,8 +78,12 @@ public Set getThermalBuses() { * the returning instances * @return a set of object and uuid unique {@link ThermalBusInput} entities */ - public Set getThermalBuses(Set operators) { - return buildAssetInputEntities(ThermalBusInput.class, thermalBusInputFactory, operators); + public Set getThermalBuses(Set operators) throws SourceException { + return Try.scanCollection( + buildAssetInputEntities(ThermalBusInput.class, thermalBusInputFactory, operators), + ThermalBusInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -88,7 +97,7 @@ public Set getThermalBuses(Set operators) { * * @return a set of object and uuid unique {@link ThermalStorageInput} entities */ - public Set getThermalStorages() { + public Set getThermalStorages() throws SourceException { return new HashSet<>(getCylindricStorages()); } @@ -114,7 +123,7 @@ public Set getThermalStorages() { * @return a set of object and uuid unique {@link ThermalStorageInput} entities */ public Set getThermalStorages( - Set operators, Set thermalBuses) { + Set operators, Set thermalBuses) throws SourceException { return new HashSet<>(getCylindricStorages(operators, thermalBuses)); } @@ -128,8 +137,10 @@ public Set getThermalStorages( * * @return a set of object and uuid unique {@link ThermalHouseInput} entities */ - public Set getThermalHouses() { - return buildThermalHouseInputEntities(thermalHouseInputFactory); + public Set getThermalHouses() throws SourceException { + return buildThermalHouseInputEntities(thermalHouseInputFactory) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -153,8 +164,10 @@ public Set getThermalHouses() { * @return a set of object and uuid unique {@link ThermalHouseInput} entities */ public Set getThermalHouses( - Set operators, Set thermalBuses) { - return buildThermalHouseInputEntities(thermalHouseInputFactory, operators, thermalBuses); + Set operators, Set thermalBuses) throws SourceException { + return buildThermalHouseInputEntities(thermalHouseInputFactory, operators, thermalBuses) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -167,8 +180,10 @@ public Set getThermalHouses( * * @return a set of object and uuid unique {@link CylindricalStorageInput} entities */ - public Set getCylindricStorages() { - return buildCylindricalStorageInputEntities(cylindricalStorageInputFactory); + public Set getCylindricStorages() throws SourceException { + return buildCylindricalStorageInputEntities(cylindricalStorageInputFactory) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -193,15 +208,20 @@ public Set getCylindricStorages() { * @return a set of object and uuid unique {@link CylindricalStorageInput} entities */ public Set getCylindricStorages( - Set operators, Set thermalBuses) { - return buildCylindricalStorageInputEntities( - cylindricalStorageInputFactory, operators, thermalBuses); + Set operators, Set thermalBuses) throws SourceException { + return Try.scanCollection( + buildCylindricalStorageInputEntities( + cylindricalStorageInputFactory, operators, thermalBuses), + CylindricalStorageInput.class) + .transformF(SourceException::new) + .getOrThrow(); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - protected Stream> buildThermalUnitInputEntityData( - AssetInputEntityData assetInputEntityData, Collection thermalBuses) { + protected Stream> + buildThermalUnitInputEntityData( + AssetInputEntityData assetInputEntityData, Collection thermalBuses) { // get the raw data Map fieldsToAttributes = assetInputEntityData.getFieldsToValues(); @@ -219,16 +239,17 @@ protected Stream> buildThermalUnitInputEnti // if the type is not present we return an empty element and // log a warning if (thermalBus.isEmpty()) { - logSkippingWarning( - assetInputEntityData.getTargetClass().getSimpleName(), - fieldsToAttributes.get("uuid"), - fieldsToAttributes.get("id"), - "thermalBus: " + thermalBusUuid); - return Stream.of(Optional.empty()); + String skippingMessage = + buildSkippingMessage( + assetInputEntityData.getTargetClass().getSimpleName(), + fieldsToAttributes.get("uuid"), + fieldsToAttributes.get("id"), + "thermalBus: " + thermalBusUuid); + return Stream.of(new Failure<>(new SourceException("Failure due to: " + skippingMessage))); } return Stream.of( - Optional.of( + new Success<>( new ThermalUnitInputEntityData( assetInputEntityData.getFieldsToValues(), assetInputEntityData.getTargetClass(), @@ -236,50 +257,57 @@ protected Stream> buildThermalUnitInputEnti thermalBus.get()))); } - public Set buildThermalHouseInputEntities(ThermalHouseInputFactory factory) { - return assetInputEntityDataStream(ThermalHouseInput.class, typeSource.getOperators()) - .flatMap( - assetInputEntityData -> - buildThermalUnitInputEntityData(assetInputEntityData, getThermalBuses()) - .map(dataOpt -> dataOpt.flatMap(factory::get)) - .flatMap(Optional::stream)) - .collect(Collectors.toSet()); + public Try, FailureException> buildThermalHouseInputEntities( + ThermalHouseInputFactory factory) throws SourceException { + Set thermalBuses = getThermalBuses(); + + return Try.scanCollection( + assetInputEntityDataStream(ThermalHouseInput.class, typeSource.getOperators()) + .flatMap( + assetInputEntityData -> + buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses) + .map(factory::get)) + .collect(Collectors.toSet()), + ThermalHouseInput.class); } - public Set buildThermalHouseInputEntities( + public Try, FailureException> buildThermalHouseInputEntities( ThermalHouseInputFactory factory, Collection operators, Collection thermalBuses) { - return assetInputEntityDataStream(ThermalHouseInput.class, operators) - .map( - assetInputEntityData -> - buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses) - .map(dataOpt -> dataOpt.flatMap(factory::get))) - .flatMap(elements -> elements.flatMap(Optional::stream)) - .collect(Collectors.toSet()); + return Try.scanCollection( + assetInputEntityDataStream(ThermalHouseInput.class, operators) + .flatMap( + assetInputEntityData -> + buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses) + .map(factory::get)) + .collect(Collectors.toSet()), + ThermalHouseInput.class); } - public Set buildCylindricalStorageInputEntities( - CylindricalStorageInputFactory factory) { - return assetInputEntityDataStream(CylindricalStorageInput.class, typeSource.getOperators()) - .flatMap( - assetInputEntityData -> - buildThermalUnitInputEntityData(assetInputEntityData, getThermalBuses()) - .map(dataOpt -> dataOpt.flatMap(factory::get)) - .flatMap(Optional::stream)) - .collect(Collectors.toSet()); + public Try, FailureException> buildCylindricalStorageInputEntities( + CylindricalStorageInputFactory factory) throws SourceException { + Set thermalBuses = getThermalBuses(); + + return Try.scanCollection( + assetInputEntityDataStream(CylindricalStorageInput.class, typeSource.getOperators()) + .flatMap( + assetInputEntityData -> + buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses) + .map(factory::get)) + .collect(Collectors.toSet()), + CylindricalStorageInput.class); } - public Set buildCylindricalStorageInputEntities( + public Set> buildCylindricalStorageInputEntities( CylindricalStorageInputFactory factory, Collection operators, Collection thermalBuses) { return assetInputEntityDataStream(CylindricalStorageInput.class, operators) - .map( + .flatMap( assetInputEntityData -> buildThermalUnitInputEntityData(assetInputEntityData, thermalBuses) - .map(dataOpt -> dataOpt.flatMap(factory::get))) - .flatMap(elements -> elements.flatMap(Optional::stream)) + .map(factory::get)) .collect(Collectors.toSet()); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesMappingSource.java b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesMappingSource.java index 722f985cd..09d4530f9 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesMappingSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesMappingSource.java @@ -5,9 +5,12 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; import edu.ie3.datamodel.io.factory.SimpleEntityData; import edu.ie3.datamodel.io.factory.timeseries.TimeSeriesMappingFactory; import edu.ie3.datamodel.models.input.InputEntity; +import edu.ie3.datamodel.utils.Try; +import edu.ie3.datamodel.utils.Try.*; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -35,7 +38,9 @@ protected TimeSeriesMappingSource() { public Map getMapping() { return getMappingSourceData() .map(this::createMappingEntry) - .flatMap(Optional::stream) + .filter(Try::isSuccess) + .map(t -> (Success) t) + .map(Success::get) .collect(Collectors.toMap(MappingEntry::getParticipant, MappingEntry::getTimeSeries)); } @@ -58,7 +63,8 @@ public Optional getTimeSeriesUuid(UUID modelIdentifier) { // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - private Optional createMappingEntry(Map fieldToValues) { + private Try createMappingEntry( + Map fieldToValues) { SimpleEntityData entityData = new SimpleEntityData(fieldToValues, MappingEntry.class); return mappingFactory.get(entityData); } diff --git a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java index 700ba2f92..dd863ba51 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/TimeSeriesSource.java @@ -5,12 +5,14 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.FactoryException; import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.timeseries.SimpleTimeBasedValueData; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedSimpleValueFactory; import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; import edu.ie3.datamodel.models.value.Value; +import edu.ie3.datamodel.utils.Try; import edu.ie3.util.interval.ClosedInterval; import java.time.ZonedDateTime; import java.util.*; @@ -35,9 +37,10 @@ protected TimeSeriesSource(Class valueClass, TimeBasedSimpleValueFactory f * need any additional information. * * @param fieldToValues Mapping from field id to values - * @return Optional simple time based value + * @return {@link Try} of simple time based value */ - protected Optional> createTimeBasedValue(Map fieldToValues) { + protected Try, FactoryException> createTimeBasedValue( + Map fieldToValues) { SimpleTimeBasedValueData factoryData = new SimpleTimeBasedValueData<>(fieldToValues, valueClass); return valueFactory.get(factoryData); diff --git a/src/main/java/edu/ie3/datamodel/io/source/TypeSource.java b/src/main/java/edu/ie3/datamodel/io/source/TypeSource.java index 7906db0df..a7412cedc 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/TypeSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/TypeSource.java @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.input.OperatorInputFactory; import edu.ie3.datamodel.io.factory.typeinput.LineTypeInputFactory; import edu.ie3.datamodel.io.factory.typeinput.SystemParticipantTypeInputFactory; @@ -15,6 +16,7 @@ import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput; import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput; import edu.ie3.datamodel.models.input.system.type.*; +import edu.ie3.datamodel.utils.Try; import java.util.Set; /** @@ -52,8 +54,12 @@ public TypeSource(DataSource dataSource) { * * @return a set of object and uuid unique {@link Transformer2WTypeInput} entities */ - public Set getTransformer2WTypes() { - return buildEntities(Transformer2WTypeInput.class, transformer2WTypeInputFactory); + public Set getTransformer2WTypes() throws SourceException { + return Try.scanCollection( + buildEntities(Transformer2WTypeInput.class, transformer2WTypeInputFactory), + Transformer2WTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -64,8 +70,11 @@ public Set getTransformer2WTypes() { * * @return a set of object and uuid unique {@link OperatorInput} entities */ - public Set getOperators() { - return buildEntities(OperatorInput.class, operatorInputFactory); + public Set getOperators() throws SourceException { + return Try.scanCollection( + buildEntities(OperatorInput.class, operatorInputFactory), OperatorInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -76,8 +85,11 @@ public Set getOperators() { * * @return a set of object and uuid unique {@link LineTypeInput} entities */ - public Set getLineTypes() { - return buildEntities(LineTypeInput.class, lineTypeInputFactory); + public Set getLineTypes() throws SourceException { + return Try.scanCollection( + buildEntities(LineTypeInput.class, lineTypeInputFactory), LineTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -89,8 +101,12 @@ public Set getLineTypes() { * * @return a set of object and uuid unique {@link Transformer3WTypeInput} entities */ - public Set getTransformer3WTypes() { - return buildEntities(Transformer3WTypeInput.class, transformer3WTypeInputFactory); + public Set getTransformer3WTypes() throws SourceException { + return Try.scanCollection( + buildEntities(Transformer3WTypeInput.class, transformer3WTypeInputFactory), + Transformer3WTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -101,8 +117,11 @@ public Set getTransformer3WTypes() { * * @return a set of object and uuid unique {@link BmTypeInput} entities */ - public Set getBmTypes() { - return buildEntities(BmTypeInput.class, systemParticipantTypeInputFactory); + public Set getBmTypes() throws SourceException { + return Try.scanCollection( + buildEntities(BmTypeInput.class, systemParticipantTypeInputFactory), BmTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -113,8 +132,12 @@ public Set getBmTypes() { * * @return a set of object and uuid unique {@link ChpTypeInput} entities */ - public Set getChpTypes() { - return buildEntities(ChpTypeInput.class, systemParticipantTypeInputFactory); + public Set getChpTypes() throws SourceException { + return Try.scanCollection( + buildEntities(ChpTypeInput.class, systemParticipantTypeInputFactory), + ChpTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -125,8 +148,11 @@ public Set getChpTypes() { * * @return a set of object and uuid unique {@link HpTypeInput} entities */ - public Set getHpTypes() { - return buildEntities(HpTypeInput.class, systemParticipantTypeInputFactory); + public Set getHpTypes() throws SourceException { + return Try.scanCollection( + buildEntities(HpTypeInput.class, systemParticipantTypeInputFactory), HpTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -137,8 +163,12 @@ public Set getHpTypes() { * * @return a set of object and uuid unique {@link StorageTypeInput} entities */ - public Set getStorageTypes() { - return buildEntities(StorageTypeInput.class, systemParticipantTypeInputFactory); + public Set getStorageTypes() throws SourceException { + return Try.scanCollection( + buildEntities(StorageTypeInput.class, systemParticipantTypeInputFactory), + StorageTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -149,8 +179,12 @@ public Set getStorageTypes() { * * @return a set of object and uuid unique {@link WecTypeInput} entities */ - public Set getWecTypes() { - return buildEntities(WecTypeInput.class, systemParticipantTypeInputFactory); + public Set getWecTypes() throws SourceException { + return Try.scanCollection( + buildEntities(WecTypeInput.class, systemParticipantTypeInputFactory), + WecTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } /** @@ -161,7 +195,10 @@ public Set getWecTypes() { * * @return a set of object and uuid unique {@link EvTypeInput} entities */ - public Set getEvTypes() { - return buildEntities(EvTypeInput.class, systemParticipantTypeInputFactory); + public Set getEvTypes() throws SourceException { + return Try.scanCollection( + buildEntities(EvTypeInput.class, systemParticipantTypeInputFactory), EvTypeInput.class) + .transformF(SourceException::new) + .getOrThrow(); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java index cdbf21425..c3702993f 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/WeatherSource.java @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.source; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory; import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; import edu.ie3.datamodel.models.value.WeatherValue; +import edu.ie3.datamodel.utils.Try; import edu.ie3.util.interval.ClosedInterval; import java.time.ZonedDateTime; import java.util.*; @@ -41,13 +43,14 @@ protected WeatherSource( // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- public abstract Map> getWeather( - ClosedInterval timeInterval); + ClosedInterval timeInterval) throws SourceException; public abstract Map> getWeather( - ClosedInterval timeInterval, Collection coordinates); + ClosedInterval timeInterval, Collection coordinates) + throws SourceException; public abstract Optional> getWeather( - ZonedDateTime date, Point coordinate); + ZonedDateTime date, Point coordinate) throws SourceException; // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- @@ -101,20 +104,23 @@ protected Map> mapWeatherValuesToPoint * Converts a stream of fields to value map into a TimeBasedValue, removes the "tid" * * @param factory TimeBasedWeatherValueFactory - * @param inputStream stream of fields to convert into TimeBasedValues's - * @return an Optional of that TimeBasedValue + * @param inputStream stream of fields to convert into TimeBasedValues + * @return a list of that TimeBasedValues */ public List> buildTimeBasedValues( - TimeBasedWeatherValueFactory factory, Stream> inputStream) { - return inputStream - .map( - fieldsToAttributes -> { - fieldsToAttributes.remove("tid"); - Optional data = - toTimeBasedWeatherValueData(fieldsToAttributes); - return factory.get(data.get()); - }) - .flatMap(Optional::stream) + TimeBasedWeatherValueFactory factory, Stream> inputStream) + throws SourceException { + return Try.scanStream( + inputStream.map( + fieldsToAttributes -> { + fieldsToAttributes.remove("tid"); + Optional data = + toTimeBasedWeatherValueData(fieldsToAttributes); + return factory.get(data.get()); + }), + "TimeBasedValue") + .transformF(SourceException::new) + .getOrThrow() .toList(); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/couchbase/CouchbaseWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/couchbase/CouchbaseWeatherSource.java index 60347211d..abfaca204 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/couchbase/CouchbaseWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/couchbase/CouchbaseWeatherSource.java @@ -232,7 +232,6 @@ public Optional> toTimeBasedWeatherValue(JsonObject logger.debug("The following json could not be parsed:\n{}", jsonObj); return Optional.empty(); } - TimeBasedValue timeBasedValue = weatherFactory.get(data.get()).orElse(null); - return Optional.ofNullable(timeBasedValue); + return weatherFactory.get(data.get()).getData(); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java index 541a247a2..e5aabaaa3 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvDataSource.java @@ -373,9 +373,9 @@ protected Set> distinctRowsWithLog( allRowsSet.stream().map(keyExtractor).collect(Collectors.joining(",\n")); log.error( """ - '{}' entities with duplicated {} key, but different field values found! Please review the corresponding input file! - Affected primary keys: - {}""", + '{}' entities with duplicated {} key, but different field values found! Please review the corresponding input file! + Affected primary keys: + {}""", entityDescriptor, keyDescriptor, affectedCoordinateIds); diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java index 4f5b89a5b..9926e29c0 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvIdCoordinateSource.java @@ -5,9 +5,11 @@ */ package edu.ie3.datamodel.io.source.csv; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.factory.SimpleFactoryData; import edu.ie3.datamodel.io.factory.timeseries.IdCoordinateFactory; import edu.ie3.datamodel.io.source.IdCoordinateSource; +import edu.ie3.datamodel.utils.Try; import edu.ie3.util.geo.CoordinateDistance; import edu.ie3.util.geo.GeoUtils; import java.io.BufferedReader; @@ -44,7 +46,8 @@ public class CsvIdCoordinateSource implements IdCoordinateSource { private final CsvDataSource dataSource; private final IdCoordinateFactory factory; - public CsvIdCoordinateSource(IdCoordinateFactory factory, CsvDataSource dataSource) { + public CsvIdCoordinateSource(IdCoordinateFactory factory, CsvDataSource dataSource) + throws SourceException { this.factory = factory; this.dataSource = dataSource; @@ -58,11 +61,14 @@ public CsvIdCoordinateSource(IdCoordinateFactory factory, CsvDataSource dataSour * * @return Mapping from coordinate id to coordinate */ - private Map setupIdToCoordinateMap() { - return buildStreamWithFieldsToAttributesMap() - .map(fieldToValues -> new SimpleFactoryData(fieldToValues, Pair.class)) - .map(factory::get) - .flatMap(Optional::stream) + private Map setupIdToCoordinateMap() throws SourceException { + return Try.scanStream( + buildStreamWithFieldsToAttributesMap() + .map(fieldToValues -> new SimpleFactoryData(fieldToValues, Pair.class)) + .map(factory::get), + "Pair") + .transformF(SourceException::new) + .getOrThrow() .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); } diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvJointGridContainerSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvJointGridContainerSource.java index 706e0a9ca..31b209676 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvJointGridContainerSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvJointGridContainerSource.java @@ -15,7 +15,9 @@ import edu.ie3.datamodel.models.input.container.JointGridContainer; import edu.ie3.datamodel.models.input.container.RawGridElements; import edu.ie3.datamodel.models.input.container.SystemParticipants; +import edu.ie3.datamodel.utils.Try; import java.nio.file.Path; +import java.util.List; /** Convenience class for cases where all used data comes from CSV sources */ public class CsvJointGridContainerSource { @@ -50,20 +52,27 @@ public static JointGridContainer read( GraphicSource graphicSource = new GraphicSource(typeSource, rawGridSource, dataSource); /* Loading models */ - RawGridElements rawGridElements = - rawGridSource - .getGridData() - .orElseThrow(() -> new SourceException("Error during reading of raw grid data.")); - SystemParticipants systemParticipants = - systemParticipantSource - .getSystemParticipants() - .orElseThrow( - () -> new SourceException("Error during reading of system participant data.")); - GraphicElements graphicElements = - graphicSource - .getGraphicElements() - .orElseThrow(() -> new SourceException("Error during reading of graphic elements.")); + Try rawGridElements = + Try.of(rawGridSource::getGridData, SourceException.class); + Try systemParticipants = + Try.of(systemParticipantSource::getSystemParticipants, SourceException.class); + Try graphicElements = + Try.of(graphicSource::getGraphicElements, SourceException.class); - return new JointGridContainer(gridName, rawGridElements, systemParticipants, graphicElements); + List exceptions = + Try.getExceptions(List.of(rawGridElements, systemParticipants, graphicElements)); + + if (!exceptions.isEmpty()) { + throw new SourceException( + exceptions.size() + " error(s) occurred while reading sources. ", exceptions); + } else { + // getOrThrow should not throw an exception in this context, because all exception are + // filtered and thrown before + return new JointGridContainer( + gridName, + rawGridElements.getOrThrow(), + systemParticipants.getOrThrow(), + graphicElements.getOrThrow()); + } } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java index 6882b6dc3..4b8d55604 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSource.java @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.source.csv; +import edu.ie3.datamodel.exceptions.FactoryException; +import edu.ie3.datamodel.exceptions.FailureException; import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.csv.CsvIndividualTimeSeriesMetaInformation; import edu.ie3.datamodel.io.factory.timeseries.*; @@ -14,6 +16,7 @@ import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; import edu.ie3.datamodel.models.value.*; import edu.ie3.datamodel.utils.TimeSeriesUtils; +import edu.ie3.datamodel.utils.Try; import edu.ie3.util.interval.ClosedInterval; import java.io.BufferedReader; import java.io.FileNotFoundException; @@ -22,7 +25,7 @@ import java.time.ZonedDateTime; import java.util.*; import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.stream.Stream; /** Source that is capable of providing information around time series from csv files. */ public class CsvTimeSeriesSource extends TimeSeriesSource { @@ -132,25 +135,28 @@ public Optional getValue(ZonedDateTime time) { * @param fieldToValueFunction function, that is able to transfer a mapping (from field to value) * onto a specific instance of the targeted entry class * @throws SourceException If the file cannot be read properly - * @return An option onto an individual time series + * @return an individual time series */ protected IndividualTimeSeries buildIndividualTimeSeries( UUID timeSeriesUuid, Path filePath, - Function, Optional>> fieldToValueFunction) + Function, Try, FactoryException>> fieldToValueFunction) throws SourceException { try (BufferedReader reader = dataSource.connector.initReader(filePath)) { - Set> timeBasedValues = - dataSource - .buildStreamWithFieldsToAttributesMap(TimeBasedValue.class, reader) - .map(fieldToValueFunction) - .flatMap(Optional::stream) - .collect(Collectors.toSet()); - return new IndividualTimeSeries<>(timeSeriesUuid, timeBasedValues); + Try>, FailureException> timeBasedValues = + Try.scanStream( + dataSource + .buildStreamWithFieldsToAttributesMap(TimeBasedValue.class, reader) + .map(fieldToValueFunction), + "TimeBasedValue"); + return new IndividualTimeSeries<>( + timeSeriesUuid, new HashSet<>(timeBasedValues.getOrThrow().toList())); } catch (FileNotFoundException e) { throw new SourceException("Unable to find a file with path '" + filePath + "'.", e); } catch (IOException e) { throw new SourceException("Error during reading of file'" + filePath + "'.", e); + } catch (FailureException e) { + throw new SourceException("Unable to build individual time series. ", e.getCause()); } } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java index 737d6a644..1997edbd1 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/csv/CsvWeatherSource.java @@ -224,7 +224,7 @@ private Optional> buildWeatherValue( /* Build factory data */ TimeBasedWeatherValueData factoryData = new TimeBasedWeatherValueData(fieldToValues, coordinate); - return weatherFactory.get(factoryData); + return weatherFactory.get(factoryData).getData(); }) .orElseGet( () -> { diff --git a/src/main/java/edu/ie3/datamodel/io/source/influxdb/InfluxDbWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/influxdb/InfluxDbWeatherSource.java index 3ac543894..de3269b61 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/influxdb/InfluxDbWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/influxdb/InfluxDbWeatherSource.java @@ -13,6 +13,7 @@ import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries; import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue; import edu.ie3.datamodel.models.value.WeatherValue; +import edu.ie3.datamodel.utils.Try; import edu.ie3.util.StringUtils; import edu.ie3.util.interval.ClosedInterval; import java.time.ZonedDateTime; @@ -170,7 +171,8 @@ private Stream>> optTimeBasedValueStream( return idCoordinateSource .getCoordinate(coordinateId) .map(point -> new TimeBasedWeatherValueData(flatCaseFields, point)) - .flatMap(weatherFactory::get); + .map(weatherFactory::get) + .flatMap(Try::getData); }); } diff --git a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlIdCoordinateSource.java b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlIdCoordinateSource.java index e633c5a0e..ee56555cd 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlIdCoordinateSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlIdCoordinateSource.java @@ -177,7 +177,7 @@ private Optional createCoordinateValue(Map fiel fieldToValues.remove("distance"); SimpleFactoryData simpleFactoryData = new SimpleFactoryData(fieldToValues, Pair.class); - Optional> pair = factory.get(simpleFactoryData); + Optional> pair = factory.get(simpleFactoryData).getData(); if (pair.isEmpty()) { return Optional.empty(); diff --git a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesMetaInformationSource.java b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesMetaInformationSource.java index 241484e48..ad01ebe62 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesMetaInformationSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesMetaInformationSource.java @@ -94,6 +94,6 @@ private Optional createEntity( Map fieldToValues) { SimpleEntityData entityData = new SimpleEntityData(fieldToValues, IndividualTimeSeriesMetaInformation.class); - return mappingFactory.get(entityData); + return mappingFactory.get(entityData).getData(); } } diff --git a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java index 5d7adeb7e..126aefae5 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlTimeSeriesSource.java @@ -188,7 +188,7 @@ private Set> getTimeBasedValueSet( */ private Optional> createEntity(Map fieldToValues) { fieldToValues.remove("timeSeries"); - return createTimeBasedValue(fieldToValues); + return createTimeBasedValue(fieldToValues).getData(); } /** diff --git a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlWeatherSource.java b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlWeatherSource.java index 1f27b6eae..d2aab44e1 100644 --- a/src/main/java/edu/ie3/datamodel/io/source/sql/SqlWeatherSource.java +++ b/src/main/java/edu/ie3/datamodel/io/source/sql/SqlWeatherSource.java @@ -7,6 +7,7 @@ import static edu.ie3.datamodel.io.source.sql.SqlDataSource.createBaseQueryString; +import edu.ie3.datamodel.exceptions.SourceException; import edu.ie3.datamodel.io.connectors.SqlConnector; import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory; import edu.ie3.datamodel.io.naming.DatabaseNamingStrategy; @@ -76,7 +77,7 @@ public SqlWeatherSource( @Override public Map> getWeather( - ClosedInterval timeInterval) { + ClosedInterval timeInterval) throws SourceException { List> timeBasedValues = buildTimeBasedValues( weatherFactory, @@ -91,7 +92,8 @@ public Map> getWeather( @Override public Map> getWeather( - ClosedInterval timeInterval, Collection coordinates) { + ClosedInterval timeInterval, Collection coordinates) + throws SourceException { Set coordinateIds = coordinates.stream() .map(idCoordinateSource::getId) @@ -119,7 +121,8 @@ public Map> getWeather( } @Override - public Optional> getWeather(ZonedDateTime date, Point coordinate) { + public Optional> getWeather(ZonedDateTime date, Point coordinate) + throws SourceException { Optional coordinateId = idCoordinateSource.getId(coordinate); if (coordinateId.isEmpty()) { log.warn("Unable to match coordinate {} to a coordinate ID", coordinate); diff --git a/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java b/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java new file mode 100644 index 000000000..7aac61132 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/utils/ExceptionUtils.java @@ -0,0 +1,27 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.utils; + +import java.util.List; + +public class ExceptionUtils { + private ExceptionUtils() { + throw new IllegalStateException("Utility classes cannot be instantiated"); + } + + /** + * Creates a string containing multiple exception messsages. + * + * @param exceptions list of exceptions + * @return str containing the messages + */ + public static String getMessages(List exceptions) { + return exceptions.stream() + .map(Throwable::getMessage) + .reduce("", (a, b) -> a + ", " + b) + .replaceFirst(", ", ""); + } +} diff --git a/src/main/java/edu/ie3/datamodel/utils/StreamUtils.java b/src/main/java/edu/ie3/datamodel/utils/StreamUtils.java new file mode 100644 index 000000000..bd7ed9347 --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/utils/StreamUtils.java @@ -0,0 +1,72 @@ +/* + * © 2022. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.utils; + +import java.util.Iterator; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; + +/** Class containing some stream utils. */ +public class StreamUtils { + private StreamUtils() {} + + /** + * Used to zip a stream with an integer stream. + * + * @param a the stream that should be zipped + * @return a stream of pairs of input stream elements and a corresponding integer value + * @param type of the input stream + */ + public static Stream> zipWithRowIndex(Stream a) { + return zip(a, getIntStream()); + } + + /** + * Used to zip two stream with each other. + * + * @param a first input stream + * @param b second input stream + * @return a stream of pairs of the two input streams + * @param type of the first input stream + * @param type of the second input stream + */ + public static Stream> zip(Stream a, Stream b) { + return StreamSupport.stream( + Spliterators.spliteratorUnknownSize( + zip(a.iterator(), b.iterator()), Spliterator.ORDERED | Spliterator.NONNULL), + false); + } + + /** + * Used to zip to iterators. + * + * @param a first iterator + * @param b second iterator + * @return an iterator of pairs of the two input iterators + * @param type of the first iterator + * @param type of the second iterator + */ + public static Iterator> zip(Iterator a, Iterator b) { + return new Iterator<>() { + public boolean hasNext() { + return a.hasNext() && b.hasNext(); // This uses the shorter of the two `Iterator`s. + } + + public Pair next() { + return new ImmutablePair<>(a.next(), b.next()); + } + }; + } + + /** Returns an infinite integer stream. */ + private static Stream getIntStream() { + return Stream.iterate(1, i -> i + 1); + } +} diff --git a/src/main/java/edu/ie3/datamodel/utils/Try.java b/src/main/java/edu/ie3/datamodel/utils/Try.java new file mode 100644 index 000000000..40c4f69ce --- /dev/null +++ b/src/main/java/edu/ie3/datamodel/utils/Try.java @@ -0,0 +1,382 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation +*/ +package edu.ie3.datamodel.utils; + +import static java.util.stream.Collectors.partitioningBy; + +import edu.ie3.datamodel.exceptions.FailureException; +import edu.ie3.datamodel.exceptions.TryException; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public abstract class Try { + private final T data; + private final E exception; + private final boolean isEmpty; + + // constructor + /** + * Constructor for {@link Try} used when a {@link Success} is created. + * + * @param data that is stored + */ + protected Try(T data) { + this.data = data; + this.exception = null; + this.isEmpty = data == null; + } + + /** + * Constructor for {@link Try} used when a {@link Failure} is created. + * + * @param ex exception that was thrown + */ + private Try(E ex) { + this.data = null; + this.exception = ex; + isEmpty = true; + } + + /** + * Method to create a {@link Try} object easily. + * + * @param supplier that either returns data or throws an exception + * @param clazz class of the exception + * @return a try object + * @param type of data + * @param type of exception that could be thrown + */ + @SuppressWarnings("unchecked") + public static Try of(TrySupplier supplier, Class clazz) { + try { + return new Success<>(supplier.get()); + } catch (Exception e) { + // this is necessary because we only want to catch exceptions that are of type E + if (e.getClass().isAssignableFrom(clazz)) { + return new Failure<>((E) e); + } else { + throw new TryException("Wrongly caught exception: ", e); + } + } + } + + /** + * Method to create a {@link Try} object easily. + * + * @param supplier that either returns no data or throws an exception + * @param clazz class of the exception + * @return a try object + * @param type of exception that could be thrown + */ + @SuppressWarnings("unchecked") + public static Try ofVoid( + TrySupplier supplier, Class clazz) { + try { + supplier.get(); + return Success.empty(); + } catch (Exception e) { + // this is necessary because we only want to catch exceptions that are of type E + if (e.getClass().isAssignableFrom(clazz)) { + return Failure.ofVoid((E) e); + } else { + throw new TryException("Wrongly caught exception: ", e); + } + } + } + + /** + * Returns true if this object is a {@link Success} or false if this object is a {@link Failure}. + */ + public abstract boolean isSuccess(); + + /** + * Returns true if this object is a {@link Failure} or false if this object is a {@link Success}. + */ + public abstract boolean isFailure(); + + /** Returns true if this object is either a {@link Success} or a {@link Failure}. */ + public boolean isEmpty() { + return isEmpty; + } + + /** + * Method for getting the data. If this object is a {@link Failure} the exception is thrown. + * + * @return data id this object is a {@link Success} + * @throws E if this object is a {@link Failure} + */ + public T getOrThrow() throws E { + if (data != null) { + return data; + } else { + assert exception != null; + throw exception; + } + } + + /** + * This method will return the stored data if this object is a {@link Success} or the given value. + * + * @param value that should be returned if this object is a {@link Failure} + * @return either the stored data or the given value + */ + public T getOrElse(T value) { + return data != null ? data : value; + } + + /** Returns an option for data. */ + public Optional getData() { + return data != null ? Optional.of(data) : Optional.empty(); + } + + /** Returns an option for an exception. */ + public Optional getException() { + return exception != null ? Optional.of(exception) : Optional.empty(); + } + + /** + * Returns the data. WARNING: This method is for internal usage only and should therefore not be + * called for other purposes. + */ + T data() { + return data; + } + + /** + * Returns the exception. WARNING: This method is for internal usage only and should therefore not + * be called for other purposes. + */ + E exception() { + return exception; + } + + // functional methods + + /** + * Method to transform the data if this object is a {@link Success}. + * + * @param mapper that is used to map the data + * @return a new {@link Try} object + * @param type of the data + */ + public Try map(Function mapper) { + return transformS(mapper); + } + + /** + * Method to transform and flat the data. + * + * @param mapper that is used to map the data + * @return a new {@link Try} object + * @param type of the data + */ + @SuppressWarnings("unchecked") + public Try flatMap(Function> mapper) { + Try, E> t = transformS(mapper); + return t instanceof Success, ?> success ? success.data() : (Try) t; + } + + /** + * Method to transform a {@link Try} object. This method should be used, if processing the + * exception is not necessary. + * + * @param successFunc that will be used to transform the data + * @return a new {@link Try} object + * @param type of data + */ + public Try transformS(Function successFunc) { + return isSuccess() ? new Success<>(successFunc.apply(data)) : Failure.of(this.exception); + } + + /** + * Method to transform a {@link Try} object. This method should be used, if only exception should + * be processed. + * + * @param failureFunc that will be used to transform the exception + * @return a new {@link Try} object + * @param type of new exception + */ + public Try transformF(Function failureFunc) { + return isFailure() ? Failure.of(failureFunc.apply(exception)) : new Success<>(data); + } + + /** + * Method to transform a {@link Try} object. This method should be used, if processing the + * exception is necessary. + * + * @param successFunc that will be used to transform the data + * @param failureFunc that will be used to transform the exception + * @return a new {@link Try} object + * @param type of data + */ + public Try transform( + Function successFunc, Function failureFunc) { + if (isSuccess()) { + return new Success<>(successFunc.apply(data)); + } else { + return new Failure<>(failureFunc.apply(exception)); + } + } + + /** + * Method to scan a collection of {@link Try} objects for {@link Failure}'s. + * + * @param c collection of {@link Try} objects + * @param typeOfData type of data + * @return a {@link Success} if no {@link Failure}'s are found in the collection + * @param type of data + */ + public static Try, FailureException> scanCollection( + Collection> c, Class typeOfData) { + return scanStream(c.stream(), typeOfData.getSimpleName()) + .transformS(stream -> stream.collect(Collectors.toSet())); + } + + /** + * Method to scan a stream of {@link Try} objects for {@link Failure}'s. + * + * @param stream of {@link Try} objects + * @return a {@link Success} if no {@link Failure}'s are found in the stream + * @param type of data + */ + public static Try, FailureException> scanStream( + Stream> stream, String typeOfData) { + Map>> map = stream.collect(partitioningBy(Try::isSuccess)); + + List> successes = map.get(true); + List> failures = map.get(false); + + // Both lists should exist in map per definition of partitioningBy + assert successes != null && failures != null; + + if (!failures.isEmpty()) { + E first = failures.get(0).exception; + + return new Failure<>( + new FailureException( + failures.size() + + " exception(s) occurred within \"" + + typeOfData + + "\" data, one is: " + + first, + first.getCause())); + } else { + return new Success<>(successes.stream().map(t -> t.data)); + } + } + + /** + * Method to retrieve the exceptions from all {@link Failure} objects. + * + * @param tries collection of {@link Try} objects + * @return a list of {@link Exception}'s + */ + public static List getExceptions( + Collection> tries) { + return tries.stream().filter(Try::isFailure).map(t -> ((Failure) t).get()).toList(); + } + + /** Implementation of {@link Try} class. This class is used to present a successful try. */ + public static final class Success extends Try { + public Success(T data) { + super(data); + } + + @Override + public boolean isSuccess() { + return true; + } + + @Override + public boolean isFailure() { + return false; + } + + /** Returns the stored data. */ + public T get() { + return data(); + } + + /** + * Returns an empty {@link Success}. + * + * @param type of exception + */ + public static Success empty() { + return new Success<>(null); + } + } + + /** Implementation of {@link Try} class. This class is used to present a failed try. */ + public static final class Failure extends Try { + public Failure(E e) { + super(e); + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public boolean isFailure() { + return true; + } + + /** Returns the thrown exception. */ + public E get() { + return exception(); + } + + /** + * Method to create a {@link Failure} object, when a non-empty {@link Success} can be returned. + * + * @param exception that should be saved + * @return a {@link Failure} + * @param type of data + * @param type of exception + */ + public static Failure of(E exception) { + return new Failure<>(exception); + } + + /** + * Method to create a {@link Failure} object, when an empty {@link Success} can be returned. + * + * @param exception that should be saved + * @return a {@link Failure} + * @param type of exception + */ + public static Failure ofVoid(E exception) { + return new Failure<>(exception); + } + + /** + * Method to transform a {@link Failure} into another {@link Failure}. + * + * @param failure given failure + * @return the transformed failure + * @param type before transformation + * @param type after transformation + */ + public static Failure of(Failure failure) { + return new Failure<>(failure.exception()); + } + } + + /** + * Functional interface for the {@link Try} class. + * + * @param type of data that is supplied + * @param type of exception that could be thrown + */ + @FunctionalInterface + public interface TrySupplier { + T get() throws E; + } +} diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/LineGraphicInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/LineGraphicInputFactoryTest.groovy index 7f5f21ef5..235a5e277 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/LineGraphicInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/LineGraphicInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.graphics +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputEntityData import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputFactory import edu.ie3.datamodel.models.input.connector.LineInput import edu.ie3.datamodel.models.input.graphics.LineGraphicInput import edu.ie3.datamodel.utils.GridAndGeoUtils +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import org.locationtech.jts.geom.LineString import spock.lang.Specification @@ -38,13 +40,13 @@ class LineGraphicInputFactoryTest extends Specification implements FactoryTestHe def lineInput = Mock(LineInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new LineGraphicInputEntityData(parameter, lineInput)) then: - input.present - input.get().getClass() == inputClass - ((LineGraphicInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert path == getGeometry(parameter["path"]) assert graphicLayer == parameter["graphiclayer"] @@ -64,13 +66,13 @@ class LineGraphicInputFactoryTest extends Specification implements FactoryTestHe def lineInput = Mock(LineInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new LineGraphicInputEntityData(parameter, lineInput)) then: - input.present - input.get().getClass() == inputClass - ((LineGraphicInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert path == GridAndGeoUtils.buildSafeLineString(getGeometry(parameter["path"]) as LineString) } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/NodeGraphicInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/NodeGraphicInputFactoryTest.groovy index c98f856ae..0eb4502bc 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/NodeGraphicInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/graphics/NodeGraphicInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.graphics +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputEntityData import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputFactory import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput import edu.ie3.datamodel.utils.GridAndGeoUtils +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import org.locationtech.jts.geom.LineString import spock.lang.Specification @@ -39,13 +41,13 @@ class NodeGraphicInputFactoryTest extends Specification implements FactoryTestHe def nodeInput = Mock(NodeInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeGraphicInputEntityData(parameter, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((NodeGraphicInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert point == getGeometry(parameter["point"]) assert path == getGeometry(parameter["path"]) @@ -68,13 +70,13 @@ class NodeGraphicInputFactoryTest extends Specification implements FactoryTestHe def nodeInput = Mock(NodeInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeGraphicInputEntityData(parameter, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((NodeGraphicInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert path == GridAndGeoUtils.buildSafeLineString(getGeometry(parameter["path"]) as LineString) } where: diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/AssetInputEntityFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/AssetInputEntityFactoryTest.groovy index b6f5b3d7f..8be1628c1 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/AssetInputEntityFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/AssetInputEntityFactoryTest.groovy @@ -9,6 +9,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.AssetInput import edu.ie3.datamodel.models.input.OperatorInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import org.apache.commons.lang3.NotImplementedException import spock.lang.Specification @@ -40,12 +41,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == operatorInput @@ -66,12 +67,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == operatorInput @@ -99,12 +100,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -126,12 +127,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert !operationTime.startDate.present assert operationTime.endDate.present @@ -154,12 +155,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -180,12 +181,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def inputClass = TestAssetInput when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED @@ -204,12 +205,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def inputClass = TestAssetInput when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -230,12 +231,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def inputClass = TestAssetInput when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert !operationTime.startDate.present assert operationTime.endDate.present @@ -257,12 +258,12 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def inputClass = TestAssetInput when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) then: - input.present - input.get().getClass() == inputClass - ((TestAssetInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -284,11 +285,11 @@ class AssetInputEntityFactoryTest extends Specification implements FactoryTestHe def inputClass = TestAssetInput when: - inputFactory.get(new AssetInputEntityData(parameter, inputClass)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass)) then: - FactoryException ex = thrown() - ex.message == + input.failure + input.exception().cause.message == "The provided fields [operatesfrom, operatesuntil, uuid] with data \n" + "{operatesfrom -> 2019-01-01T00:00:00+01:00[Europe/Berlin],\n" + "operatesuntil -> 2019-12-31T00:00:00+01:00[Europe/Berlin],\n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/CylindricalStorageInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/CylindricalStorageInputFactoryTest.groovy index e7d5caa21..a83225f58 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/CylindricalStorageInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/CylindricalStorageInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.CylindricalStorageInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -39,12 +41,12 @@ class CylindricalStorageInputFactoryTest extends Specification implements Facto def thermalBusInput = Mock(ThermalBusInput) when: - Optional input = inputFactory.get(new ThermalUnitInputEntityData(parameter, inputClass, thermalBusInput)) + Try input = inputFactory.get(new ThermalUnitInputEntityData(parameter, inputClass, thermalBusInput)) then: - input.present - input.get().getClass() == inputClass - ((CylindricalStorageInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/LineInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/LineInputFactoryTest.groovy index de99b678a..c30fbe0a9 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/LineInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/LineInputFactoryTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput @@ -12,6 +13,7 @@ import edu.ie3.datamodel.models.input.connector.LineInput import edu.ie3.datamodel.models.input.connector.type.LineTypeInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.utils.GridAndGeoUtils +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import org.locationtech.jts.geom.LineString import spock.lang.Specification @@ -56,12 +58,12 @@ class LineInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(LineTypeInput) when: - Optional input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) + Try input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((LineInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -107,12 +109,12 @@ class LineInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(LineTypeInput) when: - Optional input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) + Try input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((LineInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -158,12 +160,12 @@ class LineInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(LineTypeInput) when: - Optional input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) + Try input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((LineInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert geoPosition == GridAndGeoUtils.buildSafeLineString(getGeometry(parameter["geoposition"]) as LineString) } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/MeasurementUnitInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/MeasurementUnitInputFactoryTest.groovy index 8ace08144..c588255a6 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/MeasurementUnitInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/MeasurementUnitInputFactoryTest.groovy @@ -5,11 +5,12 @@ */ package edu.ie3.datamodel.io.factory.input - +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.MeasurementUnitInput import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -38,12 +39,12 @@ class MeasurementUnitInputFactoryTest extends Specification implements FactoryTe def nodeInput = Mock(NodeInput) when: - Optional input = inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, nodeInput)) + Try input = inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((MeasurementUnitInput) input.get()).with { + input.success + input.data().getClass() == inputClass + ((MeasurementUnitInput) input.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/NodeInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/NodeInputFactoryTest.groovy index 65b6d053e..04223ecb9 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/NodeInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/NodeInputFactoryTest.groovy @@ -5,10 +5,12 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.voltagelevels.GermanVoltageLevelUtils +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.ComparableQuantity @@ -45,12 +47,12 @@ class NodeInputFactoryTest extends Specification implements FactoryTestHelper { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((NodeInput) input.get()).with { + input.success + input.data().getClass() == inputClass + ((NodeInput) input.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/OperatorInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/OperatorInputFactoryTest.groovy index 1cd317aba..2cdf3c0e0 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/OperatorInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/OperatorInputFactoryTest.groovy @@ -5,8 +5,10 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.input.OperatorInput +import edu.ie3.datamodel.utils.Try import spock.lang.Specification class OperatorInputFactoryTest extends Specification { @@ -31,12 +33,12 @@ class OperatorInputFactoryTest extends Specification { def inputClass = OperatorInput when: - Optional input = inputFactory.get(new SimpleEntityData(parameter, inputClass)) + Try input = inputFactory.get(new SimpleEntityData(parameter, inputClass)) then: - input.present - input.get().getClass() == inputClass - ((OperatorInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/SwitchInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/SwitchInputFactoryTest.groovy index 795f96e12..8a84c68fa 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/SwitchInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/SwitchInputFactoryTest.groovy @@ -5,9 +5,11 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.connector.SwitchInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -39,12 +41,12 @@ class SwitchInputFactoryTest extends Specification implements FactoryTestHelper def nodeInputB = Mock(NodeInput) when: - Optional input = inputFactory.get(new ConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB)) + Try input = inputFactory.get(new ConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB)) then: - input.present - input.get().getClass() == inputClass - ((SwitchInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalBusInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalBusInputFactoryTest.groovy index 0b7e17478..d639fdc9e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalBusInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalBusInputFactoryTest.groovy @@ -5,8 +5,10 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -35,12 +37,12 @@ class ThermalBusInputFactoryTest extends Specification implements FactoryTestHel def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) + Try input = inputFactory.get(new AssetInputEntityData(parameter, inputClass, operatorInput)) then: - input.present - input.get().getClass() == inputClass - ((ThermalBusInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy index 40b875d29..0e6546626 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/ThermalHouseInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.models.input.thermal.ThermalHouseInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -39,12 +41,12 @@ class ThermalHouseInputFactoryTest extends Specification implements FactoryTestH def thermalBusInput = Mock(ThermalBusInput) when: - Optional input = inputFactory.get(new ThermalUnitInputEntityData(parameter, inputClass, thermalBusInput)) + Try input = inputFactory.get(new ThermalUnitInputEntityData(parameter, inputClass, thermalBusInput)) then: - input.present - input.get().getClass() == inputClass - ((ThermalHouseInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer2WInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer2WInputFactoryTest.groovy index 2d085cd92..e99acca8e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer2WInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer2WInputFactoryTest.groovy @@ -5,10 +5,12 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.connector.Transformer2WInput import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -43,12 +45,12 @@ class Transformer2WInputFactoryTest extends Specification implements FactoryTest def typeInput = Mock(Transformer2WTypeInput) when: - Optional input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) + Try input = inputFactory.get(new TypedConnectorInputEntityData(parameter, inputClass, operatorInput, nodeInputA, nodeInputB, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((Transformer2WInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer3WInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer3WInputFactoryTest.groovy index 051448604..a2a73912c 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer3WInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/Transformer3WInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.datamodel.models.input.connector.type.Transformer3WTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -40,12 +42,12 @@ class Transformer3WInputFactoryTest extends Specification implements FactoryTes def typeInput = Mock(Transformer3WTypeInput) when: - Optional input = inputFactory.get(new Transformer3WInputEntityData(parameter, inputClass, nodeInputA, nodeInputB, nodeInputC, typeInput)) + Try input = inputFactory.get(new Transformer3WInputEntityData(parameter, inputClass, nodeInputA, nodeInputB, nodeInputC, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((Transformer3WInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/BmInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/BmInputFactoryTest.groovy index 7940b9bdb..75461033a 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/BmInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/BmInputFactoryTest.groovy @@ -5,12 +5,14 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.BmInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.BmTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -49,13 +51,13 @@ class BmInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(BmTypeInput) when: - Optional input = inputFactory.get( - new SystemParticipantTypedEntityData(parameter, inputClass,operatorInput, nodeInput, typeInput)) + Try input = inputFactory.get( + new SystemParticipantTypedEntityData(parameter, inputClass, operatorInput, nodeInput, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((BmInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/ChpInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/ChpInputFactoryTest.groovy index 0de257f6e..537e63a84 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/ChpInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/ChpInputFactoryTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.ChpInput @@ -12,6 +13,7 @@ import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.ChpTypeInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -50,13 +52,13 @@ class ChpInputFactoryTest extends Specification implements FactoryTestHelper { def thermalStorageInput = Mock(ThermalStorageInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new ChpInputEntityData(parameter, operatorInput, nodeInput, typeInput, thermalBusInput, thermalStorageInput)) then: - input.present - input.get().getClass() == inputClass - ((ChpInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EmInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EmInputFactoryTest.groovy index 40ed1d634..ea130b6de 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EmInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EmInputFactoryTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData import edu.ie3.datamodel.models.ControlStrategy import edu.ie3.datamodel.models.EmControlStrategy @@ -12,6 +13,7 @@ import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.EmInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint +import edu.ie3.datamodel.utils.Try import edu.ie3.util.quantities.PowerSystemUnits import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -47,13 +49,13 @@ class EmInputFactoryTest extends Specification { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((EmInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -92,13 +94,13 @@ class EmInputFactoryTest extends Specification { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((EmInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -132,13 +134,13 @@ class EmInputFactoryTest extends Specification { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((EmInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.empty assert operationTime.endDate.empty diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvInputFactoryTest.groovy index 3e6110395..9ce6086ca 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.EvInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.EvTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -45,13 +47,13 @@ class EvInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(EvTypeInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new SystemParticipantTypedEntityData(parameter, inputClass, operatorInput, nodeInput, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((EvInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvcsInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvcsInputFactoryTest.groovy index d01e29071..4142a6305 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvcsInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/EvcsInputFactoryTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput @@ -12,6 +13,7 @@ import edu.ie3.datamodel.models.input.system.EvcsInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.chargingpoint.ChargingPointTypeUtils import edu.ie3.datamodel.models.input.system.type.evcslocation.EvcsLocationType +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import edu.ie3.util.quantities.PowerSystemUnits import spock.lang.Specification @@ -55,13 +57,13 @@ class EvcsInputFactoryTest extends Specification implements FactoryTestHelper { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((EvcsInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -104,12 +106,12 @@ class EvcsInputFactoryTest extends Specification implements FactoryTestHelper { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - // FactoryException is caught in Factory.java. We get an empty Option back - !input.present + input.failure + input.exception().cause.message == "Exception while trying to parse field \"type\" with supposed int value \"-- invalid --\"" } def "A EvcsInputFactory should fail when passing an invalid EvcsLocationType"() { @@ -132,11 +134,11 @@ class EvcsInputFactoryTest extends Specification implements FactoryTestHelper { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - // FactoryException is caught in Factory.java. We get an empty Option back - !input.present + input.failure + input.exception().cause.message == "Exception while trying to parse field \"locationtype\" with supposed int value \"-- invalid --\"" } } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/FixedFeedInInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/FixedFeedInInputFactoryTest.groovy index 68aaaff58..98404d821 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/FixedFeedInInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/FixedFeedInInputFactoryTest.groovy @@ -12,6 +12,7 @@ import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.FixedFeedInInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -48,12 +49,12 @@ class FixedFeedInInputFactoryTest extends Specification implements FactoryTestHe def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) + Try input = inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((FixedFeedInInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) @@ -85,11 +86,11 @@ class FixedFeedInInputFactoryTest extends Specification implements FactoryTestHe def nodeInput = Mock(NodeInput) when: - inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, nodeInput)) + Try input = inputFactory.get(new NodeAssetInputEntityData(parameter, inputClass, nodeInput)) then: - FactoryException ex = thrown() - ex.message == "The provided fields [cosphirated, id, srated, uuid] with data \n" + + input.failure + input.exception().cause.message == "The provided fields [cosphirated, id, srated, uuid] with data \n" + "{cosphirated -> 4,\n" + "id -> TestID,\n" + "srated -> 3,\n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/HpInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/HpInputFactoryTest.groovy index 60b7d52fe..e82a0e04f 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/HpInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/HpInputFactoryTest.groovy @@ -5,12 +5,14 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.HpInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.HpTypeInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -47,13 +49,13 @@ class HpInputFactoryTest extends Specification implements FactoryTestHelper { def thermalBusInput = Mock(ThermalBusInput) when: - Optional input = inputFactory.get( - new HpInputEntityData(parameter,operatorInput, nodeInput, typeInput, thermalBusInput)) + Try input = inputFactory.get( + new HpInputEntityData(parameter, operatorInput, nodeInput, typeInput, thermalBusInput)) then: - input.present - input.get().getClass() == inputClass - ((HpInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/LoadInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/LoadInputFactoryTest.groovy index 042f457ee..40c177453 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/LoadInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/LoadInputFactoryTest.groovy @@ -5,15 +5,17 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData -import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.OperationTime import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.LoadInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint +import edu.ie3.datamodel.models.profile.BdewStandardLoadProfile import edu.ie3.datamodel.models.profile.NbwTemperatureDependantLoadProfile +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -49,13 +51,13 @@ class LoadInputFactoryTest extends Specification implements FactoryTestHelper { "srated" : "4", "cosphirated" : "5" ] - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((LoadInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime == OperationTime.notLimited() assert operator == OperatorInput.NO_OPERATOR_ASSIGNED diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/PvInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/PvInputFactoryTest.groovy index 425fd3592..431765355 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/PvInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/PvInputFactoryTest.groovy @@ -5,12 +5,14 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.PvInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -54,13 +56,13 @@ class PvInputFactoryTest extends Specification implements FactoryTestHelper { def operatorInput = Mock(OperatorInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new NodeAssetInputEntityData(parameter, inputClass, operatorInput, nodeInput)) then: - input.present - input.get().getClass() == inputClass - ((PvInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/StorageInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/StorageInputFactoryTest.groovy index 71e261663..6522aa7b2 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/StorageInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/StorageInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.StorageInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.StorageTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -45,13 +47,13 @@ class StorageInputFactoryTest extends Specification implements FactoryTestHelper def typeInput = Mock(StorageTypeInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new SystemParticipantTypedEntityData(parameter, inputClass, operatorInput, nodeInput, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((StorageInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert operationTime.startDate.present assert operationTime.startDate.get() == ZonedDateTime.parse(parameter["operatesfrom"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/WecInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/WecInputFactoryTest.groovy index 5c4fc5f17..88076ca7a 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/WecInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/input/participant/WecInputFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.input.participant +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.system.WecInput import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.WecTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -46,13 +48,13 @@ class WecInputFactoryTest extends Specification implements FactoryTestHelper { def typeInput = Mock(WecTypeInput) when: - Optional input = inputFactory.get( + Try input = inputFactory.get( new SystemParticipantTypedEntityData(parameter, inputClass, operatorInput, nodeInput, typeInput)) then: - input.present - input.get().getClass() == inputClass - ((WecInput) input.get()).with { + input.success + input.data().getClass() == inputClass + input.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert !operationTime.startDate.present assert operationTime.endDate.present diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ConnectorResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ConnectorResultFactoryTest.groovy index 985c208af..caa2a74be 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ConnectorResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ConnectorResultFactoryTest.groovy @@ -5,12 +5,14 @@ */ package edu.ie3.datamodel.io.factory.result +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.connector.ConnectorResult import edu.ie3.datamodel.models.result.connector.LineResult import edu.ie3.datamodel.models.result.connector.Transformer2WResult import edu.ie3.datamodel.models.result.connector.Transformer3WResult +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -51,12 +53,12 @@ class ConnectorResultFactoryTest extends Specification implements FactoryTestHel } when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, modelClass)) + Try result = resultFactory.get(new SimpleEntityData(parameter, modelClass)) then: - result.present - result.get().getClass() == resultingModelClass - ((ConnectorResult) result.get()).with { + result.success + result.data().getClass() == resultingModelClass + ((ConnectorResult) result.data()).with { assert time == TIME_UTIL.toZonedDateTime(parameter["time"]) assert inputModel == UUID.fromString(parameter["inputModel"]) assert iAAng == getQuant(parameter["iaang"], StandardUnits.ELECTRIC_CURRENT_ANGLE) @@ -65,12 +67,12 @@ class ConnectorResultFactoryTest extends Specification implements FactoryTestHel assert iBMag == getQuant(parameter["ibmag"], StandardUnits.ELECTRIC_CURRENT_MAGNITUDE) } - if (result.get().getClass() == Transformer2WResult) { - assert ((Transformer2WResult) result.get()).tapPos == Integer.parseInt(parameter["tappos"]) + if (result.data().getClass() == Transformer2WResult) { + assert ((Transformer2WResult) result.data()).tapPos == Integer.parseInt(parameter["tappos"]) } - if (result.get().getClass() == Transformer3WResult) { - Transformer3WResult transformer3WResult = ((Transformer3WResult) result.get()) + if (result.data().getClass() == Transformer3WResult) { + Transformer3WResult transformer3WResult = ((Transformer3WResult) result.data()) assert transformer3WResult.tapPos == Integer.parseInt(parameter["tappos"]) assert transformer3WResult.iCAng == getQuant(parameter["icang"], StandardUnits.ELECTRIC_CURRENT_ANGLE) assert transformer3WResult.iCMag == getQuant(parameter["icmag"], StandardUnits.ELECTRIC_CURRENT_MAGNITUDE) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactoryTest.groovy index 685632855..bf5399dab 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/FlexOptionsResultFactoryTest.groovy @@ -9,6 +9,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.system.FlexOptionsResult +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -35,12 +36,12 @@ class FlexOptionsResultFactoryTest extends Specification implements FactoryTestH ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, FlexOptionsResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, FlexOptionsResult)) then: - result.present - result.get().getClass() == FlexOptionsResult - ((FlexOptionsResult) result.get()).with { + result.success + result.data().getClass() == FlexOptionsResult + ((FlexOptionsResult) result.data()).with { assert pRef == getQuant(parameter["pref"], StandardUnits.ACTIVE_POWER_RESULT) assert pMin == getQuant(parameter["pmin"], StandardUnits.ACTIVE_POWER_RESULT) assert pMax == getQuant(parameter["pmax"], StandardUnits.ACTIVE_POWER_RESULT) @@ -60,11 +61,11 @@ class FlexOptionsResultFactoryTest extends Specification implements FactoryTestH ] when: - resultFactory.get(new SimpleEntityData(parameter, FlexOptionsResult)) + Try input = resultFactory.get(new SimpleEntityData(parameter, FlexOptionsResult)) then: - FactoryException ex = thrown() - ex.message == "The provided fields [inputModel, pmin, pref, time] with data \n" + + input.failure + input.exception().cause.message == "The provided fields [inputModel, pmin, pref, time] with data \n" + "{inputModel -> 91ec3bcf-1897-4d38-af67-0bf7c9fa73c7,\n" + "pmin -> -1,\n" + "pref -> 2,\n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/NodeResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/NodeResultFactoryTest.groovy index 44b55bde6..dbabd1376 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/NodeResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/NodeResultFactoryTest.groovy @@ -9,6 +9,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.NodeResult +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -34,12 +35,12 @@ class NodeResultFactoryTest extends Specification implements FactoryTestHelper { ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, NodeResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, NodeResult)) then: - result.present - result.get().getClass() == NodeResult - ((NodeResult) result.get()).with { + result.success + result.data().getClass() == NodeResult + ((NodeResult) result.data()).with { assert vMag == getQuant(parameter["vmag"], StandardUnits.VOLTAGE_MAGNITUDE) assert vAng == getQuant(parameter["vang"], StandardUnits.VOLTAGE_ANGLE) assert time == TIME_UTIL.toZonedDateTime(parameter["time"]) @@ -57,11 +58,11 @@ class NodeResultFactoryTest extends Specification implements FactoryTestHelper { ] when: - resultFactory.get(new SimpleEntityData(parameter, NodeResult)) + Try input = resultFactory.get(new SimpleEntityData(parameter, NodeResult)) then: - FactoryException ex = thrown() - ex.message == "The provided fields [inputModel, time, vmag] with data \n" + + input.failure + input.exception().cause.message == "The provided fields [inputModel, time, vmag] with data \n" + "{inputModel -> 91ec3bcf-1897-4d38-af67-0bf7c9fa73c7,\n" + "time -> 2020-01-30 17:26:44,\n" + "vmag -> 2} are invalid for instance of NodeResult. \n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/SwitchResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/SwitchResultFactoryTest.groovy index ec5bd35a4..ddb9f64ba 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/SwitchResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/SwitchResultFactoryTest.groovy @@ -5,8 +5,10 @@ */ package edu.ie3.datamodel.io.factory.result +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.result.connector.SwitchResult +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -33,12 +35,12 @@ class SwitchResultFactoryTest extends Specification implements FactoryTestHelper ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, SwitchResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, SwitchResult)) then: - result.present - result.get().getClass() == SwitchResult - ((SwitchResult) result.get()).with { + result.success + result.data().getClass() == SwitchResult + ((SwitchResult) result.data()).with { assert time == TIME_UTIL.toZonedDateTime(parameter["time"]) assert inputModel == UUID.fromString(parameter["inputModel"]) assert closed == Boolean.parseBoolean(parameter["closed"]) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactoryTest.groovy index 0be343451..758c1a61c 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/SystemParticipantResultFactoryTest.groovy @@ -9,6 +9,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.system.* +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.unit.Units @@ -55,12 +56,12 @@ class SystemParticipantResultFactoryTest extends Specification implements Factor } when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, modelClass)) + Try result = resultFactory.get(new SimpleEntityData(parameter, modelClass)) then: - result.present - result.get().getClass() == resultingModelClass - ((SystemParticipantResult) result.get()).with { + result.success + result.data().getClass() == resultingModelClass + ((SystemParticipantResult) result.data()).with { assert p == getQuant(parameter["p"], StandardUnits.ACTIVE_POWER_RESULT) assert q == getQuant(parameter["q"], StandardUnits.REACTIVE_POWER_RESULT) assert time == TIME_UTIL.toZonedDateTime(parameter["time"]) @@ -68,19 +69,19 @@ class SystemParticipantResultFactoryTest extends Specification implements Factor } if (modelClass == EvResult) { - assert (((EvResult) result.get()).soc == getQuant(parameter["soc"], Units.PERCENT)) + assert (((EvResult) result.data()).soc == getQuant(parameter["soc"], Units.PERCENT)) } if (modelClass == StorageResult) { - assert (((StorageResult) result.get()).soc == getQuant(parameter["soc"], Units.PERCENT)) + assert (((StorageResult) result.data()).soc == getQuant(parameter["soc"], Units.PERCENT)) } if (modelClass == HpResult) { - assert(((HpResult)result.get()).getqDot() == getQuant(parameter["qDot"], StandardUnits.Q_DOT_RESULT)) + assert(((HpResult) result.data()).getqDot() == getQuant(parameter["qDot"], StandardUnits.Q_DOT_RESULT)) } if (modelClass == ChpResult) { - assert(((ChpResult)result.get()).getqDot() == getQuant(parameter["qDot"], StandardUnits.Q_DOT_RESULT)) + assert(((ChpResult) result.data()).getqDot() == getQuant(parameter["qDot"], StandardUnits.Q_DOT_RESULT)) } where: @@ -109,12 +110,12 @@ class SystemParticipantResultFactoryTest extends Specification implements Factor "q" : "2" ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, StorageResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, StorageResult)) then: - result.present - result.get().getClass() == StorageResult - ((StorageResult) result.get()).with { + result.success + result.data().getClass() == StorageResult + ((StorageResult) result.data()).with { assert p == getQuant(parameter["p"], StandardUnits.ACTIVE_POWER_RESULT) assert q == getQuant(parameter["q"], StandardUnits.REACTIVE_POWER_RESULT) assert soc == getQuant(parameter["soc"], Units.PERCENT) @@ -132,11 +133,11 @@ class SystemParticipantResultFactoryTest extends Specification implements Factor "q" : "2" ] when: - resultFactory.get(new SimpleEntityData(parameter, WecResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, WecResult)) then: - FactoryException ex = thrown() - ex.message == "The provided fields [inputModel, q, time] with data \n" + + result.failure + result.exception().cause.message == "The provided fields [inputModel, q, time] with data \n" + "{inputModel -> 91ec3bcf-1777-4d38-af67-0bf7c9fa73c7,\n" + "q -> 2,\n" + "time -> 2020-01-30 17:26:44} are invalid for instance of WecResult. \n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy index 4e0fb66ca..811bf5202 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/result/ThermalResultFactoryTest.groovy @@ -5,11 +5,13 @@ */ package edu.ie3.datamodel.io.factory.result +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.result.thermal.CylindricalStorageResult import edu.ie3.datamodel.models.result.thermal.ThermalHouseResult import edu.ie3.datamodel.models.result.thermal.ThermalUnitResult +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -39,12 +41,12 @@ class ThermalResultFactoryTest extends Specification implements FactoryTestHelpe "fillLevel" : "20" ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, CylindricalStorageResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, CylindricalStorageResult)) then: - result.present - result.get().getClass() == CylindricalStorageResult - ((CylindricalStorageResult) result.get()).with { + result.success + result.data().getClass() == CylindricalStorageResult + ((CylindricalStorageResult) result.data()).with { assert time == TIME_UTIL.toZonedDateTime(parameter.get("time")) assert inputModel == UUID.fromString(parameter.get("inputModel")) assert qDot == Quantities.getQuantity(Double.parseDouble(parameter.get("qDot")), StandardUnits.HEAT_DEMAND) @@ -63,12 +65,12 @@ class ThermalResultFactoryTest extends Specification implements FactoryTestHelpe "indoorTemperature": "21" ] when: - Optional result = resultFactory.get(new SimpleEntityData(parameter, ThermalHouseResult)) + Try result = resultFactory.get(new SimpleEntityData(parameter, ThermalHouseResult)) then: - result.present - result.get().getClass() == ThermalHouseResult - ((ThermalHouseResult) result.get()).with { + result.success + result.data().getClass() == ThermalHouseResult + ((ThermalHouseResult) result.data()).with { assert time == TIME_UTIL.toZonedDateTime(parameter.get("time")) assert inputModel == UUID.fromString(parameter.get("inputModel")) assert qDot == Quantities.getQuantity(Double.parseDouble(parameter.get("qDot")), StandardUnits.HEAT_DEMAND) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/CosmoIdCoordinateFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/CosmoIdCoordinateFactoryTest.groovy index 8ca8bbd6a..3ab508f2c 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/CosmoIdCoordinateFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/CosmoIdCoordinateFactoryTest.groovy @@ -5,7 +5,6 @@ */ package edu.ie3.datamodel.io.factory.timeseries -import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleFactoryData import edu.ie3.util.geo.GeoUtils import org.apache.commons.lang3.tuple.Pair @@ -31,14 +30,18 @@ class CosmoIdCoordinateFactoryTest extends Specification { "latgeo", "longgeo" ] as Set - def validSimpleFactoryData = new SimpleFactoryData([ + + Map parameter = [ "tid": "1", "id": "106580", "latgeo": "39.602772", "longgeo": "1.279336", "latrot": "-10", "longrot": "-6.8125" - ] as Map, Pair) + ] + + + def validSimpleFactoryData = new SimpleFactoryData(parameter, Pair) when: @@ -51,40 +54,44 @@ class CosmoIdCoordinateFactoryTest extends Specification { def "A COSMO id to coordinate factory refuses to build from invalid data"() { given: - def invalidSimpleFactoryData = new SimpleFactoryData([ + Map parameter = [ "tid": "1", "id": "106580", "latrot": "-10", "longrot": "-6.8125" - ] as Map, Pair) + ] + + def invalidSimpleFactoryData = new SimpleFactoryData(parameter, Pair) when: - factory.get(invalidSimpleFactoryData) + def actual = factory.get(invalidSimpleFactoryData) then: - def e = thrown(FactoryException) - e.message.startsWith("The provided fields [id, latrot, longrot, tid] with data \n{id -> 106580,\nlatrot" + + actual.failure + actual.exception().cause.message.startsWith("The provided fields [id, latrot, longrot, tid] with data \n{id -> 106580,\nlatrot" + " -> -10,\nlongrot -> -6.8125,\ntid -> 1} are invalid for instance of Pair.") } def "A COSMO id to coordinate factory builds model from valid data"() { given: - def validSimpleFactoryData = new SimpleFactoryData([ + Map parameter = [ "tid": "1", "id": "106580", "latgeo": "39.602772", "longgeo": "1.279336", "latrot": "-10", "longrot": "-6.8125" - ] as Map, Pair) + ] + + def validSimpleFactoryData = new SimpleFactoryData(parameter, Pair) Pair expectedPair = Pair.of(106580, GeoUtils.buildPoint(39.602772, 1.279336)) when: def actual = factory.get(validSimpleFactoryData) then: - actual.present - actual.get().with { + actual.success + actual.data().with { assert it.key == expectedPair.key assert it.value.equalsExact(expectedPair.value, 1E-6) } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/IconIdCoordinateFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/IconIdCoordinateFactoryTest.groovy index d4a004b79..23af78bf0 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/IconIdCoordinateFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/IconIdCoordinateFactoryTest.groovy @@ -5,7 +5,6 @@ */ package edu.ie3.datamodel.io.factory.timeseries -import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleFactoryData import edu.ie3.util.geo.GeoUtils import org.apache.commons.lang3.tuple.Pair @@ -29,11 +28,13 @@ class IconIdCoordinateFactoryTest extends Specification { "longitude", "coordinatetype" ] as Set - def validSimpleFactoryData = new SimpleFactoryData([ + Map parameter = [ "id":"477295", "latitude":"52.312", "longitude":"12.812", - "coordinatetype":"ICON"] as Map, Pair) + "coordinatetype":"ICON"] + + def validSimpleFactoryData = new SimpleFactoryData(parameter, Pair) when: def actual = factory.getFields(validSimpleFactoryData) @@ -45,35 +46,38 @@ class IconIdCoordinateFactoryTest extends Specification { def "A COSMO id to coordinate factory refuses to build from invalid data"() { given: - def invalidSimpleFactoryData = new SimpleFactoryData([ + Map parameter = [ "id":"477295", "latitude":"52.312", - "coordinatetype":"ICON"] as Map, Pair) + "coordinatetype":"ICON"] + + def invalidSimpleFactoryData = new SimpleFactoryData(parameter, Pair) when: - factory.get(invalidSimpleFactoryData) + def actual = factory.get(invalidSimpleFactoryData) then: - def e = thrown(FactoryException) - e.message.startsWith("The provided fields [coordinatetype, id, latitude] with data \n{coordinatetype -> " + + actual.failure + actual.exception().cause.message.startsWith("The provided fields [coordinatetype, id, latitude] with data \n{coordinatetype -> " + "ICON,\nid -> 477295,\nlatitude -> 52.312} are invalid for instance of Pair. ") } def "A COSMO id to coordinate factory builds model from valid data"() { given: - def validSimpleFactoryData = new SimpleFactoryData([ + Map parameter = [ "id":"477295", "latitude":"52.312", "longitude":"12.812", - "coordinatetype":"ICON"] as Map, Pair) + "coordinatetype":"ICON"] + def validSimpleFactoryData = new SimpleFactoryData(parameter, Pair) Pair expectedPair = Pair.of(477295, GeoUtils.buildPoint(52.312, 12.812)) when: def actual = factory.get(validSimpleFactoryData) then: - actual.present - actual.get().with { + actual.success + actual.data().with { assert it.key == expectedPair.key assert it.value.equalsExact(expectedPair.value, 1E-6) } diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/TimeBasedSimpleValueFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/TimeBasedSimpleValueFactoryTest.groovy index e05cd8989..a91436c4e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/TimeBasedSimpleValueFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/timeseries/TimeBasedSimpleValueFactoryTest.groovy @@ -11,12 +11,7 @@ import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue -import edu.ie3.datamodel.models.value.EnergyPriceValue -import edu.ie3.datamodel.models.value.HeatAndPValue -import edu.ie3.datamodel.models.value.HeatAndSValue -import edu.ie3.datamodel.models.value.HeatDemandValue -import edu.ie3.datamodel.models.value.PValue -import edu.ie3.datamodel.models.value.SValue +import edu.ie3.datamodel.models.value.* import edu.ie3.util.TimeUtil import spock.lang.Shared import spock.lang.Specification diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/LineTypeInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/LineTypeInputFactoryTest.groovy index a5304c04c..4c47f1f19 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/LineTypeInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/LineTypeInputFactoryTest.groovy @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.factory.typeinput +import edu.ie3.datamodel.exceptions.FactoryException +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits @@ -38,12 +40,12 @@ class LineTypeInputFactoryTest extends Specification implements FactoryTestHelpe def typeInputClass = LineTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass - ((LineTypeInput) typeInput.get()).with { + typeInput.success + typeInput.data().getClass() == typeInputClass + typeInput.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert b == getQuant(parameter["b"], StandardUnits.SUSCEPTANCE_PER_LENGTH) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/SystemParticipantTypeInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/SystemParticipantTypeInputFactoryTest.groovy index 5c5cd1d8f..81a9b74db 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/SystemParticipantTypeInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/SystemParticipantTypeInputFactoryTest.groovy @@ -10,6 +10,7 @@ import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.system.characteristic.CharacteristicPoint import edu.ie3.datamodel.models.input.system.type.* +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification import tech.units.indriya.quantity.Quantities @@ -55,13 +56,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = EvTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((EvTypeInput) typeInput.get()).with { + ((EvTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -90,13 +91,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = HpTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((HpTypeInput) typeInput.get()).with { + ((HpTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -124,13 +125,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = BmTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((BmTypeInput) typeInput.get()).with { + ((BmTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -162,13 +163,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = WecTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((WecTypeInput) typeInput.get()).with { + ((WecTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -209,13 +210,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = ChpTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((ChpTypeInput) typeInput.get()).with { + ((ChpTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -252,13 +253,13 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac def typeInputClass = StorageTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - ((StorageTypeInput) typeInput.get()).with { + ((StorageTypeInput) typeInput.data()).with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert capex == getQuant(parameter["capex"], StandardUnits.CAPEX) @@ -295,11 +296,11 @@ class SystemParticipantTypeInputFactoryTest extends Specification implements Fac ] when: - typeInputFactory.get(new SimpleEntityData(parameter, StorageTypeInput)) + Try input = typeInputFactory.get(new SimpleEntityData(parameter, StorageTypeInput)) then: - FactoryException ex = thrown() - ex.message == "The provided fields [capex, cosPhiRated, dod, estorage, eta, id, lifetime, opex, pmax, pmin, srated, uuid] with data \n" + + input.failure + input.exception().cause.message == "The provided fields [capex, cosPhiRated, dod, estorage, eta, id, lifetime, opex, pmax, pmin, srated, uuid] with data \n" + "{capex -> 3,\n" + "cosPhiRated -> 6,\n" + "dod -> 10,\n" + diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer2WTypeInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer2WTypeInputFactoryTest.groovy index 53d197b31..0561bf3d2 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer2WTypeInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer2WTypeInputFactoryTest.groovy @@ -5,9 +5,11 @@ */ package edu.ie3.datamodel.io.factory.typeinput +import edu.ie3.datamodel.exceptions.FactoryException import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits import edu.ie3.datamodel.models.input.connector.type.Transformer2WTypeInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import spock.lang.Specification @@ -45,13 +47,13 @@ class Transformer2WTypeInputFactoryTest extends Specification implements Factory def typeInputClass = Transformer2WTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - typeInput.get().with { + typeInput.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert rSc == getQuant(parameter["rsc"], StandardUnits.RESISTANCE) diff --git a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer3WTypeInputFactoryTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer3WTypeInputFactoryTest.groovy index 0c204f2cb..039b9eeeb 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer3WTypeInputFactoryTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/factory/typeinput/Transformer3WTypeInputFactoryTest.groovy @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.factory.typeinput +import edu.ie3.datamodel.exceptions.FactoryException +import edu.ie3.datamodel.utils.Try import edu.ie3.test.helper.FactoryTestHelper import edu.ie3.datamodel.io.factory.SimpleEntityData import edu.ie3.datamodel.models.StandardUnits @@ -51,13 +53,13 @@ class Transformer3WTypeInputFactoryTest extends Specification implements Factory def typeInputClass = Transformer3WTypeInput when: - Optional typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) + Try typeInput = typeInputFactory.get(new SimpleEntityData(parameter, typeInputClass)) then: - typeInput.present - typeInput.get().getClass() == typeInputClass + typeInput.success + typeInput.data().getClass() == typeInputClass - typeInput.get().with { + typeInput.data().with { assert uuid == UUID.fromString(parameter["uuid"]) assert id == parameter["id"] assert sRatedA == getQuant(parameter["srateda"], StandardUnits.S_RATED) diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/EntitySourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/EntitySourceTest.groovy index d42b393a2..48247e0bb 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/EntitySourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/EntitySourceTest.groovy @@ -72,8 +72,8 @@ class EntitySourceTest extends Specification { def assetTypeOpt = dummyEntitySource.getAssetType(types, fieldsToAttributes, "TestClassName") then: - assetTypeOpt.present == resultIsPresent - assetTypeOpt.ifPresent({ assetType -> + assetTypeOpt.data.present == resultIsPresent + assetTypeOpt.data.ifPresent({ assetType -> assert (assetType == resultData) }) @@ -100,7 +100,7 @@ class EntitySourceTest extends Specification { then: noExceptionThrown() // no NPE should be thrown - thermalBusInputEntity.present - thermalBusInputEntity.get().operator.id == OperatorInput.NO_OPERATOR_ASSIGNED.id // operator id should be set accordingly + thermalBusInputEntity.success + thermalBusInputEntity.data().operator.id == OperatorInput.NO_OPERATOR_ASSIGNED.id // operator id should be set accordingly } } diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy index 2120d9fe3..5376773bb 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvGraphicSourceTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.exceptions.SourceException import edu.ie3.datamodel.io.factory.input.graphics.LineGraphicInputEntityData import edu.ie3.datamodel.io.factory.input.graphics.NodeGraphicInputEntityData import edu.ie3.datamodel.io.source.GraphicSource @@ -13,6 +14,7 @@ import edu.ie3.datamodel.io.source.TypeSource import edu.ie3.datamodel.models.input.NodeInput import edu.ie3.datamodel.models.input.OperatorInput import edu.ie3.datamodel.models.input.graphics.NodeGraphicInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.common.GridTestData as gtd import org.locationtech.jts.geom.LineString import org.locationtech.jts.geom.Point @@ -28,63 +30,65 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def csvGraphicSource = new GraphicSource(typeSource, rawGridSource, new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) when: - def graphicElementsOpt = csvGraphicSource.getGraphicElements() + def graphicElements = csvGraphicSource.graphicElements then: - graphicElementsOpt.present - graphicElementsOpt.ifPresent({ - assert (it.allEntitiesAsList().size() == 3) - assert (it.nodeGraphics.size() == 2) - assert (it.lineGraphics.size() == 1) - }) + graphicElements.allEntitiesAsList().size() == 3 + graphicElements.nodeGraphics.size() == 2 + graphicElements.lineGraphics.size() == 1 } def "A CsvGraphicSource should process invalid input data as expected when requested to provide an instance of GraphicElements"() { given: def typeSource = new TypeSource(new CsvDataSource(csvSep, typeFolderPath, fileNamingStrategy)) def rawGridSource = - new RawGridSource(typeSource, new CsvDataSource(csvSep, gridDefaultFolderPath, fileNamingStrategy)) { - @Override - Set getNodes() { - return Collections.emptySet() - } - - @Override - Set getNodes(Set operators) { - return Collections.emptySet() - } - } + new RawGridSource(typeSource, new CsvDataSource(csvSep, gridDefaultFolderPath, fileNamingStrategy)) { + @Override + Set getNodes() { + return Collections.emptySet() + } + + @Override + Set getNodes(Set operators) { + return Collections.emptySet() + } + } def csvGraphicSource = new GraphicSource(typeSource, rawGridSource, new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) when: - def graphicElementsOpt = csvGraphicSource.getGraphicElements() + def graphicElements = Try.of(() -> csvGraphicSource.graphicElements, SourceException) then: - !graphicElementsOpt.present + graphicElements.failure + graphicElements.data == Optional.empty() + + Exception ex = graphicElements.exception() + ex.class == SourceException + ex.message.startsWith("edu.ie3.datamodel.exceptions.FailureException: 2 exception(s) occurred within \"LineInput\" data, one is: edu.ie3.datamodel.exceptions.FactoryException: edu.ie3.datamodel.exceptions.SourceException: Failure due to: Skipping LineInput with uuid") } def "A CsvGraphicSource should read and handle a valid node graphics file as expected"() { given: def csvGraphicSource = new GraphicSource( - Mock(TypeSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) def expectedNodeGraphicD = new NodeGraphicInput( - gtd.nodeGraphicD.uuid, - gtd.nodeGraphicD.graphicLayer, - gtd.nodeGraphicD.path, - gtd.nodeD, - gtd.geoJsonReader.read("{ \"type\": \"Point\", \"coordinates\": [7.4116482, 51.4843281] }") as Point - ) + gtd.nodeGraphicD.uuid, + gtd.nodeGraphicD.graphicLayer, + gtd.nodeGraphicD.path, + gtd.nodeD, + gtd.geoJsonReader.read("{ \"type\": \"Point\", \"coordinates\": [7.4116482, 51.4843281] }") as Point + ) def expectedNodeGraphicC = new NodeGraphicInput( - gtd.nodeGraphicC.uuid, - gtd.nodeGraphicC.graphicLayer, - gtd.geoJsonReader.read("{ \"type\": \"LineString\", \"coordinates\": [[7.4116482, 51.4843281], [7.4116482, 51.4843281]]}") as LineString, - gtd.nodeC, - gtd.nodeGraphicC.point - ) + gtd.nodeGraphicC.uuid, + gtd.nodeGraphicC.graphicLayer, + gtd.geoJsonReader.read("{ \"type\": \"LineString\", \"coordinates\": [[7.4116482, 51.4843281], [7.4116482, 51.4843281]]}") as LineString, + gtd.nodeC, + gtd.nodeGraphicC.point + ) when: def nodeGraphics = csvGraphicSource.getNodeGraphicInput([gtd.nodeC, gtd.nodeD] as Set) @@ -100,9 +104,9 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should read and handle a valid line graphics file as expected"() { given: def csvGraphicSource = new GraphicSource( - Mock(TypeSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) when: def lineGraphics = csvGraphicSource.getLineGraphicInput([gtd.lineCtoD] as Set) @@ -115,9 +119,9 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should build node graphic entity data from valid and invalid input data correctly"() { given: def csvGraphicSource = new GraphicSource( - Mock(TypeSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) def fieldsToAttributesMap = [ "uuid" : "09aec636-791b-45aa-b981-b14edf171c4c", "graphic_layer": "main", @@ -128,9 +132,11 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { expect: def res = csvGraphicSource.buildNodeGraphicEntityData(fieldsToAttributesMap, nodeCollection as Set) - res.present == isPresent + res.success == isPresent + + if (isPresent) { + def value = res.data() - res.ifPresent({ value -> assert value == new NodeGraphicInputEntityData([ "uuid" : "09aec636-791b-45aa-b981-b14edf171c4c", "graphic_layer": "main", @@ -138,8 +144,7 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { "point" : "{\"type\":\"Point\",\"coordinates\":[0.0,10],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}" ], gtd.nodeC) assert value.node == gtd.nodeC - }) - + } where: nodeCollection || isPresent @@ -151,9 +156,9 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { def "A CsvGraphicSource should build line graphic entity data from valid and invalid input data correctly"() { given: def csvGraphicSource = new GraphicSource( - Mock(TypeSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, graphicsFolderPath, fileNamingStrategy)) def fieldsToAttributesMap = [ "uuid" : "ece86139-3238-4a35-9361-457ecb4258b0", "graphic_layer": "main", @@ -163,16 +168,18 @@ class CsvGraphicSourceTest extends Specification implements CsvTestDataMeta { expect: def res = csvGraphicSource.buildLineGraphicEntityData(fieldsToAttributesMap, nodeCollection as Set) - res.present == isPresent + res.success == isPresent + + if (isPresent) { + def value = res.data() - res.ifPresent({ value -> assert value == new LineGraphicInputEntityData(["uuid" : "ece86139-3238-4a35-9361-457ecb4258b0", "graphic_layer": "main", "path" : "{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[0.0,10]],\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:4326\"}}}" ] , gtd.lineAtoB) assert value.line == gtd.lineAtoB - }) + } where: diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy index f7d538b5e..c43886fcc 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvRawGridSourceTest.groovy @@ -5,6 +5,7 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.exceptions.SourceException import edu.ie3.datamodel.io.factory.input.AssetInputEntityData import edu.ie3.datamodel.io.factory.input.ConnectorInputEntityData import edu.ie3.datamodel.io.factory.input.Transformer3WInputEntityData @@ -15,12 +16,12 @@ import edu.ie3.datamodel.models.input.connector.LineInput import edu.ie3.datamodel.models.input.connector.SwitchInput import edu.ie3.datamodel.models.input.connector.Transformer3WInput import edu.ie3.datamodel.models.input.container.RawGridElements +import edu.ie3.datamodel.utils.Try import edu.ie3.test.common.GridTestData import edu.ie3.test.common.GridTestData as rgtd import spock.lang.Shared import spock.lang.Specification -import java.nio.file.Path import java.util.stream.Collectors import java.util.stream.Stream @@ -63,8 +64,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def connectorDataOption = source.buildUntypedConnectorInputEntityData(validAssetEntityInputData, nodes) then: "everything is fine" - connectorDataOption.present - connectorDataOption.get().with { + connectorDataOption.success + connectorDataOption.data().with { assert fieldsToValues == expectedFieldsToAttributes assert targetClass == SwitchInput assert nodeA == rgtd.nodeA @@ -93,42 +94,42 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def connectorDataOption = source.buildUntypedConnectorInputEntityData(validAssetEntityInputData, nodes) then: "it returns en empty Optional" - !connectorDataOption.present + connectorDataOption.failure } def "The CsvRawGridSource is able to convert a stream of valid AssetInputEntityData to ConnectorInputEntityData"() { given: "valid input data" def validStream = Stream.of( - new AssetInputEntityData([ - "uuid" : "5dc88077-aeb6-4711-9142-db57287640b1", - "id" : "test_switch_AtoB", - "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", - "operatesFrom" : "2020-03-24 15:11:31", - "operatesUntil" : "2020-03-24 15:11:31", - "nodeA" : "4ca90220-74c2-4369-9afa-a18bf068840d", - "nodeB" : "47d29df0-ba2d-4d23-8e75-c82229c5c758", - "closed" : "true" - ], SwitchInput), - new AssetInputEntityData([ - "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", - "id" : "test_lineCtoD", - "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", - "operatesFrom" : "2020-03-24 15:11:31", - "operatesUntil" : "2020-03-24 15:11:31", - "nodeA" : "bd837a25-58f3-44ac-aa90-c6b6e3cd91b2", - "nodeB" : "6e0980e0-10f2-4e18-862b-eb2b7c90509b", - "parallelDevices" : "2", - "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", - "length" : "0.003", - "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", - "olmCharacteristic" : "olm:{(0.0,1.0)}" - ], - LineInput) - ) + new AssetInputEntityData([ + "uuid" : "5dc88077-aeb6-4711-9142-db57287640b1", + "id" : "test_switch_AtoB", + "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", + "operatesFrom" : "2020-03-24 15:11:31", + "operatesUntil" : "2020-03-24 15:11:31", + "nodeA" : "4ca90220-74c2-4369-9afa-a18bf068840d", + "nodeB" : "47d29df0-ba2d-4d23-8e75-c82229c5c758", + "closed" : "true" + ], SwitchInput), + new AssetInputEntityData([ + "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", + "id" : "test_lineCtoD", + "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", + "operatesFrom" : "2020-03-24 15:11:31", + "operatesUntil" : "2020-03-24 15:11:31", + "nodeA" : "bd837a25-58f3-44ac-aa90-c6b6e3cd91b2", + "nodeB" : "6e0980e0-10f2-4e18-862b-eb2b7c90509b", + "parallelDevices" : "2", + "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", + "length" : "0.003", + "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", + "olmCharacteristic" : "olm:{(0.0,1.0)}" + ], + LineInput) + ) def expectedSet = [ - Optional.of(new ConnectorInputEntityData([ + new ConnectorInputEntityData([ "uuid" : "5dc88077-aeb6-4711-9142-db57287640b1", "id" : "test_switch_AtoB", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -139,8 +140,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { SwitchInput, rgtd.nodeA, rgtd.nodeB - )), - Optional.of(new ConnectorInputEntityData([ + ), + new ConnectorInputEntityData([ "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", "id" : "test_lineCtoD", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -155,7 +156,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { LineInput, rgtd.nodeC, rgtd.nodeD - )) + ) ] as Set def nodes = [ @@ -170,7 +171,11 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { then: "everything is fine" actualSet.size() == expectedSet.size() - actualSet.containsAll(expectedSet) + actualSet.forEach { + it.success + } + + actualSet.stream().map { it.data() }.toList().containsAll(expectedSet) } def "The CsvRawGridSource is able to add a type to untyped ConnectorInputEntityData correctly"() { @@ -235,7 +240,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeD ) - def expectedTypedEntityData = Optional.of(new TypedConnectorInputEntityData([ + def expectedTypedEntityData = new TypedConnectorInputEntityData([ "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", "id" : "test_lineCtoD", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -250,7 +255,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeC, rgtd.nodeD, rgtd.lineTypeInputCtoD - )) + ) def availableTypes = [rgtd.lineTypeInputCtoD] @@ -258,7 +263,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.findAndAddType(validConnectorEntityData, availableTypes) then: "everything is fine" - actual == expectedTypedEntityData + actual.success + actual.data() == expectedTypedEntityData } def "The CsvRawGridSource is able to identify ConnectorInputEntityData data with non matching type requirements correctly"() { @@ -286,47 +292,46 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.findAndAddType(validConnectorEntityData, availableTypes) then: "everything is fine" - !actual.present + actual.failure } def "The CsvRawGridSource is able to convert a stream of valid ConnectorInputEntityData to TypedConnectorInputEntityData"() { given: "valid input data" - def validStream = Stream.of( - Optional.of(new ConnectorInputEntityData([ - "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", - "id" : "test_lineCtoD", - "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", - "operatesFrom" : "2020-03-24 15:11:31", - "operatesUntil" : "2020-03-24 15:11:31", - "parallelDevices" : "2", - "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", - "length" : "0.003", - "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", - "olmCharacteristic" : "olm:{(0.0,1.0)}" - ], - LineInput, - rgtd.nodeC, - rgtd.nodeD - )), - Optional.of(new ConnectorInputEntityData([ - "uuid" : "92ec3bcf-1777-4d38-af67-0bf7c9fa73c7", - "id" : "test_line_AtoB", - "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", - "operatesFrom" : "2020-03-24 15:11:31", - "operatesUntil" : "2020-03-24 15:11:31", - "parallelDevices" : "2", - "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", - "length" : "0.003", - "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", - "olmCharacteristic" : "olm:{(0.0,1.0)}" - ], LineInput, - rgtd.nodeA, - rgtd.nodeB - )) - ) + def validStream = Stream.of(new Try.Success<>( + new ConnectorInputEntityData([ + "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", + "id" : "test_lineCtoD", + "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", + "operatesFrom" : "2020-03-24 15:11:31", + "operatesUntil" : "2020-03-24 15:11:31", + "parallelDevices" : "2", + "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", + "length" : "0.003", + "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", + "olmCharacteristic" : "olm:{(0.0,1.0)}" + ], + LineInput, + rgtd.nodeC, + rgtd.nodeD + )), + new Try.Success<>(new ConnectorInputEntityData([ + "uuid" : "92ec3bcf-1777-4d38-af67-0bf7c9fa73c7", + "id" : "test_line_AtoB", + "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", + "operatesFrom" : "2020-03-24 15:11:31", + "operatesUntil" : "2020-03-24 15:11:31", + "parallelDevices" : "2", + "type" : "3bed3eb3-9790-4874-89b5-a5434d408088", + "length" : "0.003", + "geoPosition" : "{ \"type\": \"LineString\", \"coordinates\": [[7.411111, 51.492528], [7.414116, 51.484136]]}", + "olmCharacteristic" : "olm:{(0.0,1.0)}" + ], LineInput, + rgtd.nodeA, + rgtd.nodeB + ))) as Stream> def expectedSet = [ - Optional.of(new TypedConnectorInputEntityData<>([ + new TypedConnectorInputEntityData<>([ "uuid" : "91ec3bcf-1777-4d38-af67-0bf7c9fa73c7", "id" : "test_lineCtoD", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -341,8 +346,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeC, rgtd.nodeD, rgtd.lineTypeInputCtoD - )), - Optional.of(new TypedConnectorInputEntityData<>([ + ), + new TypedConnectorInputEntityData<>([ "uuid" : "92ec3bcf-1777-4d38-af67-0bf7c9fa73c7", "id" : "test_line_AtoB", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -356,7 +361,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeA, rgtd.nodeB, rgtd.lineTypeInputCtoD - )) + ) ] def availableTypes = [rgtd.lineTypeInputCtoD] @@ -366,7 +371,12 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { then: "everything is fine" actualSet.size() == expectedSet.size() - actualSet.containsAll(expectedSet) + actualSet.forEach { + it.success + } + actualSet.stream().map { + it.data() + }.toList().containsAll(expectedSet) } def "The CsvRawGridSource is able to add the third node for a three winding transformer correctly"() { @@ -387,7 +397,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeB, rgtd.transformerTypeAtoBtoC) - def expected = Optional.of(new Transformer3WInputEntityData([ + def expected = new Transformer3WInputEntityData([ "uuid" : "cc327469-7d56-472b-a0df-edbb64f90e8f", "id" : "3w_test", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -401,7 +411,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeA, rgtd.nodeB, rgtd.nodeC, - rgtd.transformerTypeAtoBtoC)) + rgtd.transformerTypeAtoBtoC) def availableNodes = [ rgtd.nodeA, @@ -413,7 +423,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.addThirdNode(typedEntityData, availableNodes) then: "everything is fine" - actual == expected + actual.success + actual.data() == expected } def "The CsvRawGridSource is NOT able to add the third node for a three winding transformer, if it is not available"() { @@ -444,12 +455,12 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.addThirdNode(typedEntityData, availableNodes) then: "everything is fine" - !actual.present + actual.failure } def "The CsvRawGridSource is able to add the third node for a three winding transformer to a stream of candidates"() { given: "suitable input data" - def inputStream = Stream.of(Optional.of(new TypedConnectorInputEntityData([ + def inputStream = Stream.of(Try.of(() -> new TypedConnectorInputEntityData([ "uuid" : "cc327469-7d56-472b-a0df-edbb64f90e8f", "id" : "3w_test", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -463,8 +474,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { Transformer3WInput, rgtd.nodeA, rgtd.nodeB, - rgtd.transformerTypeAtoBtoC)), - Optional.of(new TypedConnectorInputEntityData([ + rgtd.transformerTypeAtoBtoC), SourceException), + Try.of(() -> new TypedConnectorInputEntityData([ "uuid" : "cc327469-7d56-472b-a0df-edbb64f90e8f", "id" : "3w_test", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -478,8 +489,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { Transformer3WInput, rgtd.nodeA, rgtd.nodeB, - rgtd.transformerTypeAtoBtoC)) - ) + rgtd.transformerTypeAtoBtoC), SourceException)) def availableNodes = [ rgtd.nodeA, @@ -488,7 +498,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { ] def expectedSet = [ - Optional.of(new Transformer3WInputEntityData([ + new Transformer3WInputEntityData([ "uuid" : "cc327469-7d56-472b-a0df-edbb64f90e8f", "id" : "3w_test", "operator" : "8f9682df-0744-4b58-a122-f0dc730f6510", @@ -502,8 +512,8 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { rgtd.nodeA, rgtd.nodeB, rgtd.nodeC, - rgtd.transformerTypeAtoBtoC)), - Optional.empty() + rgtd.transformerTypeAtoBtoC), + null ] when: "the sources tries to add nodes" @@ -511,7 +521,12 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { then: "everything is fine" actualSet.size() == expectedSet.size() - actualSet.containsAll(expectedSet) + actualSet.forEach { + it.success + } + actualSet.stream().map { + it.data() + }.toList().containsAll(expectedSet) } def "The CsvRawGridSource is able to load all nodes from file"() { @@ -693,39 +708,39 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { when: "loading a total grid structure from file" def actual = source.getGridData() def expected = new RawGridElements( - [ - rgtd.nodeA, - rgtd.nodeB, - rgtd.nodeC, - rgtd.nodeD, - rgtd.nodeE, - rgtd.nodeF, - rgtd.nodeG - ] as Set, - [ - rgtd.lineAtoB, - rgtd.lineCtoD - ] as Set, - [ - GridTestData.transformerBtoD, - GridTestData.transformerBtoE, - GridTestData.transformerCtoE, - GridTestData.transformerCtoF, - GridTestData.transformerCtoG - ] as Set, - [ - GridTestData.transformerAtoBtoC - ] as Set, - [rgtd.switchAtoB] as Set, - [ - rgtd.measurementUnitInput - ] as Set - ) + [ + rgtd.nodeA, + rgtd.nodeB, + rgtd.nodeC, + rgtd.nodeD, + rgtd.nodeE, + rgtd.nodeF, + rgtd.nodeG + ] as Set, + [ + rgtd.lineAtoB, + rgtd.lineCtoD + ] as Set, + [ + GridTestData.transformerBtoD, + GridTestData.transformerBtoE, + GridTestData.transformerCtoE, + GridTestData.transformerCtoF, + GridTestData.transformerCtoG + ] as Set, + [ + GridTestData.transformerAtoBtoC + ] as Set, + [rgtd.switchAtoB] as Set, + [ + rgtd.measurementUnitInput + ] as Set + ) then: "all elements are there" - actual.present - actual.get().with { - /* It's okay, to only test the uuids, because content is tested with the other test methods */ + actual != null + actual.with { + /* It's okay, to only test the uuids, because content is tested with the other test mehtods */ assert nodes.size() == expected.nodes.size() assert nodes.each {entry -> expected.nodes.contains({it.uuid == entry.uuid})} assert lines.size() == expected.lines.size() @@ -741,7 +756,7 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { } } - def "The CsvRawGridSource returns an empty Optional, if one mandatory element for the RawGridElements is missing"() { + def "The CsvRawGridSource throws a rawInputDataException, if one mandatory element for the RawGridElements is missing"() { given: "a source pointing to malformed grid data" TypeSource typeSource = new TypeSource(new CsvDataSource(csvSep, typeFolderPath, fileNamingStrategy)) source = new RawGridSource(typeSource, new CsvDataSource(csvSep, gridMalformedFolderPath, fileNamingStrategy)) @@ -750,10 +765,12 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.getGridData() then: "the optional is empty" - !actual.present + actual == null + SourceException ex = thrown() + ex.message == "edu.ie3.datamodel.exceptions.FailureException: 1 exception(s) occurred within \"NodeInput\" data, one is: edu.ie3.datamodel.exceptions.FactoryException: An error occurred when creating instance of NodeInput.class." } - def "The CsvRawGridSource returns an empty Optional, if the RawGridElements contain no single element"() { + def "The CsvRawGridSource returns an empty grid, if the RawGridElements contain no single element"() { given: "a source pointing to malformed grid data" TypeSource typeSource = new TypeSource(new CsvDataSource(csvSep, typeFolderPath, fileNamingStrategy)) source = new RawGridSource(typeSource, new CsvDataSource(csvSep, gridEmptyFolderPath, fileNamingStrategy)) @@ -762,6 +779,6 @@ class CsvRawGridSourceTest extends Specification implements CsvTestDataMeta { def actual = source.getGridData() then: "the optional is empty" - !actual.present + actual.allEntitiesAsList().empty } } \ No newline at end of file diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy index ccce80529..3bc2e0aef 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvSystemParticipantSourceTest.groovy @@ -5,6 +5,8 @@ */ package edu.ie3.datamodel.io.source.csv +import edu.ie3.datamodel.exceptions.SourceException +import edu.ie3.datamodel.exceptions.SystemParticipantsException import edu.ie3.datamodel.io.factory.input.NodeAssetInputEntityData import edu.ie3.datamodel.io.factory.input.participant.ChpInputEntityData import edu.ie3.datamodel.io.factory.input.participant.HpInputEntityData @@ -27,6 +29,7 @@ import edu.ie3.datamodel.models.input.system.StorageInput import edu.ie3.datamodel.models.input.system.WecInput import edu.ie3.datamodel.models.input.thermal.ThermalBusInput import edu.ie3.datamodel.models.input.thermal.ThermalStorageInput +import edu.ie3.datamodel.utils.Try import edu.ie3.test.common.SystemParticipantTestData as sptd import spock.lang.Specification @@ -44,24 +47,21 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) when: - def systemParticipantsOpt = csvSystemParticipantSource.getSystemParticipants() + def systemParticipants = csvSystemParticipantSource.systemParticipants then: - systemParticipantsOpt.present - systemParticipantsOpt.ifPresent({ systemParticipants -> - assert (systemParticipants.allEntitiesAsList().size() == 11) - assert (systemParticipants.getPvPlants().first().uuid == sptd.pvInput.uuid) - assert (systemParticipants.getBmPlants().first().uuid == sptd.bmInput.uuid) - assert (systemParticipants.getChpPlants().first().uuid == sptd.chpInput.uuid) - assert (systemParticipants.getEvs().first().uuid == sptd.evInput.uuid) - assert (systemParticipants.getFixedFeedIns().first().uuid == sptd.fixedFeedInInput.uuid) - assert (systemParticipants.getHeatPumps().first().uuid == sptd.hpInput.uuid) - assert (systemParticipants.getLoads().first().uuid == sptd.loadInput.uuid) - assert (systemParticipants.getWecPlants().first().uuid == sptd.wecInput.uuid) - assert (systemParticipants.getStorages().first().uuid == sptd.storageInput.uuid) - assert (systemParticipants.getEvCS().first().uuid == sptd.evcsInput.uuid) - assert (systemParticipants.getEmSystems().first().uuid == sptd.emInput.uuid) - }) + systemParticipants.allEntitiesAsList().size() == 11 + systemParticipants.pvPlants.first().uuid == sptd.pvInput.uuid + systemParticipants.bmPlants.first().uuid == sptd.bmInput.uuid + systemParticipants.chpPlants.first().uuid == sptd.chpInput.uuid + systemParticipants.evs.first().uuid == sptd.evInput.uuid + systemParticipants.fixedFeedIns.first().uuid == sptd.fixedFeedInInput.uuid + systemParticipants.heatPumps.first().uuid == sptd.hpInput.uuid + systemParticipants.loads.first().uuid == sptd.loadInput.uuid + systemParticipants.wecPlants.first().uuid == sptd.wecInput.uuid + systemParticipants.storages.first().uuid == sptd.storageInput.uuid + systemParticipants.evCS.first().uuid == sptd.evcsInput.uuid + systemParticipants.emSystems.first().uuid == sptd.emInput.uuid } def "A CsvSystemParticipantSource should process invalid input data as expected when requested to provide an instance of SystemParticipants"() { @@ -78,25 +78,33 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat getNodes(_) >> new HashSet() } as RawGridSource def csvSystemParticipantSource = new SystemParticipantSource( - typeSource, - thermalSource, - rawGridSource, - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + typeSource, + thermalSource, + rawGridSource, + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) when: - def systemParticipantsOpt = csvSystemParticipantSource.getSystemParticipants() + def systemParticipants = Try.of(() -> csvSystemParticipantSource.systemParticipants, SystemParticipantsException) then: - !systemParticipantsOpt.present + systemParticipants.failure + systemParticipants.data == Optional.empty() + + Exception ex = systemParticipants.exception() + ex.class == SystemParticipantsException + ex.message.startsWith("11 error(s) occurred while initializing system participants. " + + "edu.ie3.datamodel.exceptions.FailureException: 1 exception(s) occurred within \"FixedFeedInInput\" data, one is: " + + "edu.ie3.datamodel.exceptions.FactoryException: edu.ie3.datamodel.exceptions.SourceException: " + + "Failure due to: Skipping FixedFeedInInput with uuid ") } def "A CsvSystemParticipantSource should build typed entity from valid and invalid input data as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) def nodeAssetInputEntityData = new NodeAssetInputEntityData(fieldsToAttributes, clazz, operator, node) @@ -104,27 +112,27 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def typedEntityDataOpt = csvSystemParticipantSource.buildTypedEntityData(nodeAssetInputEntityData, types) then: - typedEntityDataOpt.present == resultIsPresent - typedEntityDataOpt.ifPresent({ typedEntityData -> + typedEntityDataOpt.success == resultIsPresent + typedEntityDataOpt.data.ifPresent({ typedEntityData -> assert (typedEntityData == resultData) }) where: types | node | operator | fieldsToAttributes | clazz || resultIsPresent || resultData []| sptd.chpInput.node | sptd.chpInput.operator | ["type": "5ebd8f7e-dedb-4017-bb86-6373c4b68eb8"] | ChpInput || false || null - [sptd.chpTypeInput]| sptd.chpInput.node | sptd.chpInput.operator | ["bla": "foo"] | ChpInput || false || null - [sptd.chpTypeInput]| sptd.chpInput.node | sptd.chpInput.operator | [:] | ChpInput || false || null - [sptd.chpTypeInput]| sptd.chpInput.node | sptd.chpInput.operator | ["type": "5ebd8f7e-dedb-4017-bb86-6373c4b68eb9"] | ChpInput || false || null - [sptd.chpTypeInput]| sptd.chpInput.node | sptd.chpInput.operator | ["type": "5ebd8f7e-dedb-4017-bb86-6373c4b68eb8"] | ChpInput || true || new SystemParticipantTypedEntityData<>([:], clazz, operator, node, sptd.chpTypeInput) + [sptd.chpTypeInput] | sptd.chpInput.node | sptd.chpInput.operator | ["bla": "foo"] | ChpInput || false || null + [sptd.chpTypeInput] | sptd.chpInput.node | sptd.chpInput.operator | [:] | ChpInput || false || null + [sptd.chpTypeInput] | sptd.chpInput.node | sptd.chpInput.operator | ["type": "5ebd8f7e-dedb-4017-bb86-6373c4b68eb9"] | ChpInput || false || null + [sptd.chpTypeInput] | sptd.chpInput.node | sptd.chpInput.operator | ["type": "5ebd8f7e-dedb-4017-bb86-6373c4b68eb8"] | ChpInput || true || new SystemParticipantTypedEntityData<>([:], clazz, operator, node, sptd.chpTypeInput) } def "A CsvSystemParticipantSource should build hp input entity from valid and invalid input data as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) def sysPartTypedEntityData = new SystemParticipantTypedEntityData<>(fieldsToAttributes, HpInput, sptd.hpInput.operator, sptd.hpInput.node, sptd.hpTypeInput) @@ -132,27 +140,27 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def hpInputEntityDataOpt = csvSystemParticipantSource.buildHpEntityData(sysPartTypedEntityData, thermalBuses) then: - hpInputEntityDataOpt.present == resultIsPresent - hpInputEntityDataOpt.ifPresent({ hpInputEntityData -> + hpInputEntityDataOpt.success == resultIsPresent + hpInputEntityDataOpt.data.ifPresent({ hpInputEntityData -> assert (hpInputEntityData == resultData) }) where: thermalBuses | fieldsToAttributes || resultIsPresent || resultData - []| ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384e"] || false || null - [sptd.hpInput.thermalBus]| ["bla": "foo"] || false || null - [sptd.hpInput.thermalBus]| [:] || false || null - [sptd.hpInput.thermalBus]| ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384f"] || false || null - [sptd.hpInput.thermalBus]| ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384e"] || true || new HpInputEntityData([:], sptd.hpInput.operator, sptd.hpInput.node, sptd.hpTypeInput, sptd.hpInput.thermalBus) + [] | ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384e"] || false || null + [sptd.hpInput.thermalBus] | ["bla": "foo"] || false || null + [sptd.hpInput.thermalBus] | [:] || false || null + [sptd.hpInput.thermalBus] | ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384f"] || false || null + [sptd.hpInput.thermalBus] | ["thermalBus": "0d95d7f2-49fb-4d49-8636-383a5220384e"] || true || new HpInputEntityData([:], sptd.hpInput.operator, sptd.hpInput.node, sptd.hpTypeInput, sptd.hpInput.thermalBus) } def "A CsvSystemParticipantSource should build chp input entity from valid and invalid input data as expected"(List thermalStorages, List thermalBuses, Map fieldsToAttributes, boolean resultIsPresent, ChpInputEntityData resultData) { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) def sysPartTypedEntityData = new SystemParticipantTypedEntityData<>(fieldsToAttributes, ChpInput, sptd.chpInput.operator, sptd.chpInput.node, sptd.chpTypeInput) @@ -160,8 +168,8 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def hpInputEntityDataOpt = csvSystemParticipantSource.buildChpEntityData(sysPartTypedEntityData, thermalStorages, thermalBuses) then: - hpInputEntityDataOpt.present == resultIsPresent - hpInputEntityDataOpt.ifPresent({ hpInputEntityData -> + hpInputEntityDataOpt.success == resultIsPresent + hpInputEntityDataOpt.data.ifPresent({ hpInputEntityData -> assert (hpInputEntityData == resultData) }) @@ -182,40 +190,50 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from a valid heat pump input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def heatPumps = csvSystemParticipantSource.getHeatPumps(nodes as Set, operators as Set, types as Set, thermalBuses as Set) - heatPumps.size() == resultingSize - heatPumps == resultingSet as Set + def heatPumps = Try.of(() -> csvSystemParticipantSource.getHeatPumps(nodes as Set, operators as Set, types as Set, thermalBuses as Set), SourceException) + + if (heatPumps.success) { + heatPumps.data().size() == resultingSize + heatPumps.data() == resultingSet as Set + } else { + heatPumps.exception().class == SourceException + } where: nodes | operators | types | thermalBuses || resultingSize || resultingSet - [sptd.hpInput.node]| [sptd.hpInput.operator]| [sptd.hpInput.type]| [sptd.hpInput.thermalBus]|| 1 || [sptd.hpInput] - [sptd.hpInput.node]| []| [sptd.hpInput.type]| [sptd.hpInput.thermalBus]|| 1 || [ + [sptd.hpInput.node] | [sptd.hpInput.operator] | [sptd.hpInput.type] | [sptd.hpInput.thermalBus] || 1 || [sptd.hpInput] + [sptd.hpInput.node] | [] | [sptd.hpInput.type] | [sptd.hpInput.thermalBus] || 1 || [ new HpInput(sptd.hpInput.uuid, sptd.hpInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.hpInput.operationTime, sptd.hpInput.node, sptd.hpInput.thermalBus, sptd.hpInput.qCharacteristics, sptd.hpInput.type) ] - []| []| []| []|| 0 || [] - [sptd.hpInput.node]| []| []| []|| 0 || [] - [sptd.hpInput.node]| [sptd.hpInput.operator]| []| []|| 0 || [] - [sptd.hpInput.node]| [sptd.hpInput.operator]| [sptd.hpInput.type]| []|| 0 || [] + [] | [] | [] | [] || 0 || [] + [sptd.hpInput.node] | [] | [] | [] || 0 || [] + [sptd.hpInput.node] | [sptd.hpInput.operator] | [] | [] || 0 || [] + [sptd.hpInput.node] | [sptd.hpInput.operator] | [sptd.hpInput.type] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from a valid chp input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def chpUnits = csvSystemParticipantSource.getChpPlants(nodes as Set, operators as Set, types as Set, thermalBuses as Set, thermalStorages as Set) - chpUnits.size() == resultingSize - chpUnits == resultingSet as Set + def chpUnits = Try.of(() -> csvSystemParticipantSource.getChpPlants(nodes as Set, operators as Set, types as Set, thermalBuses as Set, thermalStorages as Set), SourceException) + + if (chpUnits.success) { + chpUnits.data().size() == resultingSize + chpUnits.data() == resultingSet as Set + } else { + chpUnits.exception().class == SourceException + } where: nodes | operators | types | thermalBuses | thermalStorages || resultingSize || resultingSet @@ -227,120 +245,145 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat ] as List || 1 || [ new ChpInput(sptd.chpInput.uuid, sptd.chpInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.chpInput.operationTime, sptd.chpInput.node, sptd.chpInput.thermalBus, sptd.chpInput.qCharacteristics, sptd.chpInput.type, sptd.chpInput.thermalStorage, sptd.chpInput.marketReaction) ] - []| []| []| []| [] as List || 0 || [] - [sptd.chpInput.node]| []| []| []| [] as List || 0 || [] - [sptd.chpInput.node]| [sptd.chpInput.operator]| []| []| [] as List || 0 || [] - [sptd.chpInput.node]| [sptd.chpInput.operator]| [sptd.chpInput.type]| []| [] as List || 0 || [] + [] | [] | [] | [] | [] as List || 0 || [] + [sptd.chpInput.node] | [] | [] | [] | [] as List || 0 || [] + [sptd.chpInput.node] | [sptd.chpInput.operator] | [] | [] | [] as List || 0 || [] + [sptd.chpInput.node] | [sptd.chpInput.operator] | [sptd.chpInput.type] | [] | [] as List || 0 || [] } def "A CsvSystemParticipantSource should return data from valid ev input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getEvs(nodes as Set, operators as Set, types as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getEvs(nodes as Set, operators as Set, types as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators | types || resultingSize || resultingSet - [sptd.evInput.node]| [sptd.evInput.operator]| [sptd.evInput.type]|| 1 || [sptd.evInput] - [sptd.evInput.node]| []| [sptd.evInput.type]|| 1 || [ + [sptd.evInput.node] | [sptd.evInput.operator] | [sptd.evInput.type] || 1 || [sptd.evInput] + [sptd.evInput.node] | [] | [sptd.evInput.type] || 1 || [ new EvInput(sptd.evInput.uuid, sptd.evInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.evInput.operationTime, sptd.evInput.node, sptd.evInput.qCharacteristics, sptd.evInput.type) ] - [sptd.evInput.node]| [sptd.evInput.operator]| []|| 0 || [] - [sptd.evInput.node]| []| []|| 0 || [] - []| []| []|| 0 || [] + [sptd.evInput.node] | [sptd.evInput.operator] | [] || 0 || [] + [sptd.evInput.node] | [] | [] || 0 || [] + [] | [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid wec input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getWecPlants(nodes as Set, operators as Set, types as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getWecPlants(nodes as Set, operators as Set, types as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators | types || resultingSize || resultingSet - [sptd.wecInput.node]| [sptd.wecInput.operator]| [sptd.wecInput.type]|| 1 || [sptd.wecInput] - [sptd.wecInput.node]| []| [sptd.wecInput.type]|| 1 || [ + [sptd.wecInput.node] | [sptd.wecInput.operator] | [sptd.wecInput.type] || 1 || [sptd.wecInput] + [sptd.wecInput.node] | [] | [sptd.wecInput.type] || 1 || [ new WecInput(sptd.wecInput.uuid, sptd.wecInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.wecInput.operationTime, sptd.wecInput.node, sptd.wecInput.qCharacteristics, sptd.wecInput.type, sptd.wecInput.marketReaction) ] - [sptd.wecInput.node]| [sptd.wecInput.operator]| []|| 0 || [] - [sptd.wecInput.node]| []| []|| 0 || [] - []| []| []|| 0 || [] + [sptd.wecInput.node] | [sptd.wecInput.operator] | [] || 0 || [] + [sptd.wecInput.node] | [] | [] || 0 || [] + [] | [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid storage input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getStorages(nodes as Set, operators as Set, types as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getStorages(nodes as Set, operators as Set, types as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators | types || resultingSize || resultingSet - [sptd.storageInput.node]| [sptd.storageInput.operator]| [sptd.storageInput.type]|| 1 || [sptd.storageInput] - [sptd.storageInput.node]| []| [sptd.storageInput.type]|| 1 || [ + [sptd.storageInput.node] | [sptd.storageInput.operator] | [sptd.storageInput.type] || 1 || [sptd.storageInput] + [sptd.storageInput.node] | [] | [sptd.storageInput.type] || 1 || [ new StorageInput(sptd.storageInput.uuid, sptd.storageInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.storageInput.operationTime, sptd.storageInput.node, sptd.storageInput.qCharacteristics, sptd.storageInput.type) ] - [sptd.storageInput.node]| [sptd.storageInput.operator]| []|| 0 || [] - [sptd.storageInput.node]| []| []|| 0 || [] - []| []| []|| 0 || [] + [sptd.storageInput.node] | [sptd.storageInput.operator] | [] || 0 || [] + [sptd.storageInput.node] | [] | [] || 0 || [] + [] | [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid bm input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getBmPlants(nodes as Set, operators as Set, types as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getBmPlants(nodes as Set, operators as Set, types as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators | types || resultingSize || resultingSet - [sptd.bmInput.node]| [sptd.bmInput.operator]| [sptd.bmInput.type]|| 1 || [sptd.bmInput] - [sptd.bmInput.node]| []| [sptd.bmInput.type]|| 1 || [ + [sptd.bmInput.node] | [sptd.bmInput.operator] | [sptd.bmInput.type] || 1 || [sptd.bmInput] + [sptd.bmInput.node] | [] | [sptd.bmInput.type] || 1 || [ new BmInput(sptd.bmInput.uuid, sptd.bmInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.bmInput.operationTime, sptd.bmInput.node, sptd.bmInput.qCharacteristics, sptd.bmInput.type, sptd.bmInput.marketReaction, sptd.bmInput.costControlled, sptd.bmInput.feedInTariff) ] - [sptd.bmInput.node]| [sptd.bmInput.operator]| []|| 0 || [] - [sptd.bmInput.node]| []| []|| 0 || [] - []| []| []|| 0 || [] + [sptd.bmInput.node] | [sptd.bmInput.operator] | [] || 0 || [] + [sptd.bmInput.node] | [] | [] || 0 || [] + [] | [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid ev charging station input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getEvCS(nodes as Set, operators as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getEvCS(nodes as Set, operators as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators || resultingSize || resultingSet @@ -355,88 +398,108 @@ class CsvSystemParticipantSourceTest extends Specification implements CsvTestDat def "A CsvSystemParticipantSource should return data from valid load input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getLoads(nodes as Set, operators as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getLoads(nodes as Set, operators as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators || resultingSize || resultingSet - [sptd.loadInput.node]| [sptd.loadInput.operator]|| 1 || [sptd.loadInput] - [sptd.loadInput.node]| []|| 1 || [ + [sptd.loadInput.node] | [sptd.loadInput.operator] || 1 || [sptd.loadInput] + [sptd.loadInput.node] | [] || 1 || [ new LoadInput(sptd.loadInput.uuid, sptd.loadInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.loadInput.operationTime, sptd.loadInput.node, sptd.loadInput.qCharacteristics, sptd.loadInput.loadProfile, sptd.loadInput.dsm, sptd.loadInput.eConsAnnual, sptd.loadInput.sRated, sptd.loadInput.cosPhiRated) ] - []| [sptd.loadInput.operator]|| 0 || [] - []| []|| 0 || [] + [] | [sptd.loadInput.operator] || 0 || [] + [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid pv input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getPvPlants(nodes as Set, operators as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getPvPlants(nodes as Set, operators as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators || resultingSize || resultingSet - [sptd.pvInput.node]| [sptd.pvInput.operator]|| 1 || [sptd.pvInput] - [sptd.pvInput.node]| []|| 1 || [ + [sptd.pvInput.node] | [sptd.pvInput.operator] || 1 || [sptd.pvInput] + [sptd.pvInput.node] | [] || 1 || [ new PvInput(sptd.pvInput.uuid, sptd.pvInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.pvInput.operationTime, sptd.pvInput.node, sptd.pvInput.qCharacteristics, sptd.pvInput.albedo, sptd.pvInput.azimuth, sptd.pvInput.etaConv, sptd.pvInput.elevationAngle, sptd.pvInput.kG, sptd.pvInput.kT, sptd.pvInput.marketReaction, sptd.pvInput.sRated, sptd.pvInput.cosPhiRated) ] - []| [sptd.pvInput.operator]|| 0 || [] - []| []|| 0 || [] + [] | [sptd.pvInput.operator] || 0 || [] + [] | [] || 0 || [] } def "A CsvSystemParticipantSource should return data from valid fixedFeedIn input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getFixedFeedIns(nodes as Set, operators as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getFixedFeedIns(nodes as Set, operators as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators || resultingSize || resultingSet - [sptd.fixedFeedInInput.node]| [ + [sptd.fixedFeedInInput.node] | [ sptd.fixedFeedInInput.operator ] as List || 1 || [sptd.fixedFeedInInput] - [sptd.fixedFeedInInput.node]| [] as List || 1 || [ + [sptd.fixedFeedInInput.node] | [] as List || 1 || [ new FixedFeedInInput(sptd.fixedFeedInInput.uuid, sptd.fixedFeedInInput.id, OperatorInput.NO_OPERATOR_ASSIGNED, sptd.fixedFeedInInput.operationTime, sptd.fixedFeedInInput.node, sptd.fixedFeedInInput.qCharacteristics, sptd.fixedFeedInInput.sRated, sptd.fixedFeedInInput.cosPhiRated) ] - []| [ + [] | [ sptd.fixedFeedInInput.operator ] as List || 0 || [] - []| [] as List || 0 || [] + [] | [] as List || 0 || [] } def "A CsvSystemParticipantSource should return data from valid em input file as expected"() { given: def csvSystemParticipantSource = new SystemParticipantSource( - Mock(TypeSource), - Mock(ThermalSource), - Mock(RawGridSource), - new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) + Mock(TypeSource), + Mock(ThermalSource), + Mock(RawGridSource), + new CsvDataSource(csvSep, participantsFolderPath, fileNamingStrategy)) expect: - def sysParts = csvSystemParticipantSource.getEmSystems(nodes as Set, operators as Set) - sysParts.size() == resultingSize - sysParts == resultingSet as Set + def sysParts = Try.of(() -> csvSystemParticipantSource.getEmSystems(nodes as Set, operators as Set), SourceException) + + if (sysParts.success) { + sysParts.data().size() == resultingSize + sysParts.data() == resultingSet as Set + } else { + sysParts.exception().class == SourceException + } where: nodes | operators || resultingSize || resultingSet diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy index 790a43845..bead486fc 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvThermalSourceTest.groovy @@ -112,8 +112,8 @@ class CsvThermalSourceTest extends Specification implements CsvTestDataMeta { then: resultingDataOpt.size() == 1 - resultingDataOpt.first().present == resultIsPresent - resultingDataOpt.first().ifPresent({ resultingData -> + resultingDataOpt.first().data.present == resultIsPresent + resultingDataOpt.first().data.ifPresent({ resultingData -> assert (resultingData == expectedThermalUnitInputEntityData) }) diff --git a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy index a98481811..177b3c15e 100644 --- a/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy +++ b/src/test/groovy/edu/ie3/datamodel/io/source/csv/CsvTimeSeriesSourceTest.groovy @@ -46,8 +46,8 @@ class CsvTimeSeriesSourceTest extends Specification implements CsvTestDataMeta { def actual = source.createTimeBasedValue(fieldToValue) then: - actual.present - actual.get() == expected + actual.success + actual.data() == expected } def "The factory method in csv time series source refuses to build time series with unsupported column type"() { diff --git a/src/test/groovy/edu/ie3/datamodel/utils/TryTest.groovy b/src/test/groovy/edu/ie3/datamodel/utils/TryTest.groovy new file mode 100644 index 000000000..86d545fc4 --- /dev/null +++ b/src/test/groovy/edu/ie3/datamodel/utils/TryTest.groovy @@ -0,0 +1,285 @@ +/* + * © 2023. TU Dortmund University, + * Institute of Energy Systems, Energy Efficiency and Energy Economics, + * Research group Distribution grid planning and operation + */ +package edu.ie3.datamodel.utils + +import edu.ie3.datamodel.exceptions.FailureException +import edu.ie3.datamodel.exceptions.SourceException +import edu.ie3.datamodel.exceptions.TryException +import spock.lang.Specification + +class TryTest extends Specification { + + def "A method can be applied to a try object"() { + when: + Try actual = Try.of(() -> "success", Exception) + + then: + actual.success + actual.data() == "success" + } + + def "A failing method can be applied to a try object"() { + when: + Try actual = Try.of(() -> { + throw new SourceException("Exception thrown.") + }, SourceException) + + then: + actual.failure + actual.exception().class == SourceException + actual.exception().message == "Exception thrown." + } + + def "A failure is returned if an expected exception type is thrown when using #of()"() { + when: + def exception = new SourceException("source exception") + Try actual = Try.of(() -> { + throw exception + }, SourceException) + + then: + actual.failure + actual.exception.get() == exception + } + + def "A TryException is thrown if an unexpected exception type is thrown when using #of()"() { + when: + Try.of(() -> { + throw new SourceException("source exception") + }, FailureException) + + then: + Exception ex = thrown() + ex.class == TryException + ex.message == "Wrongly caught exception: " + Throwable cause = ex.cause + cause.class == SourceException + cause.message == "source exception" + } + + def "A failure is returned when using Failure#ofVoid() with an exception"() { + when: + def exception = new SourceException("source exception") + Try actual = Try.Failure.ofVoid(exception) + + then: + actual.failure + actual.exception.get() == exception + } + + def "A failure is returned when using Failure#of() with an exception"() { + when: + def exception = new SourceException("source exception") + Try actual = Try.Failure.of(exception) + + then: + actual.failure + actual.exception.get() == exception + } + + def "A failure is returned when using Failure#of() with a failure"() { + when: + def exception = new SourceException("source exception") + Try actual = Try.Failure.of(new Try.Failure(exception)) + + then: + actual.failure + actual.exception.get() == exception + } + + def "A failure is returned if an expected exception type is thrown when using Try#ofVoid()"() { + when: + def exception = new SourceException("source exception") + Try actual = Try.ofVoid(() -> { + throw exception + }, SourceException) + + then: + actual.failure + actual.exception.get() == exception + } + + def "A TryException is thrown if an unexpected exception type is thrown when using Try#ofVoid()"() { + when: + Try.ofVoid(() -> { + throw new SourceException("source exception") + }, FailureException) + + then: + Exception ex = thrown() + ex.class == TryException + ex.message == "Wrongly caught exception: " + Throwable cause = ex.cause + cause.class == SourceException + cause.message == "source exception" + } + + def "A void method can be applied to a try object"() { + when: + Try actual = Try.ofVoid(() -> null, Exception) + + then: + actual.success + actual.empty + actual.data.empty + } + + def "A success object can be resolved with get method"() { + given: + Try success = new Try.Success<>("success") + + when: + String str = success.get() + + then: + str == "success" + } + + def "A failure object can be resolved with get method"() { + given: + Try failure = new Try.Failure<>(new Exception("failure")) + + when: + Exception ex = failure.get() + + then: + ex.message == "failure" + } + + def "An empty Success should work as expected"() { + given: + Try empty = Try.Success.empty() as Try + + expect: + empty.success + empty.data == Optional.empty() + empty.empty + } + + def "A scan for exceptions should work as expected when failures are included"() { + given: + Set> set = Set.of( + new Try.Success<>("one"), + new Try.Failure<>(new Exception("exception")), + new Try.Success<>("two"), + new Try.Success<>("three") + ) + + when: + Try, Exception> scan = Try.scanCollection(set, String) + + then: + scan.failure + scan.exception().message == "1 exception(s) occurred within \"String\" data, one is: java.lang.Exception: exception" + } + + def "A scan for exceptions should work as expected when no failures are included"() { + given: + Set> set = Set.of( + new Try.Success<>("one"), + new Try.Success<>("two"), + new Try.Success<>("three") + ) + + when: + Try, Exception> scan = Try.scanCollection(set, String) + + then: + scan.success + scan.data().size() == 3 + } + + def "The getOrThrow method should work as expected"() { + given: + Try failure = new Try.Failure<>(new SourceException("source exception")) + + when: + failure.orThrow + + then: + Exception ex = thrown() + ex.class == SourceException + ex.message == "source exception" + } + + def "The getOrElse method should work as expected"() { + given: + Try success = new Try.Success<>("success") + Try failure = new Try.Failure<>(new SourceException("exception")) + + when: + String successResult = success.getOrElse("else") + String failureResult = failure.getOrElse("else") + + then: + successResult == "success" + failureResult == "else" + } + + def "A Try objects transformation should work as correctly for successes"() { + given: + Try success = new Try.Success<>("5") + + when: + Try first = success.transformS(str -> Integer.parseInt(str) ) + Try second = success.transform(str -> Integer.parseInt(str), ex -> new Exception(ex) ) + + then: + first.success + second.success + + first.data() == 5 + second.data() == 5 + } + + def "A Try objects transformation should work as correctly for failures"() { + given: + Try failure = new Try.Failure<>(new SourceException("")) + + when: + Try first = failure.transformS(str -> Integer.parseInt(str) ) + Try second = failure.transform(str -> Integer.parseInt(str), ex -> new Exception(ex) ) + + then: + first.failure + second.failure + + first.exception().class == SourceException + second.exception().class == Exception + } + + def "All exceptions of a collection of try objects should be returned"() { + given: + List> tries = List.of( + new Try.Success<>("one"), + new Try.Failure<>(new SourceException("source exception")), + new Try.Failure<>(new UnsupportedOperationException("unsupported operation exception")), + new Try.Success<>("two"), + new Try.Failure<>(new SourceException("source exception 2")) + ) + + when: + List exceptions = Try.getExceptions(tries) + + then: + exceptions.size() == 3 + + exceptions.get(0).with { + assert it.class == SourceException + assert it.message == "source exception" + } + + exceptions.get(1).with { + assert it.class == UnsupportedOperationException + assert it.message == "unsupported operation exception" + } + + exceptions.get(2).with { + assert it.class == SourceException + assert it.message == "source exception 2" + } + } +} diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/line_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/line_input.csv index c5f849c5c..e067b14d5 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/line_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/line_input.csv @@ -1,3 +1,3 @@ uuid,geo_position,id,length,node_a,node_b,olm_characteristic,operates_from,operates_until,operator,parallel_devices,type 92ec3bcf-1777-4d38-af67-0bf7c9fa73c7,"{""type"":""LineString"",""coordinates"":[[7.411111,51.492528],[7.414116,51.484136]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",test_line_AtoB,0.003,4ca90220-74c2-4369-9afa-a18bf068840d,47d29df0-ba2d-4d23-8e75-c82229c5c758,olm:{(0.00,1.00)},2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,2,3bed3eb3-9790-4874-89b5-a5434d408088 -91ec3bcf-1777-4d38-af67-0bf7c9fa73c7,"{""type"":""LineString"",""coordinates"":[[7.411111,51.492528],[7.414116,51.484136]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",test_line_CtoD,0.003,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,6e0980e0-10f2-4e18-862b-eb2b7c90509b,olm:{(0.00,1.00)},2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,2,3bed3eb3-9790-4874-89b5-a5434d408088 \ No newline at end of file +91ec3bcf-1777-4d38-af67-0bf7c9fa73c,"{""type"":""LineString"",""coordinates"":[[7.411111,51.492528],[7.414116,51.484136]],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",test_line_CtoD,0.003,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,6e0980e0-10f2-4e18-862b-eb2b7c90509b,olm:{(0.00,1.00)},2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,2,3bed3eb3-9790-4874-89b5-a5434d408088 \ No newline at end of file diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/measurement_unit_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/measurement_unit_input.csv index d9e432af9..d602fcd2c 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/measurement_unit_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/measurement_unit_input.csv @@ -1,2 +1,2 @@ uuid,v_ang,v_mag,id,node,operates_from,operates_until,operator,p,q -ce6119e3-f725-4166-b6e0-59f62e0c293d,true,true,test_measurementUnit,aaa74c1a-d07e-4615-99a5-e991f1d81cc4,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,true,true +c e6119e3-f725-4166-b6e0-59f62e0c293d,true,true,test_measurementUnit,aaa74c1a-d07e-4615-99a5-e991f1d81cc4,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,true,true diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/node_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/node_input.csv index 6a9f52e29..743894f9a 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/node_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/node_input.csv @@ -1,7 +1,7 @@ uuid,geo_position,id,operates_from,operates_until,operator,slack,subnet,v_rated,v_target,volt_lvl 4ca90220-74c2-4369-9afa-a18bf068840d,"{""type"":""Point"",""coordinates"":[7.411111,51.492528],""crs"":{""type"":""name"",""properties"":{""name"":""EPSG:4326""}}}",node_a,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,true,1,380.0,1.0,Höchstspannung 47d29df0-ba2d-4d23-8e75-c82229c5c758,,node_b,,,,false,2,110.0,1.0,Hochspannung -bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,,node_c,,,,false,3,20.0,1.0,Mittelspannung +bd837a25-58f3-44ac-aa90-c6b6e3 cd91b2,,node_c,,,,false,3,20.0,1.0,Mittelspannung 98a3e7fa-c456-455b-a5ea-bb19e7cbeb63,,node_e,,,,false,5,10.0,1.0,Mittelspannung 9e37ce48-9650-44ec-b888-c2fd182aff01,,node_f,,,,false,6,0.4,1.0,Niederspannung aaa74c1a-d07e-4615-99a5-e991f1d81cc4,,node_g,,,,false,6,0.4,1.0,Niederspannung diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/switch_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/switch_input.csv index af37806f6..5e9754c1c 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/switch_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/switch_input.csv @@ -1,2 +1,2 @@ uuid,closed,id,node_a,node_b,operates_from,operates_until,operator -5dc88077-aeb6-4711-9142-db57287640b1,true,test_switch_AtoB,4ca90220-74c2-4369-9afa-a18bf068840d,47d29df0-ba2d-4d23-8e75-c82229c5c758,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92 +5dc88077-aeb6-4711-9142-db57287640b1,true,test_switch_AtoB,4ca90220-74c2-4369-9afa -a18bf068840d,47d29df0-ba2d-4d23-8e75-c82229c5c758,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92 diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_2_w_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_2_w_input.csv index 564775304..d1a429620 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_2_w_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_2_w_input.csv @@ -1,6 +1,6 @@ uuid,auto_tap,id,node_a,node_b,operates_from,operates_until,operator,parallel_devices,tap_pos,type 58247de7-e297-4d9b-a5e4-b662c058c655,true,2w_single_test,47d29df0-ba2d-4d23-8e75-c82229c5c758,6e0980e0-10f2-4e18-862b-eb2b7c90509b,,,,1,0,202069a7-bcf8-422c-837c-273575220c8a -8542bfa5-dc34-4367-b549-e9f515e6cced,true,2w_v_1,47d29df0-ba2d-4d23-8e75-c82229c5c758,98a3e7fa-c456-455b-a5ea-bb19e7cbeb63,,,,1,0,ac30443b-29e7-4635-b399-1062cfb3ffda +8542bfa5-dc34-4367-b549-e9f515e6cced,true,2w_v_1,47d29df0-ba2d-4d23-8e75-c 82229c5c758,98a3e7fa-c456-455b-a5ea-bb19e7cbeb63,,,,1,0,ac30443b-29e7-4635-b399-1062cfb3ffda 0c03391d-47e1-49b3-9c9c-1616258e78a7,true,2w_v_2,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,98a3e7fa-c456-455b-a5ea-bb19e7cbeb63,,,,1,0,8441dd78-c528-4e63-830d-52d341131432 26a3583e-8e62-40b7-ba4c-092f6fd5a70d,true,2w_parallel_1,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,9e37ce48-9650-44ec-b888-c2fd182aff01,,,,1,0,08559390-d7c0-4427-a2dc-97ba312ae0ac 5dc88077-aeb6-4711-9142-db57292640b1,true,2w_parallel_2,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,aaa74c1a-d07e-4615-99a5-e991f1d81cc4,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,1,0,08559390-d7c0-4427-a2dc-97ba312ae0ac diff --git a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_3_w_input.csv b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_3_w_input.csv index b970ceefb..8a8d3e8a4 100644 --- a/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_3_w_input.csv +++ b/src/test/resources/edu/ie3/datamodel/io/source/csv/_grid/malformed/transformer_3_w_input.csv @@ -1,2 +1,2 @@ uuid,auto_tap,id,node_a,node_b,node_c,operates_from,operates_until,operator,parallel_devices,tap_pos,type -cc327469-7d56-472b-a0df-edbb64f90e8f,true,3w_test,4ca90220-74c2-4369-9afa-a18bf068840d,47d29df0-ba2d-4d23-8e75-c82229c5c758,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,1,0,5b0ee546-21fb-4a7f-a801-5dbd3d7bb356 +cc327469-7d56-472b-a0df-edbb6 4f90e8f,true,3w_test,4ca90220-74c2-4369-9afa-a18bf068840d,47d29df0-ba2d-4d23-8e75-c82229c5c758,bd837a25-58f3-44ac-aa90-c6b6e3cd91b2,2020-03-24T15:11:31Z[UTC],2020-03-25T15:11:31Z[UTC],f15105c4-a2de-4ab8-a621-4bc98e372d92,1,0,5b0ee546-21fb-4a7f-a801-5dbd3d7bb356