SEBSERV-2 #gbl, utils and tests
This commit is contained in:
parent
25f829908e
commit
f81a20bd03
12 changed files with 396 additions and 12 deletions
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.profile;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server dev-gui components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the web-gui environment
|
||||
* and only for development and/or testing */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "dev-gui", "test" })
|
||||
public @interface DevGuiProfile {
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.profile;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server dev-ws components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the web-service environment
|
||||
* and only for development and/or testing */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "dev-ws", "test" })
|
||||
public @interface DevWebServiceProfile {
|
||||
}
|
|
@ -15,6 +15,10 @@ import java.lang.annotation.Target;
|
|||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server gui components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the web-gui environment
|
||||
* but for all vertical profiles like dev, prod and test */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "dev-gui", "prod-gui", "test" })
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.profile;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server prod-gui components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the gui-service environment
|
||||
* and only for production and/or testing */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "prod-gui", "test" })
|
||||
public @interface ProdGuiProfile {
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.profile;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server prod-ws components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the web-service environment
|
||||
* and only for production and/or testing */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "prod-ws", "test" })
|
||||
public @interface ProdWebServiceProfile {
|
||||
}
|
|
@ -15,6 +15,10 @@ import java.lang.annotation.Target;
|
|||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
/** Profile annotation for SEB-Server web-service components.
|
||||
*
|
||||
* Use this as profile annotation on components that are only needed in the web-service environment
|
||||
* but for all vertical profiles like dev, prod and test */
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Profile({ "dev-ws", "prod-ws", "test" })
|
||||
|
|
|
@ -61,6 +61,10 @@ public final class Result<T> {
|
|||
return this.error;
|
||||
}
|
||||
|
||||
public boolean hasError() {
|
||||
return this.error != null;
|
||||
}
|
||||
|
||||
/** Use this to get the resulting value or (if null) to get a given other value
|
||||
*
|
||||
* @param other the other value to get if the computed value is null
|
||||
|
@ -69,10 +73,19 @@ public final class Result<T> {
|
|||
return this.value != null ? this.value : other;
|
||||
}
|
||||
|
||||
/** Use this to get the resulting value or (if null) to get a given other value
|
||||
*
|
||||
* @param supplier supplier to get the value from if the computed value is null
|
||||
* @return return either the computed value if existing or a given other value */
|
||||
public T orElse(final Supplier<T> supplier) {
|
||||
return this.value != null ? this.value : supplier.get();
|
||||
}
|
||||
|
||||
/** Use this to map a given Result of type T to another Result of type U
|
||||
* within a given mapping function.
|
||||
*
|
||||
* @param mapf the mapping function
|
||||
* @return mapped Result of type U */
|
||||
public <U> Result<U> map(final Function<? super T, ? extends U> mapf) {
|
||||
if (this.error == null) {
|
||||
return Result.of(mapf.apply(this.value));
|
||||
|
@ -81,6 +94,11 @@ public final class Result<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/** Use this to map a given Result of type T to another Result of type U
|
||||
* within a given mapping function.
|
||||
*
|
||||
* @param mapf the mapping function
|
||||
* @return mapped Result of type U */
|
||||
public <U> Result<U> flatMap(final Function<? super T, Result<U>> mapf) {
|
||||
if (this.error == null) {
|
||||
return mapf.apply(this.value);
|
||||
|
@ -89,18 +107,16 @@ public final class Result<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/** Use this to get the resulting value. In an error case, a given error handling
|
||||
* function is used that receives the error and returns a resulting value instead
|
||||
* (or throw some error instead)
|
||||
*
|
||||
* @param errorHandler the error handling function
|
||||
* @return */
|
||||
public T onError(final Function<Throwable, T> errorHandler) {
|
||||
return this.error != null ? errorHandler.apply(this.error) : this.value;
|
||||
}
|
||||
|
||||
public static final <T> Result<T> of(final T value) {
|
||||
return new Result<>(value);
|
||||
}
|
||||
|
||||
public static final <T> Result<T> ofError(final Throwable error) {
|
||||
return new Result<>(error);
|
||||
}
|
||||
|
||||
/** Use this to get the resulting value of existing or throw an Runtime exception with
|
||||
* given message otherwise.
|
||||
*
|
||||
|
@ -113,4 +129,23 @@ public final class Result<T> {
|
|||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/** Use this to create a Result of a given resulting value.
|
||||
*
|
||||
* @param value resulting value
|
||||
* @return Result instance contains a resulting value and no error */
|
||||
public static final <T> Result<T> of(final T value) {
|
||||
assert value != null : "value has null reference";
|
||||
return new Result<>(value);
|
||||
}
|
||||
|
||||
/** Use this to create a Result with error
|
||||
*
|
||||
* @param error the error that is wrapped within the created Result
|
||||
* @return Result of specified error */
|
||||
public static final <T> Result<T> ofError(final Throwable error) {
|
||||
assert error != null : "error has null reference";
|
||||
return new Result<>(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
60
src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java
Normal file
60
src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
/** Use this to extract a single element from a Collection. This also checks if there is only a single element
|
||||
* within the Collection.
|
||||
*
|
||||
* @param collection the Collection to extract the single and only element
|
||||
* @return The single element
|
||||
* @throws IllegalArgumentException if the collection is null, or empty or has more then one element */
|
||||
public static final <T> Result<T> getSingle(final Collection<T> collection) {
|
||||
if (collection == null || collection.isEmpty() || collection.size() > 1) {
|
||||
return Result.ofError(
|
||||
new IllegalArgumentException(
|
||||
"Collection has no or more then one element. Expected is exaclty one. Size: " +
|
||||
((collection != null) ? collection.size() : "null")));
|
||||
}
|
||||
|
||||
return Result.of(collection.iterator().next());
|
||||
}
|
||||
|
||||
/** Use this to create an immutable Collection of specified type from varargs
|
||||
*
|
||||
* @param values elements of the new immutable Collection
|
||||
* @return an immutable Collection of specified type with given elements */
|
||||
@SafeVarargs
|
||||
public static final <T> Collection<T> immutableCollectionOf(final T... values) {
|
||||
if (values == null || values.length <= 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableCollection(Arrays.asList(values));
|
||||
}
|
||||
|
||||
/** Use this to create an immutable Set of specified type from varargs
|
||||
*
|
||||
* @param values elements of the new immutable Set
|
||||
* @return an immutable Set of specified type with given elements */
|
||||
@SafeVarargs
|
||||
public static final <T> Set<T> immutableSetOf(final T... items) {
|
||||
if (items == null || items.length <= 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(items)));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
server.address=localhost
|
||||
server.port=8080
|
||||
|
||||
server.servlet.context-path=/
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
server.address=localhost
|
||||
server.port=8090
|
||||
server.servlet.context-path=/api/
|
||||
|
||||
spring.datasource.initialize=true
|
||||
spring.datasource.initialization-mode=always
|
||||
spring.datasource.url=jdbc:mariadb://localhost:6603/SEBServer?useSSL=false&createDatabaseIfNotExist=true
|
||||
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
|
||||
spring.datasource.platform=dev
|
||||
|
||||
server.port=8090
|
||||
spring.datasource.platform=dev
|
103
src/test/java/ch/ethz/seb/sebserver/gbl/util/ResultTest.java
Normal file
103
src/test/java/ch/ethz/seb/sebserver/gbl/util/ResultTest.java
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ResultTest {
|
||||
|
||||
@Test
|
||||
public void testCreate() {
|
||||
final Result<String> of = Result.of("VALUE");
|
||||
final Result<Object> ofError = Result.ofError(new RuntimeException("Some Error"));
|
||||
|
||||
assertNotNull(of.get());
|
||||
assertEquals("VALUE", of.get());
|
||||
|
||||
assertTrue(ofError.hasError());
|
||||
assertEquals("Some Error", ofError.getError().getMessage());
|
||||
|
||||
try {
|
||||
Result.of(null);
|
||||
fail("Exception expected");
|
||||
} catch (final Throwable t) {
|
||||
assertEquals("value has null reference", t.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
Result.ofError(null);
|
||||
fail("Exception expected");
|
||||
} catch (final Throwable t) {
|
||||
assertEquals("error has null reference", t.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap() {
|
||||
final Result<String> resultOf = Result.of("1");
|
||||
final Result<String> resultOfError = Result.ofError(new RuntimeException("Some Error"));
|
||||
|
||||
final Result<Integer> numberResult = resultOf.map(r -> Integer.parseInt(r));
|
||||
final Result<Integer> numberResultOfError = resultOfError.map(r -> Integer.parseInt(r));
|
||||
|
||||
assertNotNull(numberResult);
|
||||
assertEquals(Integer.valueOf(1), numberResult.get());
|
||||
|
||||
assertTrue(numberResultOfError.hasError());
|
||||
assertEquals("Some Error", numberResultOfError.getError().getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFlatMap() {
|
||||
final Result<String> resultOf = Result.of("1");
|
||||
final Result<String> resultOfError = Result.ofError(new RuntimeException("Some Error"));
|
||||
|
||||
final Result<Integer> numberResult = resultOf.flatMap(r -> Result.of(Integer.parseInt(r)));
|
||||
final Result<Integer> numberResultOfError = resultOfError.flatMap(r -> Result.of(Integer.parseInt(r)));
|
||||
|
||||
assertNotNull(numberResult);
|
||||
assertEquals(Integer.valueOf(1), numberResult.get());
|
||||
|
||||
assertTrue(numberResultOfError.hasError());
|
||||
assertEquals("Some Error", numberResultOfError.getError().getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOrElse() {
|
||||
final Result<String> resultOf = Result.of("ONE");
|
||||
final Result<String> resultOfError = Result.ofError(new RuntimeException("Some Error"));
|
||||
|
||||
assertEquals("ONE", resultOf.orElse("TWO"));
|
||||
assertEquals("TWO", resultOfError.orElse("TWO"));
|
||||
|
||||
assertEquals("ONE", resultOf.orElse(() -> "TWO"));
|
||||
assertEquals("TWO", resultOfError.orElse(() -> "TWO"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnError() {
|
||||
final Result<String> resultOf = Result.of("ONE");
|
||||
final Result<String> resultOfError = Result.ofError(new RuntimeException("Some Error"));
|
||||
|
||||
assertEquals("ONE", resultOf.onError(t -> t.getMessage()));
|
||||
assertEquals("Some Error", resultOfError.onError(t -> t.getMessage()));
|
||||
|
||||
assertEquals("ONE", resultOf.onErrorThrow("Should not be thrown"));
|
||||
try {
|
||||
resultOfError.onErrorThrow("Should be thrown");
|
||||
fail("Excpetion expected here");
|
||||
} catch (final Throwable t) {
|
||||
assertEquals("Should be thrown", t.getMessage());
|
||||
assertEquals("Some Error", t.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
71
src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java
Normal file
71
src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class UtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetSingle() {
|
||||
final Collection<String> singleCollection = Utils.immutableCollectionOf("ONE");
|
||||
final Collection<String> collection = Utils.immutableCollectionOf("ONE", "TWO");
|
||||
|
||||
final Result<String> r1 = Utils.getSingle(null);
|
||||
final Result<String> r2 = Utils.getSingle(Collections.emptyList());
|
||||
final Result<String> r3 = Utils.getSingle(singleCollection);
|
||||
final Result<String> r4 = Utils.getSingle(collection);
|
||||
|
||||
assertTrue(r1.hasError());
|
||||
assertTrue(r2.hasError());
|
||||
assertFalse(r3.hasError());
|
||||
assertTrue(r4.hasError());
|
||||
|
||||
assertEquals("ONE", r3.get());
|
||||
assertEquals("Collection has no or more then one element. Expected is exaclty one. Size: null",
|
||||
r1.getError().getMessage());
|
||||
assertEquals("Collection has no or more then one element. Expected is exaclty one. Size: 2",
|
||||
r4.getError().getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmutableCollectionOf() {
|
||||
final Collection<String> r1 = Utils.immutableCollectionOf((String[]) null);
|
||||
final Collection<String> r2 = Utils.immutableCollectionOf((String) null);
|
||||
final Collection<String> r3 = Utils.immutableCollectionOf(null, null);
|
||||
final Collection<String> r4 = Utils.immutableCollectionOf("ONE", "TWO");
|
||||
|
||||
assertEquals("[]", r1.toString());
|
||||
assertEquals("[null]", r2.toString());
|
||||
assertEquals("[null, null]", r3.toString());
|
||||
assertEquals("[ONE, TWO]", r4.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmutableSetOf() {
|
||||
final Set<String> r1 = Utils.immutableSetOf((String[]) null);
|
||||
final Set<String> r2 = Utils.immutableSetOf((String) null);
|
||||
final Set<String> r3 = Utils.immutableSetOf(null, null);
|
||||
final Set<String> r4 = Utils.immutableSetOf("ONE", "TWO");
|
||||
final Set<String> r5 = Utils.immutableSetOf("ONE", "TWO", "ONE");
|
||||
|
||||
assertEquals("[]", r1.toString());
|
||||
assertEquals("[null]", r2.toString());
|
||||
assertEquals("[null]", r3.toString());
|
||||
assertEquals("[ONE, TWO]", r4.toString());
|
||||
assertEquals("[ONE, TWO]", r5.toString());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue