diff --git a/Twitter4J/pom.xml b/Twitter4J/pom.xml index 80236a2cd4..982c1adc23 100644 --- a/Twitter4J/pom.xml +++ b/Twitter4J/pom.xml @@ -1,13 +1,9 @@ 4.0.0 - - com.mabsisa Twitter4J jar - 1.0-SNAPSHOT Twitter4J - http://maven.apache.org com.baeldung @@ -23,27 +19,6 @@ - - ${project.artifactId} - - - src/main/resources - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/ApplicationTest.java - - - - - - 4.0.6 diff --git a/activejdbc/pom.xml b/activejdbc/pom.xml index 0c8047f10b..542e674ff3 100644 --- a/activejdbc/pom.xml +++ b/activejdbc/pom.xml @@ -1,7 +1,6 @@ 4.0.0 - com.baeldung activejdbc 1.0-SNAPSHOT jar @@ -79,55 +78,11 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - brief - true - false - - **/*Spec*.java - **/*Test*.java - - - **/helpers/* - **/*$* - - - - - - snapshots1 - JavaLite Snapshots1 - http://repo.javalite.io/ - - true - always - warn - - - - - - - snapshots2 - JavaLite Snapshots2 - http://repo.javalite.io/ - - true - always - warn - - - - - 1.4.13 + 2.0 development.test,development 5.1.34 diff --git a/activejdbc/src/main/java/com/baeldung/model/Employee.java b/activejdbc/src/main/java/com/baeldung/model/Employee.java index b7fa8aaf1f..e6e9be2aac 100644 --- a/activejdbc/src/main/java/com/baeldung/model/Employee.java +++ b/activejdbc/src/main/java/com/baeldung/model/Employee.java @@ -16,4 +16,8 @@ public class Employee extends Model { set("created_by",createdBy); } + public String getLastName() { + return getString("last_name"); + } + } diff --git a/activejdbc/src/main/java/com/baeldung/model/Role.java b/activejdbc/src/main/java/com/baeldung/model/Role.java index 3f425dbe6b..bbd5a7d169 100644 --- a/activejdbc/src/main/java/com/baeldung/model/Role.java +++ b/activejdbc/src/main/java/com/baeldung/model/Role.java @@ -15,4 +15,8 @@ public class Role extends Model { set("role_name",role); set("created_by",createdBy); } + + public String getRoleName() { + return getString("role_name"); + } } diff --git a/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java similarity index 97% rename from activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java rename to activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java index 316dc34712..22eb87f930 100644 --- a/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppTest.java +++ b/activejdbc/src/test/java/com/baeldung/ActiveJDBCAppManualTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import java.util.List; -public class ActiveJDBCAppTest extends DBSpec +public class ActiveJDBCAppManualTest extends DBSpec { @Test public void ifEmployeeCreated_thenIsValid() { diff --git a/algorithms/roundUpToHundred/.gitignore b/algorithms/roundUpToHundred/.gitignore new file mode 100644 index 0000000000..ae3c172604 --- /dev/null +++ b/algorithms/roundUpToHundred/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java new file mode 100644 index 0000000000..f5024c227d --- /dev/null +++ b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundred.java @@ -0,0 +1,20 @@ +package com.java.src; + +import java.util.Scanner; + +public class RoundUpToHundred { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + double input = scanner.nextDouble(); + scanner.close(); + + RoundUpToHundred.round(input); + } + + static long round(double input) { + long i = (long) Math.ceil(input); + return ((i + 99) / 100) * 100; + }; + +} diff --git a/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java new file mode 100644 index 0000000000..f35a9a249f --- /dev/null +++ b/algorithms/roundUpToHundred/src/com/java/src/RoundUpToHundredTest.java @@ -0,0 +1,14 @@ +package com.java.src; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class RoundUpToHundredTest { + @Test + public void givenInput_whenRound_thenRoundUpToTheNearestHundred() { + assertEquals("Rounded up to hundred", 100, RoundUpToHundred.round(99)); + assertEquals("Rounded up to three hundred ", 300, RoundUpToHundred.round(200.2)); + assertEquals("Returns same rounded value", 400, RoundUpToHundred.round(400)); + } +} diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml index 3a72804ab1..98d9563284 100644 --- a/apache-shiro/pom.xml +++ b/apache-shiro/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung apache-shiro 1.0-SNAPSHOT @@ -36,13 +35,11 @@ org.slf4j jcl-over-slf4j - ${slf4j-version} runtime org.slf4j slf4j-log4j12 - ${slf4j-version} runtime @@ -53,26 +50,9 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${java.version} - ${java.version} - - - - - 1.4.0 - 3.7.0 - 1.8 1.2.17 - 1.7.25 \ No newline at end of file diff --git a/asm/pom.xml b/asm/pom.xml index 7bbaa2a8f1..5aad2a0e37 100644 --- a/asm/pom.xml +++ b/asm/pom.xml @@ -42,14 +42,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - -javaagent:"C:\asm-1.0.jar" - - diff --git a/cas/cas-secured-app/pom.xml b/cas/cas-secured-app/pom.xml index 22d1522fbe..2291da9084 100644 --- a/cas/cas-secured-app/pom.xml +++ b/cas/cas-secured-app/pom.xml @@ -2,12 +2,10 @@ 4.0.0 - com.baeldung cas-secured-app - 0.0.1-SNAPSHOT jar cas-secured-app - Demo project for Spring Boot + Demo project for CAS parent-boot-1 @@ -60,10 +58,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/cas/cas-server/pom.xml b/cas/cas-server/pom.xml index a15b4b58d5..9b61aaec3d 100644 --- a/cas/cas-server/pom.xml +++ b/cas/cas-server/pom.xml @@ -2,11 +2,17 @@ 4.0.0 - com.baeldung cas-server war 1.0 + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 + + org.apereo.cas @@ -39,7 +45,6 @@ org.springframework.boot spring-boot-maven-plugin - ${springboot.version} ${mainClassName} true @@ -74,42 +79,10 @@ - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - cas - - - sonatype-releases - http://oss.sonatype.org/content/repositories/releases/ - - false - - - true - - - - sonatype-snapshots - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - false - - - - shibboleth-releases - https://build.shibboleth.net/nexus/content/repositories/releases - - - @@ -214,8 +187,7 @@ - 5.3.0-SNAPSHOT - 1.5.13.RELEASE + 5.3.3 -tomcat @@ -223,14 +195,12 @@ false ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF - 1.8 - 1.8 - UTF-8 0.0.4 2.6 3.3 + 0.3.0 1.1.0 - \ No newline at end of file + diff --git a/core-java-9/logging.sh b/core-java-9/logging.sh new file mode 100755 index 0000000000..c9b502f300 --- /dev/null +++ b/core-java-9/logging.sh @@ -0,0 +1,15 @@ +# compile logging module +# javac --module-path mods -d mods/com.baeldung.logging src/modules/com.baeldung.logging/module-info.java src/modules/com.baeldung.logging/com/baeldung/logging/*.java + +# compile logging slf4j module +javac --module-path mods -d mods/com.baeldung.logging.slf4j src/modules/com.baeldung.logging.slf4j/module-info.java src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/*.java + + +# compile logging main app module +javac --module-path mods -d mods/com.baeldung.logging.app src/modules/com.baeldung.logging.app/module-info.java src/modules/com.baeldung.logging.app/com/baeldung/logging/app/*.java + +# run logging main app +# java --module-path mods -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp + +# run looging main app using logback +java --module-path mods -Dlogback.configurationFile=mods/logback.xml -m com.baeldung.logging.app/com.baeldung.logging.app.MainApp diff --git a/core-java-9/mods/logback.xml b/core-java-9/mods/logback.xml new file mode 100644 index 0000000000..c22c7a7130 --- /dev/null +++ b/core-java-9/mods/logback.xml @@ -0,0 +1,16 @@ + + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} -- %msg%n + + + + + + + + + \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java b/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java new file mode 100644 index 0000000000..01f53d59e9 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.app/com/baeldung/logging/app/MainApp.java @@ -0,0 +1,13 @@ +package com.baeldung.logging.app; + +import static java.lang.System.Logger.*; + +public class MainApp { + + private static System.Logger LOGGER = System.getLogger("MainApp"); + + public static void main(String[] args) { + LOGGER.log(Level.ERROR, "error test"); + LOGGER.log(Level.INFO, "info test"); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.app/module-info.java b/core-java-9/src/modules/com.baeldung.logging.app/module-info.java new file mode 100644 index 0000000000..037c72b755 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.app/module-info.java @@ -0,0 +1,2 @@ +module com.baeldung.logging.app { +} \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java new file mode 100644 index 0000000000..df41e071fd --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -0,0 +1,99 @@ +package com.baeldung.logging.slf4j; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ResourceBundle; + +public class Slf4jLogger implements System.Logger { + + private final String name; + private final Logger logger; + + public Slf4jLogger(String name) { + this.name = name; + logger = LoggerFactory.getLogger(name); + } + + @Override + public String getName() { + return name; + } + + @Override + public boolean isLoggable(Level level) { + switch (level) { + case OFF: + return false; + case TRACE: + return logger.isTraceEnabled(); + case DEBUG: + return logger.isDebugEnabled(); + case INFO: + return logger.isInfoEnabled(); + case WARNING: + return logger.isWarnEnabled(); + case ERROR: + return logger.isErrorEnabled(); + case ALL: + default: + return true; + } + } + + @Override + public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) { + if (!isLoggable(level)) { + return; + } + + switch (level) { + case TRACE: + logger.trace(msg, thrown); + break; + case DEBUG: + logger.debug(msg, thrown); + break; + case INFO: + logger.info(msg, thrown); + break; + case WARNING: + logger.warn(msg, thrown); + break; + case ERROR: + logger.error(msg, thrown); + break; + case ALL: + default: + logger.info(msg, thrown); + } + } + + @Override + public void log(Level level, ResourceBundle bundle, String format, Object... params) { + if (!isLoggable(level)) { + return; + } + + switch (level) { + case TRACE: + logger.trace(format, params); + break; + case DEBUG: + logger.debug(format, params); + break; + case INFO: + logger.info(format, params); + break; + case WARNING: + logger.warn(format, params); + break; + case ERROR: + logger.error(format, params); + break; + case ALL: + default: + logger.info(format, params); + } + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java new file mode 100644 index 0000000000..97f7cccb92 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLoggerFinder.java @@ -0,0 +1,8 @@ +package com.baeldung.logging.slf4j; + +public class Slf4jLoggerFinder extends System.LoggerFinder { + @Override + public System.Logger getLogger(String name, Module module) { + return new Slf4jLogger(name); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java b/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java new file mode 100644 index 0000000000..311ca22f5b --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging.slf4j/module-info.java @@ -0,0 +1,6 @@ +module com.baeldung.logging.slf4j { + requires org.slf4j; + provides java.lang.System.LoggerFinder + with com.baeldung.logging.slf4j.Slf4jLoggerFinder; + exports com.baeldung.logging.slf4j; +} \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java new file mode 100644 index 0000000000..a495e6979d --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/ConsoleLogger.java @@ -0,0 +1,27 @@ +package com.baeldung.logging; + +import java.text.MessageFormat; +import java.util.ResourceBundle; + +public class ConsoleLogger implements System.Logger { + + @Override + public String getName() { + return "ConsoleLogger"; + } + + @Override + public boolean isLoggable(Level level) { + return true; + } + + @Override + public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) { + System.out.printf("ConsoleLogger [%s]: %s - %s%n", level, msg, thrown); + } + + @Override + public void log(Level level, ResourceBundle bundle, String format, Object... params) { + System.out.printf("ConsoleLogger [%s]: %s%n", level, MessageFormat.format(format, params)); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java new file mode 100644 index 0000000000..b38955f199 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/com/baeldung/logging/CustomLoggerFinder.java @@ -0,0 +1,9 @@ +package com.baeldung.logging; + +public class CustomLoggerFinder extends System.LoggerFinder { + + @Override + public System.Logger getLogger(String name, Module module) { + return new ConsoleLogger(); + } +} diff --git a/core-java-9/src/modules/com.baeldung.logging/module-info.java b/core-java-9/src/modules/com.baeldung.logging/module-info.java new file mode 100644 index 0000000000..4ca0af0225 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.logging/module-info.java @@ -0,0 +1,5 @@ +module com.baeldung.logging { + provides java.lang.System.LoggerFinder + with com.baeldung.logging.CustomLoggerFinder; + exports com.baeldung.logging; +} \ No newline at end of file diff --git a/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java b/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java new file mode 100644 index 0000000000..688c7592f3 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/java/map/MapUtil.java @@ -0,0 +1,44 @@ +/** + * + */ +package com.baeldung.java.map; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.stream.Stream; + +/** + * @author swpraman + * + */ +public class MapUtil { + + public static Stream keys(Map map, V value) { + return map.entrySet() + .stream() + .filter(entry -> value.equals(entry.getValue())) + .map(Map.Entry::getKey); + } + + public static Set getKeys(Map map, V value) { + Set keys = new HashSet<>(); + for (Entry entry : map.entrySet()) { + if (entry.getValue().equals(value)) { + keys.add(entry.getKey()); + } + } + return keys; + } + + public static K getKey(Map map, V value) { + for (Entry entry : map.entrySet()) { + if (entry.getValue().equals(value)) { + return entry.getKey(); + } + } + return null; + } + +} diff --git a/core-java-collections/src/main/java/com/baeldung/performance/Employee.java b/core-java-collections/src/main/java/com/baeldung/performance/Employee.java index d811cfbb7d..1ed4410371 100644 --- a/core-java-collections/src/main/java/com/baeldung/performance/Employee.java +++ b/core-java-collections/src/main/java/com/baeldung/performance/Employee.java @@ -44,4 +44,12 @@ public class Employee { result = 31 * result + name.hashCode(); return result; } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } } diff --git a/core-java-collections/src/main/java/com/baeldung/sort/Employee.java b/core-java-collections/src/main/java/com/baeldung/sort/Employee.java new file mode 100644 index 0000000000..b5e56f6141 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/sort/Employee.java @@ -0,0 +1,60 @@ +package com.baeldung.sort; + +public class Employee implements Comparable { + + private Long id; + private String name; + + public Employee(Long id, String name) { + this.name = name; + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Employee employee = (Employee) o; + + if (!id.equals(employee.id)) return false; + return name.equals(employee.name); + + } + + @Override + public int hashCode() { + int result = id.hashCode(); + result = 31 * result + name.hashCode(); + return result; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public int compareTo(Employee employee) { + return (int)(this.id - employee.getId()); + } +} diff --git a/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java b/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java new file mode 100644 index 0000000000..b8a2b32060 --- /dev/null +++ b/core-java-collections/src/main/java/com/baeldung/sort/SortHashMap.java @@ -0,0 +1,104 @@ +package com.baeldung.sort; + +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableSortedMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; + +import java.util.*; +import java.util.stream.Collectors; + +public class SortHashMap { + + private static Map map = new HashMap<>(); + + public static void main(String[] args) { + + initialize(); + + treeMapSortByKey(); + + arrayListSortByValue(); + arrayListSortByKey(); + + sortStream(); + + sortGuava(); + + addDuplicates(); + + treeSetByKey(); + treeSetByValue(); + + } + + private static void sortGuava() { + final Ordering naturalOrdering = + Ordering.natural().onResultOf(Functions.forMap(map, null)); + + System.out.println(ImmutableSortedMap.copyOf(map, naturalOrdering)); + } + + private static void sortStream() { + map.entrySet().stream() + .sorted(Map.Entry.comparingByKey().reversed()) + .forEach(System.out::println); + + Map result = map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, + (oldValue, newValue) -> oldValue, LinkedHashMap::new)); + + result.entrySet().forEach(System.out::println); + } + + private static void treeSetByValue() { + SortedSet values = new TreeSet<>(map.values()); + System.out.println(values); + } + + private static void treeSetByKey() { + SortedSet keysSet = new TreeSet<>(map.keySet()); + System.out.println(keysSet); + } + + private static void treeMapSortByKey() { + TreeMap sorted = new TreeMap<>(map); + sorted.putAll(map); + + sorted.entrySet().forEach(System.out::println); + + } + + private static void arrayListSortByValue() { + List employeeById = new ArrayList<>(map.values()); + + Collections.sort(employeeById); + + System.out.println(employeeById); + } + + private static void arrayListSortByKey() { + List employeeByKey = new ArrayList<>(map.keySet()); + Collections.sort(employeeByKey); + System.out.println(employeeByKey); + } + + private static void initialize() { + Employee employee1 = new Employee(1L, "Mher"); + map.put(employee1.getName(), employee1); + Employee employee2 = new Employee(22L, "Annie"); + map.put(employee2.getName(), employee2); + Employee employee3 = new Employee(8L, "John"); + map.put(employee3.getName(), employee3); + Employee employee4 = new Employee(2L, "George"); + map.put(employee4.getName(), employee4); + } + + private static void addDuplicates() { + Employee employee5 = new Employee(1L, "Mher"); + map.put(employee5.getName(), employee5); + Employee employee6 = new Employee(22L, "Annie"); + map.put(employee6.getName(), employee6); + } +} diff --git a/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java b/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java new file mode 100644 index 0000000000..8b0a7ef0db --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/collection/ClearVsRemoveAllUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.collection; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Unit tests demonstrating differences between ArrayList#clear() and ArrayList#removeAll() + */ +class ClearVsRemoveAllUnitTest { + + /* + * Tests + */ + @Test + void givenArrayListWithElements_whenClear_thenListBecomesEmpty() { + Collection collection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); + + collection.clear(); + + assertTrue(collection.isEmpty()); + } + + @Test + void givenTwoArrayListsWithCommonElements_whenRemoveAll_thenFirstListMissElementsFromSecondList() { + Collection firstCollection = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); + Collection secondCollection = new ArrayList<>(Arrays.asList(3, 4, 5, 6, 7)); + + firstCollection.removeAll(secondCollection); + + assertEquals(Arrays.asList(1, 2), firstCollection); + assertEquals(Arrays.asList(3, 4, 5, 6, 7), secondCollection); + } + +} diff --git a/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java b/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java new file mode 100644 index 0000000000..e31385e972 --- /dev/null +++ b/core-java-collections/src/test/java/com/baeldung/java/map/MapUtilUnitTest.java @@ -0,0 +1,104 @@ +/** + * + */ +package com.baeldung.java.map; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.DualHashBidiMap; +import org.junit.Test; + +import com.google.common.collect.HashBiMap; + +/** + * @author swpraman + * + */ +public class MapUtilUnitTest { + + + @Test + public void whenUsingImperativeWayForSingleKey_shouldReturnSingleKey() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("New Delhi", "India"); + assertEquals("New Delhi", MapUtil.getKey(capitalCountryMap, "India")); + } + + @Test + public void whenUsingImperativeWayForAllKeys_shouldReturnAllKeys() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + capitalCountryMap.put("Bloemfontein", "South Africa"); + + assertEquals(new HashSet(Arrays.asList( + new String[] {"Cape Town", "Pretoria", "Bloemfontein"})), + MapUtil.getKeys(capitalCountryMap, "South Africa")); + } + + @Test + public void whenUsingFunctionalWayForSingleKey_shouldReturnSingleKey() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + assertEquals("Berlin", MapUtil.keys(capitalCountryMap, "Germany").findFirst().get()); + } + + @Test + public void whenUsingFunctionalWayForAllKeys_shouldReturnAllKeys() { + Map capitalCountryMap = new HashMap<>(); + capitalCountryMap.put("Tokyo", "Japan"); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + capitalCountryMap.put("Bloemfontein", "South Africa"); + assertEquals(new HashSet(Arrays.asList( + new String[] {"Cape Town", "Pretoria", "Bloemfontein"})), + MapUtil.keys(capitalCountryMap, "South Africa").collect(Collectors.toSet())); + } + + @Test + public void whenUsingBidiMap_shouldReturnKey() { + BidiMap capitalCountryMap = new DualHashBidiMap(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + assertEquals("Berlin", capitalCountryMap.getKey("Germany")); + } + + @Test + public void whenUsingBidiMapAddDuplicateValue_shouldRemoveOldEntry() { + BidiMap capitalCountryMap = new DualHashBidiMap(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + assertEquals("Pretoria", capitalCountryMap.getKey("South Africa")); + } + + @Test + public void whenUsingBiMap_shouldReturnKey() { + HashBiMap capitalCountryMap = HashBiMap.create(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + assertEquals("Berlin", capitalCountryMap.inverse().get("Germany")); + } + + @Test(expected=IllegalArgumentException.class) + public void whenUsingBiMapAddDuplicateValue_shouldThrowException() { + HashBiMap capitalCountryMap = HashBiMap.create(); + capitalCountryMap.put("Berlin", "Germany"); + capitalCountryMap.put("Cape Town", "South Africa"); + capitalCountryMap.put("Pretoria", "South Africa"); + assertEquals("Berlin", capitalCountryMap.inverse().get("Germany")); + } + +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java new file mode 100644 index 0000000000..b31a04015f --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java @@ -0,0 +1,17 @@ +package com.baeldung.concurrent.yield; + +public class ThreadYield { + public static void main(String[] args) { + Runnable r = () -> { + int counter = 0; + while (counter < 2) { + System.out.println(Thread.currentThread() + .getName()); + counter++; + Thread.yield(); + } + }; + new Thread(r).start(); + new Thread(r).start(); + } +} diff --git a/core-java-io/pom.xml b/core-java-io/pom.xml index bc71fb8838..cf3e950cb8 100644 --- a/core-java-io/pom.xml +++ b/core-java-io/pom.xml @@ -1,7 +1,6 @@ 4.0.0 - com.baeldung core-java-io 0.1.0-SNAPSHOT jar @@ -166,36 +165,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - - true - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot-maven-plugin.version} - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - org.codehaus.mojo exec-maven-plugin @@ -229,32 +198,6 @@ integration - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - **/*IntTest.java - - - - - - - json - - - org.codehaus.mojo exec-maven-plugin @@ -310,14 +253,11 @@ 1.7.0 - 1.8 - 1.8 3.0.0-M1 2.4.0 2.1.0.1 1.19 2.4.5 - 2.0.4.RELEASE \ No newline at end of file diff --git a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java index 7da71a093d..42147b07db 100644 --- a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java +++ b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java @@ -24,6 +24,13 @@ public class ZipDirectory { return; } if (fileToZip.isDirectory()) { + if (fileName.endsWith("/")) { + zipOut.putNextEntry(new ZipEntry(fileName)); + zipOut.closeEntry(); + } else { + zipOut.putNextEntry(new ZipEntry(fileName + "/")); + zipOut.closeEntry(); + } final File[] children = fileToZip.listFiles(); for (final File childFile : children) { zipFile(childFile, fileName + "/" + childFile.getName(), zipOut); diff --git a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java index 7968967679..6a020f5eae 100644 --- a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java +++ b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java @@ -1,6 +1,7 @@ package com.baeldung.file; import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.hamcrest.CoreMatchers; import org.hamcrest.Matchers; import org.junit.Test; @@ -120,4 +121,14 @@ public class FileOperationsManualTest { return resultStringBuilder.toString(); } + + @Test + public void givenFileName_whenUsingIOUtils_thenFileData() throws IOException { + String expectedData = "This is a content of the file"; + + FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt"); + String data = IOUtils.toString(fis, "UTF-8"); + + assertEquals(expectedData, data.trim()); + } } \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java similarity index 96% rename from core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java rename to core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java index 803d8881b4..caa7049475 100644 --- a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java +++ b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java @@ -9,7 +9,7 @@ import java.nio.file.Paths; import org.junit.Test; -public class SymLinkExampleUnitTest { +public class SymLinkExampleManualTest { @Test public void whenUsingFiles_thenCreateSymbolicLink() throws IOException { diff --git a/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java b/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java deleted file mode 100644 index 87d10a3548..0000000000 --- a/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.decimalformat; - - import java.math.RoundingMode; - import java.text.DecimalFormat; - import java.text.NumberFormat; - import java.util.Locale; - - public class DoubletoString { - - public static void main(String[] args) { - - double doubleValue = 345.56; - - System.out.println(String.valueOf((int) doubleValue)); - - System.out.println(String.format("%.0f", doubleValue)); - - doubleValue = Math.floor(doubleValue); - DecimalFormat df = new DecimalFormat("#"); - df.setRoundingMode(RoundingMode.FLOOR); - System.out.println(df.format(doubleValue)); - - Locale enlocale = new Locale("en", "US"); - String pattern = "###,##"; - df = (DecimalFormat) NumberFormat.getNumberInstance(enlocale); - df.applyPattern(pattern); - String format = df.format(doubleValue); - System.out.println(format); - - Locale dalocale = new Locale("da", "DK"); - df = (DecimalFormat) NumberFormat.getNumberInstance(dalocale); - df.applyPattern(pattern); - System.out.println(df.format(doubleValue)); - - - } - - } diff --git a/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java new file mode 100644 index 0000000000..a28ac3d5a1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java @@ -0,0 +1,40 @@ +package com.baeldung.doubles; + +import java.math.BigDecimal; + +public class SplitFloatingPointNumbers { + + public static void main(String[] args) { + + double doubleNumber = 24.04; + splitUsingFloatingTypes(doubleNumber); + splitUsingString(doubleNumber); + splitUsingBigDecimal(doubleNumber); + } + + private static void splitUsingFloatingTypes(double doubleNumber) { + System.out.println("Using Floating Point Arithmetics:"); + int intPart = (int) doubleNumber; + System.out.println("Double Number: "+doubleNumber); + System.out.println("Integer Part: "+ intPart); + System.out.println("Decimal Part: "+ (doubleNumber - intPart)); + } + + private static void splitUsingString(double doubleNumber) { + System.out.println("Using String Operations:"); + String doubleAsString = String.valueOf(doubleNumber); + int indexOfDecimal = doubleAsString.indexOf("."); + System.out.println("Double Number: "+doubleNumber); + System.out.println("Integer Part: "+ doubleAsString.substring(0, indexOfDecimal)); + System.out.println("Decimal Part: "+ doubleAsString.substring(indexOfDecimal)); + } + + private static void splitUsingBigDecimal(double doubleNumber) { + System.out.println("Using BigDecimal Operations:"); + BigDecimal bigDecimal = new BigDecimal(String.valueOf(doubleNumber)); + int intValue = bigDecimal.intValue(); + System.out.println("Double Number: "+bigDecimal.toPlainString()); + System.out.println("Integer Part: "+intValue); + System.out.println("Decimal Part: "+bigDecimal.subtract(new BigDecimal(intValue)).toPlainString()); + } +} diff --git a/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java new file mode 100644 index 0000000000..8cce20de8d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java @@ -0,0 +1,25 @@ +package com.baeldung.heapdump; + +import com.sun.management.HotSpotDiagnosticMXBean; + +import javax.management.MBeanServer; + +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.nio.file.Paths; + +public class HeapDump { + + public static void dumpHeap(String filePath, boolean live) throws IOException { + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy( + server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class); + mxBean.dumpHeap(filePath, live); + } + + public static void main(String[] args) throws IOException { + String file = Paths.get("dump.hprof").toFile().getPath(); + + dumpHeap(file, true); + } +} diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java new file mode 100644 index 0000000000..e2259e4249 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java @@ -0,0 +1,149 @@ +package com.baeldung.passwordhashing; + +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Arrays; +import java.util.Base64; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; + +/** + * Hash passwords for storage, and test passwords against password tokens. + * + * Instances of this class can be used concurrently by multiple threads. + * + * @author erickson + * @see StackOverflow + */ +public final class PBKDF2Hasher +{ + + /** + * Each token produced by this class uses this identifier as a prefix. + */ + public static final String ID = "$31$"; + + /** + * The minimum recommended cost, used by default + */ + public static final int DEFAULT_COST = 16; + + private static final String ALGORITHM = "PBKDF2WithHmacSHA1"; + + private static final int SIZE = 128; + + private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})"); + + private final SecureRandom random; + + private final int cost; + + public PBKDF2Hasher() + { + this(DEFAULT_COST); + } + + /** + * Create a password manager with a specified cost + * + * @param cost the exponential computational cost of hashing a password, 0 to 30 + */ + public PBKDF2Hasher(int cost) + { + iterations(cost); /* Validate cost */ + this.cost = cost; + this.random = new SecureRandom(); + } + + private static int iterations(int cost) + { + if ((cost < 0) || (cost > 30)) + throw new IllegalArgumentException("cost: " + cost); + return 1 << cost; + } + + /** + * Hash a password for storage. + * + * @return a secure authentication token to be stored for later authentication + */ + public String hash(char[] password) + { + byte[] salt = new byte[SIZE / 8]; + random.nextBytes(salt); + byte[] dk = pbkdf2(password, salt, 1 << cost); + byte[] hash = new byte[salt.length + dk.length]; + System.arraycopy(salt, 0, hash, 0, salt.length); + System.arraycopy(dk, 0, hash, salt.length, dk.length); + Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding(); + return ID + cost + '$' + enc.encodeToString(hash); + } + + /** + * Authenticate with a password and a stored password token. + * + * @return true if the password and token match + */ + public boolean checkPassword(char[] password, String token) + { + Matcher m = layout.matcher(token); + if (!m.matches()) + throw new IllegalArgumentException("Invalid token format"); + int iterations = iterations(Integer.parseInt(m.group(1))); + byte[] hash = Base64.getUrlDecoder().decode(m.group(2)); + byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8); + byte[] check = pbkdf2(password, salt, iterations); + int zero = 0; + for (int idx = 0; idx < check.length; ++idx) + zero |= hash[salt.length + idx] ^ check[idx]; + return zero == 0; + } + + private static byte[] pbkdf2(char[] password, byte[] salt, int iterations) + { + KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE); + try { + SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM); + return f.generateSecret(spec).getEncoded(); + } + catch (NoSuchAlgorithmException ex) { + throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex); + } + catch (InvalidKeySpecException ex) { + throw new IllegalStateException("Invalid SecretKeyFactory", ex); + } + } + + /** + * Hash a password in an immutable {@code String}. + * + *

Passwords should be stored in a {@code char[]} so that it can be filled + * with zeros after use instead of lingering on the heap and elsewhere. + * + * @deprecated Use {@link #hash(char[])} instead + */ + @Deprecated + public String hash(String password) + { + return hash(password.toCharArray()); + } + + /** + * Authenticate with a password in an immutable {@code String} and a stored + * password token. + * + * @deprecated Use {@link #checkPassword(char[],String)} instead. + * @see #hash(String) + */ + @Deprecated + public boolean checkPassword(String password, String token) + { + return checkPassword(password.toCharArray(), token); + } + +} diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java new file mode 100644 index 0000000000..4f5337f963 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java @@ -0,0 +1,35 @@ +package com.baeldung.passwordhashing; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + + +/** A really simple SHA_512 Encryption example. + * + */ +public class SHA512Hasher { + + public String hash(String passwordToHash, byte[] salt){ + String generatedPassword = null; + try { + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(salt); + byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8)); + StringBuilder sb = new StringBuilder(); + for(int i=0; i< bytes.length ;i++){ + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + generatedPassword = sb.toString(); + } + catch (NoSuchAlgorithmException e){ + e.printStackTrace(); + } + return generatedPassword; + } + + public boolean checkPassword(String hash, String attempt, byte[] salt){ + String generatedHash = hash(attempt, salt); + return hash.equals(generatedHash); + } +} diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java new file mode 100644 index 0000000000..36c9b65070 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java @@ -0,0 +1,18 @@ +package com.baeldung.passwordhashing; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import java.security.spec.KeySpec; + +/** A really simple SimplePBKDF2 Encryption example. + * + */ +public class SimplePBKDF2Hasher { + + public static String hashSimple(String password, byte[] salt) throws Exception{ + KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); + SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + byte[] hash = f.generateSecret(spec).getEncoded(); + return String.valueOf(hash); + } +} diff --git a/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java new file mode 100644 index 0000000000..69e151bfcb --- /dev/null +++ b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java @@ -0,0 +1,70 @@ +package com.baeldung.switchstatement; + +public class SwitchStatement { + + public String exampleOfIF(String animal) { + + String result; + + if (animal.equals("DOG") || animal.equals("CAT")) { + result = "domestic animal"; + } else if (animal.equals("TIGER")) { + result = "wild animal"; + } else { + result = "unknown animal"; + } + return result; + } + + public String exampleOfSwitch(String animal) { + + String result; + + switch (animal) { + case "DOG": + case "CAT": + result = "domestic animal"; + break; + case "TIGER": + result = "wild animal"; + break; + default: + result = "unknown animal"; + break; + } + return result; + } + + public String forgetBreakInSwitch(String animal) { + + String result; + + switch (animal) { + + case "DOG": + System.out.println("domestic animal"); + result = "domestic animal"; + + default: + System.out.println("unknown animal"); + result = "unknown animal"; + + } + return result; + } + + public String constantCaseValue(String animal) { + + String result = ""; + + final String dog = "DOG"; + + switch (animal) { + + case dog: + result = "domestic animal"; + } + return result; + } + +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java new file mode 100644 index 0000000000..fb92eb8d0d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java @@ -0,0 +1,13 @@ +package com.baeldung.zoneddatetime; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +public class OffsetDateTimeExample { + + public OffsetDateTime getCurrentTimeByZoneOffset(String offset) { + ZoneOffset zoneOffSet= ZoneOffset.of(offset); + OffsetDateTime date = OffsetDateTime.now(zoneOffSet); + return date; + } +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java new file mode 100644 index 0000000000..58e2d4d5ad --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java @@ -0,0 +1,13 @@ +package com.baeldung.zoneddatetime; + +import java.time.OffsetTime; +import java.time.ZoneOffset; + +public class OffsetTimeExample { + + public OffsetTime getCurrentTimeByZoneOffset(String offset) { + ZoneOffset zoneOffSet = ZoneOffset.of(offset); + OffsetTime time = OffsetTime.now(zoneOffSet); + return time; + } +} diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java new file mode 100644 index 0000000000..b54b8c5225 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java @@ -0,0 +1,21 @@ +package com.baeldung.zoneddatetime; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +public class ZoneDateTimeExample { + + public ZonedDateTime getCurrentTimeByZoneId(String region) { + ZoneId zone = ZoneId.of(region); + ZonedDateTime date = ZonedDateTime.now(zone); + return date; + } + + public ZonedDateTime convertZonedDateTime(ZonedDateTime sourceDate, String destZone) { + + ZoneId destZoneId = ZoneId.of(destZone); + ZonedDateTime destDate = sourceDate.withZoneSameInstant(destZoneId); + + return destDate; + } +} diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java new file mode 100644 index 0000000000..8e90725c77 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.passwordhashing; + +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class PBKDF2HasherUnitTest { + + private PBKDF2Hasher mPBKDF2Hasher; + + @Before + public void setUp() throws Exception { + mPBKDF2Hasher = new PBKDF2Hasher(); + } + + @Test + public void givenCorrectMessageAndHash_whenAuthenticated_checkAuthenticationSucceeds() throws Exception { + String message1 = "password123"; + + String hash1 = mPBKDF2Hasher.hash(message1.toCharArray()); + + assertTrue(mPBKDF2Hasher.checkPassword(message1.toCharArray(), hash1)); + + } + + @Test + public void givenWrongMessage_whenAuthenticated_checkAuthenticationFails() throws Exception { + String message1 = "password123"; + + String hash1 = mPBKDF2Hasher.hash(message1.toCharArray()); + + String wrongPasswordAttempt = "IamWrong"; + + assertFalse(mPBKDF2Hasher.checkPassword(wrongPasswordAttempt.toCharArray(), hash1)); + + } + + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java new file mode 100644 index 0000000000..3acfb0ba9d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.passwordhashing; + +import org.junit.Before; +import org.junit.Test; + +import java.security.SecureRandom; + +import static org.junit.Assert.*; + +/** + * Created by PhysicsSam on 06-Sep-18. + */ +public class SHA512HasherUnitTest { + + private SHA512Hasher hasher; + private SecureRandom secureRandom; + + @Before + public void setUp() throws Exception { + hasher = new SHA512Hasher(); + secureRandom = new SecureRandom(); + } + + @Test + public void givenSamePasswordAndSalt_whenHashed_checkResultingHashesAreEqual() throws Exception { + + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String hash1 = hasher.hash("password", salt); + String hash2 = hasher.hash("password", salt); + + assertEquals(hash1, hash2); + + } + + @Test + public void givenSamePasswordAndDifferentSalt_whenHashed_checkResultingHashesNotEqual() throws Exception { + + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + String hash1 = hasher.hash("password", salt); + //generate a second salt + byte[] secondSalt = new byte[16]; + String hash2 = hasher.hash("password", secondSalt); + + assertNotEquals(hash1, hash2); + + } + + @Test + public void givenPredefinedHash_whenCorrectAttemptGiven_checkAuthenticationSucceeds() throws Exception { + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String originalHash = hasher.hash("password123", salt); + + assertTrue(hasher.checkPassword(originalHash, "password123", salt)); + } + + @Test + public void givenPredefinedHash_whenIncorrectAttemptGiven_checkAuthenticationFails() throws Exception { + byte[] salt = new byte[16]; + secureRandom.nextBytes(salt); + + String originalHash = hasher.hash("password123", salt); + + assertFalse(hasher.checkPassword(originalHash, "password124", salt)); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java new file mode 100644 index 0000000000..8dbfcaf5e7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java @@ -0,0 +1,100 @@ +package com.baeldung.removingdecimals; + +import org.junit.Test; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.concurrent.TimeUnit; + +/** + * This benchmark compares some of the approaches to formatting a floating-point + * value into a {@link String} while removing the decimal part. + * + * To run, simply run the {@link RemovingDecimalsManualTest#runBenchmarks()} test + * at the end of this class. + * + * The benchmark takes about 15 minutes to run. Since it is using {@link Mode#Throughput}, + * higher numbers mean better performance. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 5) +@Measurement(iterations = 20) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Benchmark) +public class RemovingDecimalsManualTest { + @Param(value = {"345.56", "345345345.56", "345345345345345345.56"}) double doubleValue; + + NumberFormat nf; + DecimalFormat df; + + @Setup + public void readyFormatters() { + nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + df = new DecimalFormat("#,###"); + } + + @Benchmark + public String whenCastToInt_thenValueIsTruncated() { + return String.valueOf((int) doubleValue); + } + + @Benchmark + public String whenUsingStringFormat_thenValueIsRounded() { + return String.format("%.0f", doubleValue); + } + + @Benchmark + public String whenUsingNumberFormat_thenValueIsRounded() { + nf.setRoundingMode(RoundingMode.HALF_UP); + return nf.format(doubleValue); + } + + @Benchmark + public String whenUsingNumberFormatWithFloor_thenValueIsTruncated() { + nf.setRoundingMode(RoundingMode.FLOOR); + return nf.format(doubleValue); + } + + @Benchmark + public String whenUsingDecimalFormat_thenValueIsRounded() { + df.setRoundingMode(RoundingMode.HALF_UP); + return df.format(doubleValue); + } + + @Benchmark + public String whenUsingDecimalFormatWithFloor_thenValueIsTruncated() { + df.setRoundingMode(RoundingMode.FLOOR); + return df.format(doubleValue); + } + + @Benchmark + public String whenUsingBigDecimalDoubleValue_thenValueIsTruncated() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.FLOOR); + return big.toString(); + } + + @Benchmark + public String whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.HALF_UP); + return big.toString(); + } + + @Test + public void runBenchmarks() throws Exception { + Options options = new OptionsBuilder() + .include(this.getClass().getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true).shouldDoGC(true) + .jvmArgs("-server").build(); + + new Runner(options).run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java new file mode 100644 index 0000000000..2f634b553b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.removingdecimals; + +import org.junit.Test; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.NumberFormat; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * Tests that demonstrate some different approaches for formatting a + * floating-point value into a {@link String} while removing the decimal part. + */ +public class RemovingDecimalsUnitTest { + private final double doubleValue = 345.56; + + @Test + public void whenCastToInt_thenValueIsTruncated() { + String truncated = String.valueOf((int) doubleValue); + assertEquals("345", truncated); + } + + @Test + public void givenALargeDouble_whenCastToInt_thenValueIsNotTruncated() { + double outOfIntRange = 6_000_000_000.56; + String truncationAttempt = String.valueOf((int) outOfIntRange); + assertNotEquals("6000000000", truncationAttempt); + } + + @Test + public void whenUsingStringFormat_thenValueIsRounded() { + String rounded = String.format("%.0f", doubleValue); + assertEquals("346", rounded); + } + + @Test + public void givenALargeDouble_whenUsingStringFormat_thenValueIsStillRounded() { + double outOfIntRange = 6_000_000_000.56; + String rounded = String.format("%.0f", outOfIntRange); + assertEquals("6000000001", rounded); + } + + @Test + public void whenUsingNumberFormat_thenValueIsRounded() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + nf.setRoundingMode(RoundingMode.HALF_UP); + String rounded = nf.format(doubleValue); + assertEquals("346", rounded); + } + + @Test + public void whenUsingNumberFormatWithFloor_thenValueIsTruncated() { + NumberFormat nf = NumberFormat.getInstance(); + nf.setMaximumFractionDigits(0); + nf.setRoundingMode(RoundingMode.FLOOR); + String truncated = nf.format(doubleValue); + assertEquals("345", truncated); + } + + @Test + public void whenUsingDecimalFormat_thenValueIsRounded() { + DecimalFormat df = new DecimalFormat("#,###"); + df.setRoundingMode(RoundingMode.HALF_UP); + String rounded = df.format(doubleValue); + assertEquals("346", rounded); + } + + @Test + public void whenUsingDecimalFormatWithFloor_thenValueIsTruncated() { + DecimalFormat df = new DecimalFormat("#,###"); + df.setRoundingMode(RoundingMode.FLOOR); + String truncated = df.format(doubleValue); + assertEquals("345", truncated); + } + + @Test + public void whenUsingBigDecimalDoubleValue_thenValueIsTruncated() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.FLOOR); + String truncated = big.toString(); + assertEquals("345", truncated); + } + + @Test + public void whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() { + BigDecimal big = new BigDecimal(doubleValue); + big = big.setScale(0, RoundingMode.HALF_UP); + String truncated = big.toString(); + assertEquals("346", truncated); + } +} diff --git a/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java new file mode 100644 index 0000000000..e8ac645531 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.switchstatement; + +import org.junit.Test; + +import org.junit.Assert; + +public class SwitchStatementUnitTest { + private SwitchStatement s = new SwitchStatement(); + + + @Test + public void whenDog_thenDomesticAnimal() { + + String animal = "DOG"; + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + @Test + public void whenNoBreaks_thenGoThroughBlocks() { + String animal = "DOG"; + Assert.assertEquals("unknown animal", s.forgetBreakInSwitch(animal)); + } + + @Test(expected=NullPointerException.class) + public void whenSwitchAgumentIsNull_thenNullPointerException() { + String animal = null; + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + + @Test + public void whenCompareStrings_thenByEqual() { + String animal = new String("DOG"); + Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); + } + + +} diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java new file mode 100644 index 0000000000..a08d3737cd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +import org.junit.Test; + +public class OffsetDateTimeExampleUnitTest { + + OffsetDateTimeExample offsetDateTimeExample = new OffsetDateTimeExample(); + + @Test + public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() { + String offset = "+02:00"; + OffsetDateTime time = offsetDateTimeExample.getCurrentTimeByZoneOffset(offset); + + assertTrue(time.getOffset() + .equals(ZoneOffset.of(offset))); + } +} diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java new file mode 100644 index 0000000000..488f934179 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.OffsetTime; +import java.time.ZoneOffset; + +import org.junit.Test; + +public class OffsetTimeExampleUnitTest { + + OffsetTimeExample offsetTimeExample = new OffsetTimeExample(); + + @Test + public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() { + String offset = "+02:00"; + OffsetTime time = offsetTimeExample.getCurrentTimeByZoneOffset(offset); + + assertTrue(time.getOffset() + .equals(ZoneOffset.of(offset))); + } +} diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java new file mode 100644 index 0000000000..e78ff3e3fd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.zoneddatetime; + +import static org.junit.Assert.assertTrue; + +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.Test; + +public class ZoneDateTimeExampleUnitTest { + + ZoneDateTimeExample zoneDateTimeExample = new ZoneDateTimeExample(); + + @Test + public void givenZone_whenGetCurrentTime_thenResultHasZone() { + String zone = "Europe/Berlin"; + ZonedDateTime time = zoneDateTimeExample.getCurrentTimeByZoneId(zone); + + assertTrue(time.getZone() + .equals(ZoneId.of(zone))); + } + + @Test + public void givenZones_whenConvertDateByZone_thenGetConstantDiff() { + String sourceZone = "Europe/Berlin"; + String destZone = "Asia/Tokyo"; + ZonedDateTime sourceDate = zoneDateTimeExample.getCurrentTimeByZoneId(sourceZone); + ZonedDateTime destDate = zoneDateTimeExample.convertZonedDateTime(sourceDate, destZone); + + assertTrue(sourceDate.toInstant() + .compareTo(destDate.toInstant()) == 0); + } +} diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml index 70cbd67645..0894a57320 100644 --- a/core-kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -55,6 +55,12 @@ fuel-coroutines ${fuel.version} + + nl.komponents.kovenant + kovenant + 3.3.0 + pom + diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt similarity index 100% rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt new file mode 100644 index 0000000000..469118f0f6 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt @@ -0,0 +1,191 @@ +package com.baeldung.kotlin + +import nl.komponents.kovenant.* +import nl.komponents.kovenant.Kovenant.deferred +import nl.komponents.kovenant.combine.and +import nl.komponents.kovenant.combine.combine +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import java.io.IOException +import java.util.* +import java.util.concurrent.TimeUnit + +class KovenantTest { + @Before + fun setupTestMode() { + Kovenant.testMode { error -> + println("An unexpected error occurred") + Assert.fail(error.message) + } + } + + @Test + fun testSuccessfulDeferred() { + val def = deferred() + Assert.assertFalse(def.promise.isDone()) + + def.resolve(1L) + Assert.assertTrue(def.promise.isDone()) + Assert.assertTrue(def.promise.isSuccess()) + Assert.assertFalse(def.promise.isFailure()) + } + + @Test + fun testFailedDeferred() { + val def = deferred() + Assert.assertFalse(def.promise.isDone()) + + def.reject(RuntimeException()) + Assert.assertTrue(def.promise.isDone()) + Assert.assertFalse(def.promise.isSuccess()) + Assert.assertTrue(def.promise.isFailure()) + } + + @Test + fun testResolveDeferredTwice() { + val def = deferred() + def.resolve(1L) + try { + def.resolve(1L) + } catch (e: AssertionError) { + // Expected. + // This is slightly unusual. The AssertionError comes from Assert.fail() from setupTestMode() + } + } + + @Test + fun testSuccessfulTask() { + val promise = task { 1L } + Assert.assertTrue(promise.isDone()) + Assert.assertTrue(promise.isSuccess()) + Assert.assertFalse(promise.isFailure()) + } + + @Test + fun testFailedTask() { + val promise = task { throw RuntimeException() } + Assert.assertTrue(promise.isDone()) + Assert.assertFalse(promise.isSuccess()) + Assert.assertTrue(promise.isFailure()) + } + + @Test + fun testCallbacks() { + val promise = task { 1L } + + promise.success { + println("This was a success") + Assert.assertEquals(1L, it) + } + + promise.fail { + println(it) + Assert.fail("This shouldn't happen") + } + + promise.always { + println("This always happens") + } + } + + @Test + fun testGetValues() { + val promise = task { 1L } + Assert.assertEquals(1L, promise.get()) + } + + @Test + fun testAllSucceed() { + val numbers = all( + task { 1L }, + task { 2L }, + task { 3L } + ) + + Assert.assertEquals(listOf(1L, 2L, 3L), numbers.get()) + } + + @Test + fun testOneFails() { + val runtimeException = RuntimeException() + + val numbers = all( + task { 1L }, + task { 2L }, + task { throw runtimeException } + ) + + Assert.assertEquals(runtimeException, numbers.getError()) + } + + @Test + fun testAnySucceeds() { + val promise = any( + task { + TimeUnit.SECONDS.sleep(3) + 1L + }, + task { + TimeUnit.SECONDS.sleep(2) + 2L + }, + task { + TimeUnit.SECONDS.sleep(1) + 3L + } + ) + + Assert.assertTrue(promise.isDone()) + Assert.assertTrue(promise.isSuccess()) + Assert.assertFalse(promise.isFailure()) + } + + @Test + fun testAllFails() { + val runtimeException = RuntimeException() + val ioException = IOException() + val illegalStateException = IllegalStateException() + val promise = any( + task { + TimeUnit.SECONDS.sleep(3) + throw runtimeException + }, + task { + TimeUnit.SECONDS.sleep(2) + throw ioException + }, + task { + TimeUnit.SECONDS.sleep(1) + throw illegalStateException + } + ) + + Assert.assertTrue(promise.isDone()) + Assert.assertFalse(promise.isSuccess()) + Assert.assertTrue(promise.isFailure()) + } + + @Test + fun testSimpleCombine() { + val promise = task { 1L } and task { "Hello" } + val result = promise.get() + + Assert.assertEquals(1L, result.first) + Assert.assertEquals("Hello", result.second) + } + + @Test + fun testLongerCombine() { + val promise = combine( + task { 1L }, + task { "Hello" }, + task { Currency.getInstance("USD") } + ) + val result = promise.get() + + Assert.assertEquals(1L, result.first) + Assert.assertEquals("Hello", result.second) + Assert.assertEquals(Currency.getInstance("USD"), result.third) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt new file mode 100644 index 0000000000..e37d2cc2fa --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt @@ -0,0 +1,38 @@ +package com.baeldung.kotlin + +import nl.komponents.kovenant.Promise +import nl.komponents.kovenant.any +import nl.komponents.kovenant.task +import org.junit.Assert +import org.junit.Ignore +import org.junit.Test + +@Ignore +// Note that this can not run in the same test run if KovenantTest has already been executed +class KovenantTimeoutTest { + @Test + fun testTimeout() { + val promise = timedTask(1000) { "Hello" } + val result = promise.get() + Assert.assertEquals("Hello", result) + } + + @Test + fun testTimeoutExpired() { + val promise = timedTask(1000) { + Thread.sleep(3000) + "Hello" + } + val result = promise.get() + Assert.assertNull(result) + } + + fun timedTask(millis: Long, body: () -> T) : Promise> { + val timeoutTask = task { + Thread.sleep(millis) + null + } + val activeTask = task(body = body) + return any(activeTask, timeoutTask) + } +} diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt new file mode 100644 index 0000000000..9c371614a4 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt @@ -0,0 +1,48 @@ +package com.baeldung.kotlin + +import org.junit.Test +import kotlin.test.assertEquals + +class StringConcatenationTest { + + @Test + fun givenTwoStrings_concatenateWithTemplates_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = "$a $b" + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithPlusOperator_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = a + " " + b + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithStringBuilder_thenEquals() { + val a = "Hello" + val b = "Baeldung" + + val builder = StringBuilder() + builder.append(a).append(" ").append(b) + + val c = builder.toString() + + assertEquals("Hello Baeldung", c) + } + + @Test + fun givenTwoStrings_concatenateWithPlusMethod_thenEquals() { + val a = "Hello" + val b = "Baeldung" + val c = a.plus(" ").plus(b) + + assertEquals("Hello Baeldung", c) + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 23d7d2e201..2212e736ab 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,5 +1,11 @@ package com.baeldung.hibernate; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +import com.baeldung.hibernate.entities.DeptEmployee; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent; import com.baeldung.hibernate.pessimisticlocking.Individual; @@ -16,10 +22,30 @@ import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.service.ServiceRegistry; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URL; -import java.util.Properties; +import com.baeldung.hibernate.pojo.Course; +import com.baeldung.hibernate.pojo.Employee; +import com.baeldung.hibernate.pojo.EntityDescription; +import com.baeldung.hibernate.pojo.OrderEntry; +import com.baeldung.hibernate.pojo.OrderEntryIdClass; +import com.baeldung.hibernate.pojo.OrderEntryPK; +import com.baeldung.hibernate.pojo.Person; +import com.baeldung.hibernate.pojo.Phone; +import com.baeldung.hibernate.pojo.PointEntity; +import com.baeldung.hibernate.pojo.PolygonEntity; +import com.baeldung.hibernate.pojo.Product; +import com.baeldung.hibernate.pojo.Student; +import com.baeldung.hibernate.pojo.TemporalValues; +import com.baeldung.hibernate.pojo.User; +import com.baeldung.hibernate.pojo.UserProfile; +import com.baeldung.hibernate.pojo.inheritance.Animal; +import com.baeldung.hibernate.pojo.inheritance.Bag; +import com.baeldung.hibernate.pojo.inheritance.Book; +import com.baeldung.hibernate.pojo.inheritance.Car; +import com.baeldung.hibernate.pojo.inheritance.MyEmployee; +import com.baeldung.hibernate.pojo.inheritance.MyProduct; +import com.baeldung.hibernate.pojo.inheritance.Pen; +import com.baeldung.hibernate.pojo.inheritance.Pet; +import com.baeldung.hibernate.pojo.inheritance.Vehicle; public class HibernateUtil { private static SessionFactory sessionFactory; @@ -72,6 +98,8 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(PessimisticLockingCourse.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class); + metadataSources.addAnnotatedClass(DeptEmployee.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class); metadataSources.addAnnotatedClass(OptimisticLockingCourse.class); metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java new file mode 100644 index 0000000000..ff94f4f849 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java @@ -0,0 +1,45 @@ +package com.baeldung.hibernate.entities; + +import java.util.List; + +import javax.persistence.*; + +@Entity +public class Department { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String name; + + @OneToMany(mappedBy="department") + private List employees; + + public Department(String name) { + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java new file mode 100644 index 0000000000..7a51009b62 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java @@ -0,0 +1,65 @@ +package com.baeldung.hibernate.entities; + +import javax.persistence.*; + +@Entity +public class DeptEmployee { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private long id; + + private String employeeNumber; + + private String designation; + + private String name; + + @ManyToOne + private Department department; + + public DeptEmployee(String name, String employeeNumber, Department department) { + this.name = name; + this.employeeNumber = employeeNumber; + this.department = department; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEmployeeNumber() { + return employeeNumber; + } + + public void setEmployeeNumber(String employeeNumber) { + this.employeeNumber = employeeNumber; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + this.department = department; + } + + public String getDesignation() { + return designation; + } + + public void setDesignation(String designation) { + this.designation = designation; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java new file mode 100644 index 0000000000..607269a267 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java @@ -0,0 +1,31 @@ +package com.baeldung.hibernate.pojo; + +public class Result { + private String employeeName; + + private String departmentName; + + public Result(String employeeName, String departmentName) { + this.employeeName = employeeName; + this.departmentName = departmentName; + } + + public Result() { + } + + public String getEmployeeName() { + return employeeName; + } + + public void setEmployeeName(String employeeName) { + this.employeeName = employeeName; + } + + public String getDepartmentName() { + return departmentName; + } + + public void setDepartmentName(String departmentName) { + this.departmentName = departmentName; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/BatchEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/BatchEmployee.java new file mode 100644 index 0000000000..00643ab3dd --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/BatchEmployee.java @@ -0,0 +1,56 @@ +package com.baeldung.hibernate.proxy; + +import org.hibernate.annotations.BatchSize; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@BatchSize(size = 5) +public class BatchEmployee implements Serializable { + + @Id + @GeneratedValue (strategy = GenerationType.SEQUENCE) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + private Boss boss; + + @Column(name = "name") + private String name; + + @Column(name = "surname") + private String surname; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Boss getBoss() { + return boss; + } + + public void setBoss(Boss boss) { + this.boss = boss; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java new file mode 100644 index 0000000000..b6e01814d0 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java @@ -0,0 +1,49 @@ +package com.baeldung.hibernate.proxy; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +public class Boss implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; + + @Column(name = "name") + private String name; + + @Column(name = "surname") + private String surname; + + public Boss() { } + + public Boss(String name, String surname) { + this.name = name; + this.surname = surname; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java new file mode 100644 index 0000000000..6bc64c35ef --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java @@ -0,0 +1,53 @@ +package com.baeldung.hibernate.proxy; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +public class Employee implements Serializable { + + @Id + @GeneratedValue (strategy = GenerationType.SEQUENCE) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + private Boss boss; + + @Column(name = "name") + private String name; + + @Column(name = "surname") + private String surname; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Boss getBoss() { + return boss; + } + + public void setBoss(Boss boss) { + this.boss = boss; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java new file mode 100644 index 0000000000..e6ad0432bd --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java @@ -0,0 +1,57 @@ +package com.baeldung.hibernate.proxy; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.SessionFactoryBuilder; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + + private static SessionFactory sessionFactory; + private static String PROPERTY_FILE_NAME; + + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; + if (sessionFactory == null) { + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = getSessionFactoryBuilder(serviceRegistry).build(); + } + return sessionFactory; + } + + private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) { + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + metadataSources.addPackage("com.baeldung.hibernate.proxy"); + metadataSources.addAnnotatedClass(Boss.class); + metadataSources.addAnnotatedClass(Employee.class); + + Metadata metadata = metadataSources.buildMetadata(); + return metadata.getSessionFactoryBuilder(); + + } + + private static ServiceRegistry configureServiceRegistry() throws IOException { + Properties properties = getProperties(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties")); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java new file mode 100644 index 0000000000..29ae55b773 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.hibernate; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; +import java.util.List; + +import com.baeldung.hibernate.entities.DeptEmployee; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.query.Query; +import org.hibernate.transform.Transformers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.baeldung.hibernate.entities.Department; +import com.baeldung.hibernate.pojo.Result; + +public class CustomClassIntegrationTest { + + private Session session; + + private Transaction transaction; + + @BeforeEach + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory().openSession(); + transaction = session.beginTransaction(); + session.createNativeQuery("delete from manager").executeUpdate(); + session.createNativeQuery("delete from department").executeUpdate(); + Department department = new Department("Sales"); + DeptEmployee employee = new DeptEmployee("John Smith", "001", department); + session.persist(department); + session.persist(employee); + transaction.commit(); + transaction = session.beginTransaction(); + } + + @Test + public void whenAllManagersAreSelected_ThenObjectGraphIsReturned() { + Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee"); + List deptEmployees = query.list(); + DeptEmployee deptEmployee = deptEmployees.get(0); + assertEquals("John Smith", deptEmployee.getName()); + assertEquals("Sales", deptEmployee.getDepartment().getName()); + } + + @Test + public void whenIndividualPropertiesAreSelected_ThenObjectArrayIsReturned() { + Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m"); + List managers = query.list(); + Object[] manager = (Object[]) managers.get(0); + assertEquals("John Smith", manager[0]); + assertEquals("Sales", manager[1]); + } + + @Test + public void whenResultConstructorInSelect_ThenListOfResultIsReturned() { + Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name) " + + "from DeptEmployee m"); + List results = query.list(); + Result result = results.get(0); + assertEquals("John Smith", result.getEmployeeName()); + assertEquals("Sales", result.getDepartmentName()); + } + + @Test + public void whenResultTransformerOnQuery_ThenListOfResultIsReturned() { + Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName " + + "from com.baeldung.hibernate.entities.DeptEmployee m"); + query.setResultTransformer(Transformers.aliasToBean(Result.class)); + List results = query.list(); + Result result = results.get(0); + assertEquals("John Smith", result.getEmployeeName()); + assertEquals("Sales", result.getDepartmentName()); + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java new file mode 100644 index 0000000000..fa41797dd2 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.hibernate.proxy; + +import org.hibernate.*; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.List; + +import static org.junit.Assert.fail; + +public class HibernateProxyUnitTest { + + private Session session; + + @Before + public void init(){ + try { + session = HibernateUtil.getSessionFactory("hibernate.properties") + .openSession(); + } catch (HibernateException | IOException e) { + fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]"); + } + + Boss boss = new Boss("Eduard", "Freud"); + session.save(boss); + } + + @After + public void close(){ + if(session != null) { + session.close(); + } + } + + @Test(expected = NullPointerException.class) + public void givenAnInexistentEmployeeId_whenUseGetMethod_thenReturnNull() { + Employee employee = session.get(Employee.class, new Long(14)); + assertNull(employee); + employee.getId(); + } + + @Test + public void givenAnInexistentEmployeeId_whenUseLoadMethod_thenReturnAProxy() { + Employee employee = session.load(Employee.class, new Long(14)); + assertNotNull(employee); + } + + @Test + public void givenABatchEmployeeList_whenSaveOne_thenSaveTheWholeBatch() { + Transaction transaction = session.beginTransaction(); + + for (long i = 1; i <= 5; i++) { + Employee employee = new Employee(); + employee.setName("Employee " + i); + session.save(employee); + } + + //After this line is possible to see all the insertions in the logs + session.flush(); + session.clear(); + transaction.commit(); + + transaction = session.beginTransaction(); + + List employeeList = session.createQuery("from Employee") + .setCacheMode(CacheMode.IGNORE).getResultList(); + + assertEquals(employeeList.size(), 5); + transaction.commit(); + } +} diff --git a/java-streams/pom.xml b/java-streams/pom.xml index 023a5f695b..e4670c268d 100644 --- a/java-streams/pom.xml +++ b/java-streams/pom.xml @@ -105,7 +105,7 @@ 3.5 1.16.12 0.9.0 - 1.13 + 1.15 0.6.5 2.10 diff --git a/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java new file mode 100644 index 0000000000..1b64c8924a --- /dev/null +++ b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java @@ -0,0 +1,209 @@ +package com.baeldung.protonpack; + +import com.codepoetics.protonpack.Indexed; +import com.codepoetics.protonpack.StreamUtils; +import com.codepoetics.protonpack.collectors.CollectorUtils; +import com.codepoetics.protonpack.collectors.NonUniqueValueException; +import com.codepoetics.protonpack.selectors.Selector; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +@SuppressWarnings("unchecked") +public class ProtonpackUnitTest { + @Test + public void whenTakeWhile_thenTakenWhile() { + Stream streamOfInt = Stream.iterate(1, i -> i + 1); + List result = StreamUtils.takeWhile(streamOfInt, i -> i < 5).collect(Collectors.toList()); + assertThat(result).contains(1, 2, 3, 4); + } + + @Test + public void whenTakeUntil_thenTakenUntil() { + Stream streamOfInt = Stream.iterate(1, i -> i + 1); + List result = StreamUtils.takeUntil(streamOfInt, i -> i > 50).collect(Collectors.toList()); + assertThat(result).contains(10, 20, 30, 40); + } + + @Test + public void givenMultipleStream_whenZipped_thenZipped() { + String[] clubs = { "Juventus", "Barcelona", "Liverpool", "PSG" }; + String[] players = { "Ronaldo", "Messi", "Salah" }; + Set zippedFrom2Sources = StreamUtils.zip(stream(clubs), stream(players), (club, player) -> club + " " + player) + .collect(Collectors.toSet()); + assertThat(zippedFrom2Sources).contains("Juventus Ronaldo", "Barcelona Messi", "Liverpool Salah"); + + String[] leagues = { "Serie A", "La Liga", "Premier League" }; + Set zippedFrom3Sources = StreamUtils.zip(stream(clubs), stream(players), stream(leagues), + (club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet()); + assertThat(zippedFrom3Sources).contains("Juventus Ronaldo Serie A", "Barcelona Messi La Liga", + "Liverpool Salah Premier League"); + } + + @Test + public void whenZippedWithIndex_thenZippedWithIndex() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool"); + Set> zipsWithIndex = StreamUtils.zipWithIndex(streamOfClubs).collect(Collectors.toSet()); + assertThat(zipsWithIndex).contains(Indexed.index(0, "Juventus"), Indexed.index(1, "Barcelona"), + Indexed.index(2, "Liverpool")); + } + + @Test + public void givenMultipleStream_whenMerged_thenMerged() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool", "PSG"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi", "Salah"); + Stream streamOfLeagues = Stream.of("Serie A", "La Liga", "Premier League"); + + Set merged = StreamUtils.merge(() -> "", (valOne, valTwo) -> valOne + " " + valTwo, streamOfClubs, + streamOfPlayers, streamOfLeagues).collect(Collectors.toSet()); + + assertThat(merged).contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League", + " PSG"); + } + + @Test + public void givenMultipleStream_whenMergedToList_thenMergedToList() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "PSG"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi"); + + List> mergedListOfList = StreamUtils.mergeToList(streamOfClubs, streamOfPlayers) + .collect(Collectors.toList()); + assertThat(mergedListOfList.get(0)).isInstanceOf(List.class); + assertThat(mergedListOfList.get(0)).containsExactly("Juventus", "Ronaldo"); + assertThat(mergedListOfList.get(1)).containsExactly("Barcelona", "Messi"); + assertThat(mergedListOfList.get(2)).containsExactly("PSG"); + } + + @Test + public void givenMultipleStream_whenInterleaved_thenInterleaved() { + Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool"); + Stream streamOfPlayers = Stream.of("Ronaldo", "Messi"); + Stream streamOfLeagues = Stream.of("Serie A", "La Liga"); + + AtomicInteger counter = new AtomicInteger(0); + Selector roundRobinSelector = (o) -> { + Object[] vals = (Object[]) o; + while (counter.get() >= vals.length || vals[counter.get()] == null) { + if (counter.incrementAndGet() >= vals.length) + counter.set(0); + } + return counter.getAndIncrement(); + }; + Stream interleavedStream = StreamUtils.interleave(roundRobinSelector, streamOfClubs, streamOfPlayers, + streamOfLeagues); + List interleavedList = interleavedStream.collect(Collectors.toList()); + assertThat(interleavedList).containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga", + "Liverpool"); + } + + @Test + public void whenSkippedUntil_thenSkippedUntil() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + List skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5).collect(Collectors.toList()); + assertThat(skippedUntilGreaterThan5).containsExactly(6, 7, 8, 9, 10); + + List skippedUntilLessThanEquals5 = StreamUtils.skipUntil(stream(numbers), i -> i <= 5) + .collect(Collectors.toList()); + assertThat(skippedUntilLessThanEquals5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void whenSkippedWhile_thenSkippedWhile() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + List skippedWhileLessThanEquals5 = StreamUtils.skipWhile(stream(numbers), i -> i <= 5) + .collect(Collectors.toList()); + assertThat(skippedWhileLessThanEquals5).containsExactly(6, 7, 8, 9, 10); + + List skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5).collect(Collectors.toList()); + assertThat(skippedWhileGreaterThan5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + + @Test + public void givenFibonacciGenerator_whenUnfolded_thenUnfolded() { + AtomicInteger lastValue = new AtomicInteger(0); + Function> fibonacciGenerator = (i) -> (i < 10) ? + Optional.of(i + lastValue.getAndSet(i)) : + Optional.empty(); + + List fib = StreamUtils.unfold(1, fibonacciGenerator).collect(Collectors.toList()); + assertThat(fib).containsExactly(1, 1, 2, 3, 5, 8, 13); + } + + @Test + public void whenWindowed_thenWindowed() { + Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7 }; + + List> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1).collect(Collectors.toList()); + assertThat(windowedWithSkip1).containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6), + asList(5, 6, 7)); + + List> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2).collect(Collectors.toList()); + assertThat(windowedWithSkip2).containsExactly(asList(1, 2, 3), asList(3, 4, 5), asList(5, 6, 7)); + } + + @Test + public void whenAggregated_thenAggregated() { + Integer[] numbers = { 1, 2, 2, 3, 4, 4, 4, 5 }; + List> aggregated = StreamUtils.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0) + .collect(Collectors.toList()); + assertThat(aggregated).containsExactly(asList(1), asList(2, 2), asList(3), asList(4, 4, 4), asList(5)); + + List> aggregatedFixSize = StreamUtils.aggregate(stream(numbers), 5).collect(Collectors.toList()); + assertThat(aggregatedFixSize).containsExactly(asList(1, 2, 2, 3, 4), asList(4, 4, 5)); + } + + @Test + public void whenGroupedRun_thenGroupedRun() { + Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 }; + List> grouped = StreamUtils.groupRuns(stream(numbers)).collect(Collectors.toList()); + assertThat(grouped).containsExactly(asList(1, 1), asList(2), asList(3), asList(4, 4), asList(5)); + + Integer[] numbers2 = { 1, 2, 3, 1 }; + List> grouped2 = StreamUtils.groupRuns(stream(numbers2)).collect(Collectors.toList()); + assertThat(grouped2).containsExactly(asList(1), asList(2), asList(3), asList(1)); + } + + @Test + public void whenAggregatedOnListCondition_thenAggregatedOnListCondition() { + Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 }; + Stream> aggregated = StreamUtils.aggregateOnListCondition(stream(numbers), + (currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5); + assertThat(aggregated).containsExactly(asList(1, 1, 2), asList(3), asList(4), asList(4), asList(5)); + } + + @Test + public void givenProjectionFunction_whenMaxedBy_thenMaxedBy() { + Stream clubs = Stream.of("Juventus", "Barcelona", "PSG"); + Optional longestName = clubs.collect(CollectorUtils.maxBy(String::length)); + assertThat(longestName.get()).isEqualTo("Barcelona"); + } + + @Test + public void givenStreamOfMultipleElem_whenUniqueCollector_thenValueReturned() { + Stream singleElement = Stream.of(1); + Optional unique = singleElement.collect(CollectorUtils.unique()); + assertThat(unique.get()).isEqualTo(1); + + } + + @Test + public void givenStreamOfMultipleElem_whenUniqueCollector_thenExceptionThrown() { + Stream multipleElement = Stream.of(1, 2, 3); + assertThatExceptionOfType(NonUniqueValueException.class).isThrownBy(() -> { + multipleElement.collect(CollectorUtils.unique()); + }); + } + +} diff --git a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java similarity index 98% rename from java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java rename to java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java index ba1cb1f726..656a6d95f9 100644 --- a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java +++ b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java @@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -public class BenchmarkUnitTest +public class BenchmarkManualTest { public void diff --git a/java-strings/pom.xml b/java-strings/pom.xml index 2afe18f07a..b1ba49b33a 100644 --- a/java-strings/pom.xml +++ b/java-strings/pom.xml @@ -47,11 +47,21 @@ jmh-core ${jmh-core.version} + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh-core.version} + com.ibm.icu icu4j ${icu4j.version} + + com.google.guava + guava + ${guava.version} + com.vdurmont @@ -92,6 +102,7 @@ 3.6.1 1.19 61.1 + 26.0-jre \ No newline at end of file diff --git a/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java index 085be66801..cdbba1ef53 100644 --- a/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java +++ b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java @@ -2,6 +2,7 @@ package com.baeldung.string; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -32,5 +33,12 @@ public class JoinerSplitter { .mapToObj(item -> (char) item) .collect(Collectors.toList()); } + + public static Map arrayToMap(String[] arrayOfString) { + return Arrays.asList(arrayOfString) + .stream() + .map(str -> str.split(":")) + .collect(Collectors.toMap(str -> str[0], str -> str[1])); + } } diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformance.java b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java new file mode 100644 index 0000000000..4873bd320c --- /dev/null +++ b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java @@ -0,0 +1,163 @@ +package com.baeldung.string; + +import org.apache.commons.lang3.StringUtils; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Measurement(batchSize = 10000, iterations = 10) +@Warmup(batchSize = 10000, iterations = 10) +public class StringPerformance extends StringPerformanceHints { + + @Benchmark + public String benchmarkStringDynamicConcat() { + return dynamicConcat(); + } + + @Benchmark + public StringBuilder benchmarkStringBuilder() { + StringBuilder stringBuilder = new StringBuilder(result); + stringBuilder.append(baeldung); + return stringBuilder; + } + + @Benchmark + public StringBuffer benchmarkStringBuffer() { + StringBuffer stringBuffer = new StringBuffer(result); + stringBuffer.append(baeldung); + return stringBuffer; + } + + @Benchmark + public String benchmarkStringConstructor() { + return stringConstructor(); + } + + @Benchmark + public String benchmarkStringLiteral() { + return stringLiteral(); + } + + @Benchmark + public String benchmarkStringFormat_s() { + return stringFormat_s(); + } + + @Benchmark + public String benchmarkStringConcat() { + return stringConcat(); + } + + @Benchmark + public String benchmarkStringIntern() { + return stringIntern(); + } + + @Benchmark + public String benchmarkStringReplace() { + return longString.replace("average", " average !!!"); + } + + @Benchmark + public String benchmarkStringUtilsReplace() { + return StringUtils.replace(longString, "average", " average !!!"); + } + + @Benchmark + public List benchmarkGuavaSplitter() { + return guavaSplitter(); + } + + @Benchmark + public String [] benchmarkStringSplit() { + return stringSplit(); + } + + @Benchmark + public String [] benchmarkStringSplitPattern() { + return stringSplitPattern(); + } + + @Benchmark + public List benchmarkStringTokenizer() { + return stringTokenizer(); + } + + @Benchmark + public List benchmarkStringIndexOf() { + return stringIndexOf(); + } + + + @Benchmark + public String benchmarkIntegerToString() { + return stringIntegerToString(); + } + + @Benchmark + public String benchmarkStringValueOf() { + return stringValueOf(); + } + + + @Benchmark + public String benchmarkStringConvertPlus() { + return stringConvertPlus(); + } + + @Benchmark + public String benchmarkStringFormat_d() { + return stringFormat_d(); + } + + @Benchmark + public boolean benchmarkStringEquals() { + return stringEquals(); + } + + + @Benchmark + public boolean benchmarkStringEqualsIgnoreCase() { + return stringEqualsIgnoreCase(); + } + + @Benchmark + public boolean benchmarkStringMatches() { + return stringIsMatch(); + } + + @Benchmark + public boolean benchmarkPrecompiledMatches() { + return precompiledMatches(); + } + + @Benchmark + public int benchmarkStringCompareTo() { + return stringCompareTo(); + } + + @Benchmark + public boolean benchmarkStringIsEmpty() { + return stringIsEmpty(); + } + + @Benchmark + public boolean benchmarkStringLengthZero() { + return stringLengthZero(); + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(StringPerformance.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server").build(); + new Runner(options).run(); + } +} diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java b/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java new file mode 100644 index 0000000000..509222136f --- /dev/null +++ b/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java @@ -0,0 +1,133 @@ +package com.baeldung.string; + +import com.google.common.base.Splitter; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +@State(Scope.Thread) +public class StringPerformanceHints { + + protected String baeldung = "baeldung"; + protected String longString = "Hello baeldung, I am a bit longer than other Strings"; + protected String formatString = "hello %s, nice to meet you"; + protected String formatDigit = "%d"; + protected String emptyString = " "; + protected String result = ""; + + protected int sampleNumber = 100; + + protected Pattern spacePattern = Pattern.compile(emptyString); + protected Pattern longPattern = Pattern.compile(longString); + protected List stringSplit = new ArrayList<>(); + protected List stringTokenizer = new ArrayList<>(); + + protected String dynamicConcat() { + result += baeldung; + return result; + } + + protected String stringConstructor() { + return new String(baeldung); + } + + protected String stringLiteral() { + result = baeldung; + return result; + } + + protected String stringFormat_s() { + return String.format(formatString, baeldung); + } + + protected String stringFormat_d() { + return String.format(formatDigit, sampleNumber); + } + + protected String stringConcat() { + result = result.concat(baeldung); + return result; + } + + protected List stringTokenizer() { + StringTokenizer st = new StringTokenizer(longString); + while (st.hasMoreTokens()) { + stringTokenizer.add(st.nextToken()); + } + return stringTokenizer; + } + + protected List stringIndexOf() { + int pos = 0, end; + while ((end = longString.indexOf(' ', pos)) >= 0) { + stringSplit.add(longString.substring(pos, end)); + pos = end + 1; + } + return stringSplit; + } + + protected String stringIntegerToString() { + return Integer.toString(sampleNumber); + } + + protected String stringValueOf() { + return String.valueOf(sampleNumber); + } + + + protected String stringConvertPlus() { + return sampleNumber + ""; + } + + + protected boolean stringEquals() { + return longString.equals(baeldung); + } + + + protected boolean stringEqualsIgnoreCase() { + return longString.equalsIgnoreCase(baeldung); + } + + protected boolean stringIsMatch() { + return longString.matches(baeldung); + } + + protected boolean precompiledMatches() { + return longPattern.matcher(baeldung).matches(); + } + + protected int stringCompareTo() { + return longString.compareTo(baeldung); + } + + protected boolean stringIsEmpty() { + return longString.isEmpty(); + } + + protected boolean stringLengthZero() { + return longString.length() == 0; + } + + protected String [] stringSplitPattern() { + return spacePattern.split(longString, 0); + } + + protected String [] stringSplit() { + return longString.split(emptyString); + } + + protected List guavaSplitter() { + return Splitter.on(" ").trimResults() + .omitEmptyStrings() + .splitToList(longString); + } + + protected String stringIntern() { + return baeldung.intern(); + } +} diff --git a/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java index 8901bcf9db..a9488e27a4 100644 --- a/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java +++ b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java @@ -3,7 +3,9 @@ package com.baeldung.string; import org.junit.Test; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.junit.Assert.assertEquals; @@ -62,5 +64,20 @@ public class JoinerSplitterUnitTest { assertEquals(result, expectation); } + + @Test + public void givenStringArray_transformedToStream_convertToMap() { + + String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"}; + + Map expectation=new HashMap<>(); + expectation.put("language", "java"); + expectation.put("os", "linux"); + expectation.put("editor", "emacs"); + + Map result = JoinerSplitter.arrayToMap(programming_languages); + assertEquals(result, expectation); + + } } diff --git a/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java index 3859a2b26b..6157640a4a 100644 --- a/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java +++ b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java @@ -2,10 +2,11 @@ package com.baeldung.string; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; import java.util.List; import org.apache.commons.lang3.StringUtils; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.google.common.base.Splitter; @@ -54,4 +55,18 @@ public class SplitUnitTest { assertThat(resultList) .containsExactly("car", "jeep", "scooter"); } + + @Test + public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_Regex() { + assertThat(" car , jeep, scooter ".trim() + .split("\\s*,\\s*")).containsExactly("car", "jeep", "scooter"); + + } + + @Test + public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_java_8() { + assertThat(Arrays.stream(" car , jeep, scooter ".split(",")) + .map(String::trim) + .toArray(String[]::new)).containsExactly("car", "jeep", "scooter"); + } } diff --git a/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java new file mode 100644 index 0000000000..17b13f89de --- /dev/null +++ b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.string; + +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString; +import static org.hamcrest.text.IsEmptyString.isEmptyString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.lang3.StringUtils; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import com.google.common.base.Strings; + +public class StringEmptyUnitTest { + + private String text = "baeldung"; + + @Test + public void givenAString_whenCheckedForEmptyUsingJunit_shouldAssertSuccessfully() { + assertTrue(!text.isEmpty()); + assertFalse(text.isEmpty()); + assertNotEquals("", text); + assertNotSame("", text); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingHamcrest_shouldAssertSuccessfully() { + assertThat(text, not(isEmptyString())); + assertThat(text, not(isEmptyOrNullString())); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingCommonsLang_shouldAssertSuccessfully() { + assertTrue(StringUtils.isNotBlank(text)); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingAssertJ_shouldAssertSuccessfully() { + Assertions.assertThat(text).isNotEmpty(); + } + + @Test + public void givenAString_whenCheckedForEmptyUsingGuava_shouldAssertSuccessfully() { + assertFalse(Strings.isNullOrEmpty(text)); + } + +} diff --git a/jersey/pom.xml b/jersey/pom.xml index e248f9cf90..b55bdc5330 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -39,6 +39,11 @@ jersey-mvc-freemarker ${jersey.version} + + org.glassfish.jersey.ext + jersey-bean-validation + ${jersey.version} + org.glassfish.jersey.test-framework jersey-test-framework-core diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java index d4744066c4..b6b9853aae 100644 --- a/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java +++ b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java @@ -1,12 +1,14 @@ package com.baeldung.jersey.server.config; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.ServerProperties; import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature; public class ViewApplicationConfig extends ResourceConfig { public ViewApplicationConfig() { packages("com.baeldung.jersey.server"); + property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true); property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker"); register(FreemarkerMvcFeature.class);; } diff --git a/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java new file mode 100644 index 0000000000..ca49797e31 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java @@ -0,0 +1,35 @@ +package com.baeldung.jersey.server.constraints; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.regex.Pattern; + +import javax.validation.Constraint; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import javax.validation.Payload; + +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = { SerialNumber.Validator.class }) +public @interface SerialNumber { + + String message() + + default "Fruit serial number is not valid"; + + Class[] groups() default {}; + + Class[] payload() default {}; + + public class Validator implements ConstraintValidator { + @Override + public void initialize(final SerialNumber serial) { + } + + @Override + public boolean isValid(final String serial, final ConstraintValidatorContext constraintValidatorContext) { + final String serialNumRegex = "^\\d{3}-\\d{3}-\\d{4}$"; + return Pattern.matches(serialNumRegex, serial); + } + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java index 30620e331d..c55362487b 100644 --- a/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java +++ b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java @@ -1,20 +1,57 @@ package com.baeldung.jersey.server.model; +import javax.validation.constraints.Min; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement public class Fruit { - private final String name; - private final String colour; + @Min(value = 10, message = "Fruit weight must be 10 or greater") + private Integer weight; + @Size(min = 5, max = 200) + private String name; + @Size(min = 5, max = 200) + private String colour; + private String serial; + + public Fruit() { + } public Fruit(String name, String colour) { this.name = name; this.colour = colour; } - + public String getName() { return name; } + + public void setName(String name) { + this.name = name; + } + + public void setColour(String colour) { + this.colour = colour; + } public String getColour() { return colour; } + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + public String getSerial() { + return serial; + } + + public void setSerial(String serial) { + this.serial = serial; + } } diff --git a/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java new file mode 100644 index 0000000000..cea61c897b --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java @@ -0,0 +1,26 @@ +package com.baeldung.jersey.server.providers; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +public class FruitExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(final ConstraintViolationException exception) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(prepareMessage(exception)) + .type("text/plain") + .build(); + } + + private String prepareMessage(ConstraintViolationException exception) { + final StringBuilder message = new StringBuilder(); + for (ConstraintViolation cv : exception.getConstraintViolations()) { + message.append(cv.getPropertyPath() + " " + cv.getMessage() + "\n"); + } + return message.toString(); + } + +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java index 4e1fa4aa11..ee34cdd3ca 100644 --- a/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java +++ b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java @@ -5,7 +5,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -15,7 +21,9 @@ import org.glassfish.jersey.server.mvc.ErrorTemplate; import org.glassfish.jersey.server.mvc.Template; import org.glassfish.jersey.server.mvc.Viewable; +import com.baeldung.jersey.server.constraints.SerialNumber; import com.baeldung.jersey.server.model.Fruit; +import com.baeldung.jersey.service.SimpleStorageService; @Path("/fruit") public class FruitResource { @@ -52,4 +60,49 @@ public class FruitResource { return name; } + @POST + @Path("/create") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void createFruit( + @NotNull(message = "Fruit name must not be null") @FormParam("name") String name, + @NotNull(message = "Fruit colour must not be null") @FormParam("colour") String colour) { + + Fruit fruit = new Fruit(name, colour); + SimpleStorageService.storeFruit(fruit); + } + + @PUT + @Path("/update") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void updateFruit(@SerialNumber @FormParam("serial") String serial) { + Fruit fruit = new Fruit(); + fruit.setSerial(serial); + SimpleStorageService.storeFruit(fruit); + } + + @POST + @Path("/create") + @Consumes(MediaType.APPLICATION_JSON) + public void createFruit(@Valid Fruit fruit) { + SimpleStorageService.storeFruit(fruit); + } + + @GET + @Valid + @Produces(MediaType.APPLICATION_JSON) + @Path("/search/{name}") + public Fruit findFruitByName(@PathParam("name") String name) { + return SimpleStorageService.findByName(name); + } + + @GET + @Produces(MediaType.TEXT_HTML) + @Path("/exception") + @Valid + public Fruit exception() { + Fruit fruit = new Fruit(); + fruit.setName("a"); + fruit.setColour("b"); + return fruit; + } } diff --git a/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java new file mode 100644 index 0000000000..e21dd584a1 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java @@ -0,0 +1,25 @@ +package com.baeldung.jersey.service; + +import java.util.HashMap; +import java.util.Map; + +import com.baeldung.jersey.server.model.Fruit; + +public class SimpleStorageService { + + private static final Map fruits = new HashMap(); + + public static void storeFruit(final Fruit fruit) { + fruits.put(fruit.getName(), fruit); + } + + public static Fruit findByName(final String name) { + return fruits.entrySet() + .stream() + .filter(map -> name.equals(map.getKey())) + .map(map -> map.getValue()) + .findFirst() + .get(); + } + +} diff --git a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java index a0b6daed51..2eeb5710cb 100644 --- a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java +++ b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java @@ -2,41 +2,116 @@ package com.baeldung.jersey.server.rest; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.Application; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.glassfish.jersey.test.JerseyTest; -import org.junit.Assert; +import org.glassfish.jersey.test.TestProperties; import org.junit.Test; import com.baeldung.jersey.server.config.ViewApplicationConfig; +import com.baeldung.jersey.server.model.Fruit; +import com.baeldung.jersey.server.providers.FruitExceptionMapper; public class FruitResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { - return new ViewApplicationConfig(); + enable(TestProperties.LOG_TRAFFIC); + enable(TestProperties.DUMP_ENTITY); + + ViewApplicationConfig config = new ViewApplicationConfig(); + config.register(FruitExceptionMapper.class); + return config; } @Test - public void testAllFruit() { + public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { final String response = target("/fruit/all").request() .get(String.class); - Assert.assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi"))); + assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi"))); } @Test - public void testIndex() { + public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { final String response = target("/fruit").request() .get(String.class); - Assert.assertThat(response, containsString("Welcome Fruit Index Page!")); + assertThat(response, containsString("Welcome Fruit Index Page!")); } @Test - public void testErrorTemplate() { + public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { final String response = target("/fruit/orange").request() .get(String.class); - Assert.assertThat(response, containsString("Error - Fruit not found: orange!")); + assertThat(response, containsString("Error - Fruit not found: orange!")); + } + + @Test + public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { + Form form = new Form(); + form.param("name", "apple"); + form.param("colour", null); + Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED) + .post(Entity.form(form)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null")); + } + + @Test + public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { + Form form = new Form(); + form.param("serial", "2345-2345"); + + Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED) + .put(Entity.form(form)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid")); + } + + @Test + public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { + Fruit fruit = new Fruit("Blueberry", "purple"); + fruit.setWeight(1); + + Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater")); + } + + @Test + public void givenFruitExists_whenSearching_thenResponseContainsFruit() { + Fruit fruit = new Fruit(); + fruit.setName("strawberry"); + fruit.setWeight(20); + Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); + + assertEquals("Http Response should be 204 ", 204, response.getStatus()); + + final String json = target("fruit/search/strawberry").request() + .get(String.class); + assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}")); + } + + @Test + public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { + final Response response = target("fruit/exception").request() + .get(); + + assertEquals("Http Response should be 400 ", 400, response.getStatus()); + String responseString = response.readEntity(String.class); + assertThat(responseString, containsString("exception..colour size must be between 5 and 200")); + assertThat(responseString, containsString("exception..name size must be between 5 and 200")); } } diff --git a/kotlin-libraries/README.md b/kotlin-libraries/README.md index ce30c71792..30c4d03ded 100644 --- a/kotlin-libraries/README.md +++ b/kotlin-libraries/README.md @@ -6,5 +6,4 @@ - [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek) - [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson) - [Kotlin with Ktor](http://www.baeldung.com/kotlin-ktor) -- [Idiomatic Logging in Kotlin](http://www.baeldung.com/kotlin-logging) -- [Guide to the Kotlin Exposed Framework](https://www.baeldung.com/kotlin-exposed-persistence) \ No newline at end of file +- [Guide to the Kotlin Exposed Framework](https://www.baeldung.com/kotlin-exposed-persistence) diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 2b83328295..5b34a903ce 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -147,7 +147,6 @@ jmapper-core ${jmapper.version} - org.apache.crunch @@ -185,7 +184,72 @@ - + + org.apache.flink + flink-connector-kafka-0.11_2.11 + ${flink.version} + + + org.apache.flink + flink-streaming-java_2.11 + ${flink.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.apache.flink + flink-core + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-java + ${flink.version} + + + commons-logging + commons-logging + + + + + org.apache.flink + flink-test-utils_2.11 + ${flink.version} + test + + + org.assertj + assertj-core + ${assertj.version} + + + org.awaitility + awaitility + ${awaitility.version} + test + + + org.awaitility + awaitility-proxy + ${awaitility.version} + test + + @@ -336,6 +400,10 @@ 2.4.0 2.8.2 1.1.0 + 1.5.0 + 2.8.5 + 3.0.0 + 3.6.2 3.8.4 1.8 3.0.0 diff --git a/libraries/src/main/java/com/baeldung/flink/FlinkDataPipeline.java b/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/FlinkDataPipeline.java rename to libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java diff --git a/libraries/src/main/java/com/baeldung/flink/LineSplitter.java b/libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/LineSplitter.java rename to libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java diff --git a/libraries/src/main/java/com/baeldung/flink/WordCount.java b/libraries-data/src/main/java/com/baeldung/flink/WordCount.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/WordCount.java rename to libraries-data/src/main/java/com/baeldung/flink/WordCount.java diff --git a/libraries/src/main/java/com/baeldung/flink/connector/Consumers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/connector/Consumers.java rename to libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java diff --git a/libraries/src/main/java/com/baeldung/flink/connector/Producers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/connector/Producers.java rename to libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java diff --git a/libraries/src/main/java/com/baeldung/flink/model/Backup.java b/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/model/Backup.java rename to libraries-data/src/main/java/com/baeldung/flink/model/Backup.java diff --git a/libraries/src/main/java/com/baeldung/flink/model/InputMessage.java b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java similarity index 99% rename from libraries/src/main/java/com/baeldung/flink/model/InputMessage.java rename to libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java index 183fa69c11..b3f75256ae 100644 --- a/libraries/src/main/java/com/baeldung/flink/model/InputMessage.java +++ b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java @@ -18,7 +18,6 @@ public class InputMessage { public String getSender() { return sender; } - public void setSender(String sender) { this.sender = sender; } diff --git a/libraries/src/main/java/com/baeldung/flink/operator/BackupAggregator.java b/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/operator/BackupAggregator.java rename to libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java diff --git a/libraries/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java b/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java rename to libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java diff --git a/libraries/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java b/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java rename to libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java diff --git a/libraries/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java similarity index 100% rename from libraries/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java rename to libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java diff --git a/libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java similarity index 89% rename from libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java rename to libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java index 1df456bbe5..9aaf8b9877 100644 --- a/libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java +++ b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java @@ -1,8 +1,6 @@ package com.baeldung.flink.schema; import com.baeldung.flink.model.InputMessage; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.apache.flink.api.common.serialization.DeserializationSchema; diff --git a/libraries/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java diff --git a/libraries-security/.gitignore b/libraries-security/.gitignore new file mode 100644 index 0000000000..71881ad3ca --- /dev/null +++ b/libraries-security/.gitignore @@ -0,0 +1,14 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear +/bin/ diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml new file mode 100644 index 0000000000..a57f029702 --- /dev/null +++ b/libraries-security/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + libraries-security + libraries-security + jar + + + com.baeldung + parent-boot-1 + 0.0.1-SNAPSHOT + ../parent-boot-1 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.3.3.RELEASE + + + + com.github.scribejava + scribejava-apis + ${scribejava.version} + + + + junit + junit + ${junit.version} + test + + + + + + 4.12 + 2.0.4.RELEASE + 5.6.0 + + + + diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java new file mode 100644 index 0000000000..bb86c497b0 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.scribejava; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + + +@SpringBootApplication +public class ScribejavaApplication { + + public static void main(String[] args) { + SpringApplication.run(ScribejavaApplication.class, args); + } + + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java new file mode 100644 index 0000000000..cf073d3035 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java @@ -0,0 +1,27 @@ +package com.baeldung.scribejava.api; + +import com.github.scribejava.core.builder.api.DefaultApi20; + +public class MyApi extends DefaultApi20 { + + private MyApi() { + } + + private static class InstanceHolder { + private static final MyApi INSTANCE = new MyApi(); + } + + public static MyApi instance() { + return InstanceHolder.INSTANCE; + } + + @Override + public String getAccessTokenEndpoint() { + return "http://localhost:8080/oauth/token"; + } + + @Override + protected String getAuthorizationBaseUrl() { + return null; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java new file mode 100644 index 0000000000..ffe4f0cc8a --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java @@ -0,0 +1,49 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.GoogleService; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; + +@RestController +public class GoogleController { + + @Autowired + private GoogleService service; + + + @GetMapping(value ="/me/google") + public void me(HttpServletResponse response){ + String auth = service.getService().getAuthorizationUrl(); + + response.setHeader("Location", auth); + response.setStatus(302); + + } + + @GetMapping(value = "/auth/google") + public String google(@RequestParam String code, HttpServletResponse servletResponse){ + + try { + OAuth2AccessToken token = service.getService().getAccessToken(code); + + OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"); + service.getService().signRequest(token, request); + Response response = service.getService().execute(request); + return response.getBody(); + + }catch (Exception e){ + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java new file mode 100644 index 0000000000..bfcd6d960c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java @@ -0,0 +1,57 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.TwitterService; +import com.github.scribejava.core.model.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Scanner; +import java.util.concurrent.ExecutionException; + +@RestController +public class TwitterController { + + @Autowired + private TwitterService service; + + + @GetMapping(value ="/me/twitter") + public String me(HttpServletResponse servletResponse){ + try { + OAuth1RequestToken requestToken = service.getService().getRequestToken(); + + String auth = service.getService().getAuthorizationUrl(requestToken); + + Runtime runtime = Runtime.getRuntime(); + try { + runtime.exec("rundll32 url.dll,FileProtocolHandler " + auth); + } catch (IOException e) { + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return null; + } + + System.out.println("Insert twitter code:"); + Scanner in = new Scanner(System.in); + + String oauthverifier = in.nextLine(); + + final OAuth1AccessToken accessToken = service.getService().getAccessToken(requestToken,oauthverifier); + + OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.twitter.com/1.1/account/verify_credentials.json"); + service.getService().signRequest(accessToken, request); + Response response = service.getService().execute(request); + return response.getBody(); + + } catch (IOException | InterruptedException | ExecutionException e) { + servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + } + + + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java new file mode 100644 index 0000000000..68a11250de --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java @@ -0,0 +1,46 @@ +package com.baeldung.scribejava.controller; + +import com.baeldung.scribejava.service.MyService; +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.model.OAuthRequest; +import com.github.scribejava.core.model.Response; +import com.github.scribejava.core.model.Verb; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletResponse; +import java.security.Principal; + +@RestController(value = "/user") +public class UserController { + + @Autowired + private MyService service; + + @GetMapping("/me/myapi") + public String me(@RequestParam String username, @RequestParam String password, HttpServletResponse responsehttp) { + + try { + OAuth2AccessToken token = service.getService().getAccessTokenPasswordGrant(username, password); + + OAuthRequest request = new OAuthRequest(Verb.GET, "http://localhost:8080/me"); + service.getService().signRequest(token, request); + Response response = service.getService().execute(request); + + return response.getBody(); + + } catch (Exception e) { + responsehttp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + } + + return null; + + } + + @GetMapping("/me") + public Principal user(Principal principal) { + return principal; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java new file mode 100644 index 0000000000..2c7162399b --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java @@ -0,0 +1,45 @@ +package com.baeldung.scribejava.oauth; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + + +@Configuration +@EnableAuthorizationServer +public class AuthServiceConfig extends AuthorizationServerConfigurerAdapter { + + @Autowired + @Qualifier("authenticationManagerBean") + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.tokenKeyAccess("permitAll()") + .checkTokenAccess("isAuthenticated()"); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory() + .withClient("baeldung_api_key") + .secret("baeldung_api_secret") + .authorizedGrantTypes("password","refresh_token") + .scopes("read","write").autoApprove(true); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints + .authenticationManager(authenticationManager) + .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST); + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java new file mode 100644 index 0000000000..7aa51400ea --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java @@ -0,0 +1,53 @@ +package com.baeldung.scribejava.oauth; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; + +@Configuration +@EnableResourceServer +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .headers().frameOptions().disable() + .and() + .csrf().disable(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication() + .withUser("baeldung") + .password("scribejava") + .roles("USER"); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + + @EnableResourceServer + @Configuration + public class ResourceServerConfig extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/user/me").authenticated() + .and() + .csrf().disable(); + } + } + +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java new file mode 100644 index 0000000000..fbcc39763c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java @@ -0,0 +1,31 @@ +package com.baeldung.scribejava.service; + +import com.github.scribejava.apis.GoogleApi20; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +@Component +public class GoogleService { + + private OAuth20Service service; + private final String API_KEY = "api_key"; + private final String API_SECRET = "api_secret"; + private final String SCOPE = "https://www.googleapis.com/auth/userinfo.email"; + private final String CALLBACK = "http://localhost:8080/auth/google"; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .scope(SCOPE) + .callback(CALLBACK) + .build(GoogleApi20.instance()); + } + + + public OAuth20Service getService() { + return service; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java new file mode 100644 index 0000000000..739c82172c --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java @@ -0,0 +1,29 @@ +package com.baeldung.scribejava.service; + +import com.baeldung.scribejava.api.MyApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth20Service; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class MyService { + + private OAuth20Service service; + private final String API_KEY = "baeldung_api_key"; + private final String API_SECRET = "baeldung_api_secret"; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .scope("read write") + .build(MyApi.instance()); + } + + + public OAuth20Service getService() { + return service; + } +} diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java new file mode 100644 index 0000000000..df49f74679 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java @@ -0,0 +1,29 @@ +package com.baeldung.scribejava.service; + +import com.github.scribejava.apis.TwitterApi; +import com.github.scribejava.core.builder.ServiceBuilder; +import com.github.scribejava.core.oauth.OAuth10aService; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class TwitterService { + + private final String API_KEY = "api_key"; + private final String API_SECRET = "api_secret"; + private OAuth10aService service; + + @PostConstruct + private void init(){ + this.service = new ServiceBuilder(API_KEY) + .apiSecret(API_SECRET) + .build(TwitterApi.instance()); + } + + public OAuth10aService getService(){ + return service; + } + + +} diff --git a/libraries-security/src/main/resources/application.properties b/libraries-security/src/main/resources/application.properties new file mode 100644 index 0000000000..71c6176533 --- /dev/null +++ b/libraries-security/src/main/resources/application.properties @@ -0,0 +1 @@ +security.oauth2.resource.filter-order = 3 \ No newline at end of file diff --git a/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java new file mode 100644 index 0000000000..6565a5b085 --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.scribejava; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class ScribejavaUnitTest { + + @Test + public void contextLoad(){ + + } + +} diff --git a/libraries/pom.xml b/libraries/pom.xml index 1a88acfb7b..91c54b6113 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -154,45 +154,7 @@ commons-dbutils ${commons.dbutils.version} - - org.apache.flink - flink-connector-kafka-0.11_2.11 - ${flink.version} - - - org.apache.flink - flink-streaming-java_2.11 - ${flink.version} - - - org.apache.flink - flink-core - ${flink.version} - - - commons-logging - commons-logging - - - - - org.apache.flink - flink-java - ${flink.version} - - - commons-logging - commons-logging - - - - - org.apache.flink - flink-test-utils_2.11 - ${flink.version} - test - org.apache.commons commons-math3 @@ -239,11 +201,7 @@ jackson-databind ${jackson.version} - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${jackson.version} - + org.datanucleus @@ -900,7 +858,6 @@ 4.5.3 2.5 - 1.5.0 2.8.5 2.92 1.9.26 @@ -933,7 +890,7 @@ 2.5.5 1.23.0 v4-rev493-1.21.0 - 1.0.0 + 2.0.0 1.7.0 3.0.14 2.2.0 diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java new file mode 100644 index 0000000000..7d4316e3ec --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java @@ -0,0 +1,8 @@ +package com.baeldung.commons.lang3.application; + +public class Application { + + public static void main(String[] args) { + + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java new file mode 100644 index 0000000000..68aab46c33 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java @@ -0,0 +1,25 @@ +package com.baeldung.commons.lang3.beans; + +public class User { + + private final String name; + private final String email; + + public User(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + @Override + public String toString() { + return "User{" + "name=" + name + ", email=" + email + '}'; + } +} diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java new file mode 100644 index 0000000000..ae5d80244c --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java @@ -0,0 +1,11 @@ +package com.baeldung.commons.lang3.beans; + +import org.apache.commons.lang3.concurrent.LazyInitializer; + +public class UserInitializer extends LazyInitializer { + + @Override + protected User initialize() { + return new User("John", "john@domain.com"); + } +} diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java new file mode 100644 index 0000000000..15488bbaf4 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java @@ -0,0 +1,56 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.KafkaException; + +import java.util.Properties; +import java.util.stream.Stream; + +import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.TRANSACTIONAL_ID_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG; + +public class TransactionalMessageProducer { + + private static final String DATA_MESSAGE_1 = "Put any space separated data here for count"; + private static final String DATA_MESSAGE_2 = "Output will contain count of every word in the message"; + + public static void main(String[] args) { + + KafkaProducer producer = createKafkaProducer(); + + producer.initTransactions(); + + try{ + + producer.beginTransaction(); + + Stream.of(DATA_MESSAGE_1, DATA_MESSAGE_2).forEach(s -> producer.send( + new ProducerRecord("input", null, s))); + + producer.commitTransaction(); + + }catch (KafkaException e){ + + producer.abortTransaction(); + + } + + } + + private static KafkaProducer createKafkaProducer() { + + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ENABLE_IDEMPOTENCE_CONFIG, "true"); + props.put(TRANSACTIONAL_ID_CONFIG, "prod-0"); + props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + + return new KafkaProducer(props); + + } +} diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java new file mode 100644 index 0000000000..0563ba6684 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java @@ -0,0 +1,105 @@ +package com.baeldung.kafka; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.consumer.OffsetAndMetadata; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.KafkaException; +import org.apache.kafka.common.TopicPartition; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.time.Duration.ofSeconds; +import static java.util.Collections.singleton; +import static org.apache.kafka.clients.consumer.ConsumerConfig.*; +import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG; +import static org.apache.kafka.clients.producer.ProducerConfig.*; + +public class TransactionalWordCount { + + private static final String CONSUMER_GROUP_ID = "my-group-id"; + private static final String OUTPUT_TOPIC = "output"; + private static final String INPUT_TOPIC = "input"; + + public static void main(String[] args) { + + KafkaConsumer consumer = createKafkaConsumer(); + KafkaProducer producer = createKafkaProducer(); + + producer.initTransactions(); + + try { + + while (true) { + + ConsumerRecords records = consumer.poll(ofSeconds(60)); + + Map wordCountMap = records.records(new TopicPartition(INPUT_TOPIC, 0)) + .stream() + .flatMap(record -> Stream.of(record.value().split(" "))) + .map(word -> Tuple.of(word, 1)) + .collect(Collectors.toMap(tuple -> tuple.getKey(), t1 -> t1.getValue(), (v1, v2) -> v1 + v2)); + + producer.beginTransaction(); + + wordCountMap.forEach((key, value) -> producer.send(new ProducerRecord(OUTPUT_TOPIC, key, value.toString()))); + + Map offsetsToCommit = new HashMap<>(); + + for (TopicPartition partition : records.partitions()) { + List> partitionedRecords = records.records(partition); + long offset = partitionedRecords.get(partitionedRecords.size() - 1).offset(); + + offsetsToCommit.put(partition, new OffsetAndMetadata(offset + 1)); + } + + producer.sendOffsetsToTransaction(offsetsToCommit, CONSUMER_GROUP_ID); + producer.commitTransaction(); + + } + + } catch (KafkaException e) { + + producer.abortTransaction(); + + } + + + } + + private static KafkaConsumer createKafkaConsumer() { + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(GROUP_ID_CONFIG, CONSUMER_GROUP_ID); + props.put(ENABLE_AUTO_COMMIT_CONFIG, "false"); + props.put(ISOLATION_LEVEL_CONFIG, "read_committed"); + props.put(KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + props.put(VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); + + KafkaConsumer consumer = new KafkaConsumer<>(props); + consumer.subscribe(singleton(INPUT_TOPIC)); + return consumer; + } + + private static KafkaProducer createKafkaProducer() { + + Properties props = new Properties(); + props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); + props.put(ENABLE_IDEMPOTENCE_CONFIG, "true"); + props.put(TRANSACTIONAL_ID_CONFIG, "prod-1"); + props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); + + return new KafkaProducer(props); + + } + +} diff --git a/libraries/src/main/java/com/baeldung/kafka/Tuple.java b/libraries/src/main/java/com/baeldung/kafka/Tuple.java new file mode 100644 index 0000000000..883de4ba21 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/kafka/Tuple.java @@ -0,0 +1,24 @@ +package com.baeldung.kafka; + +public class Tuple { + + private String key; + private Integer value; + + private Tuple(String key, Integer value) { + this.key = key; + this.value = value; + } + + public static Tuple of(String key, Integer value){ + return new Tuple(key,value); + } + + public String getKey() { + return key; + } + + public Integer getValue() { + return value; + } +} diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java index 76d044ca60..086f32677e 100644 --- a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java +++ b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java @@ -18,16 +18,19 @@ import java.util.List; public class BeanExamples { public static List beanBuilderExample(Path path, Class clazz) { + ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy(); + return beanBuilderExample(path, clazz, ms); + } + + public static List beanBuilderExample(Path path, Class clazz, MappingStrategy ms) { CsvTransfer csvTransfer = new CsvTransfer(); try { - ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy(); ms.setType(clazz); Reader reader = Files.newBufferedReader(path); - CsvToBean cb = new CsvToBeanBuilder(reader) - .withType(clazz) - .withMappingStrategy(ms) - .build(); + CsvToBean cb = new CsvToBeanBuilder(reader).withType(clazz) + .withMappingStrategy(ms) + .build(); csvTransfer.setCsvList(cb.parse()); reader.close(); @@ -40,11 +43,10 @@ public class BeanExamples { public static String writeCsvFromBean(Path path) { try { - Writer writer = new FileWriter(path.toString()); + Writer writer = new FileWriter(path.toString()); - StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer) - .withSeparator(CSVWriter.DEFAULT_SEPARATOR) - .build(); + StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer).withSeparator(CSVWriter.DEFAULT_SEPARATOR) + .build(); List list = new ArrayList<>(); list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd")); diff --git a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java index e46d8654a2..64e13a277e 100644 --- a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java +++ b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java @@ -42,4 +42,13 @@ public class BidiMapUnitTest { map.put("key1", "value1"); assertEquals(map.getKey("value1"), "key1"); } + + @Test + public void givenKeyValue_whenAddValue_thenReplaceFirstKey() { + BidiMap map = new DualHashBidiMap<>(); + map.put("key1", "value1"); + map.put("key2", "value1"); + assertEquals(map.size(), 1); + assertFalse(map.containsKey("key1")); + } } diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java new file mode 100644 index 0000000000..5eba736b4a --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java @@ -0,0 +1,84 @@ +package com.baeldung.commons.lang3.test; + +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.ArrayUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class ArrayUtilsUnitTest { + + @Test + public void givenArrayUtilsClass_whenCalledtoString_thenCorrect() { + String[] array = {"a", "b", "c"}; + assertThat(ArrayUtils.toString(array)).isEqualTo("{a,b,c}"); + } + + @Test + public void givenArrayUtilsClass_whenCalledtoStringIfArrayisNull_thenCorrect() { + String[] array = null; + assertThat(ArrayUtils.toString(array, "Array is null")).isEqualTo("Array is null"); + } + + @Test + public void givenArrayUtilsClass_whenCalledhashCode_thenCorrect() { + String[] array = {"a", "b", "c"}; + assertThat(ArrayUtils.hashCode(array)).isEqualTo(997619); + } + + @Test + public void givenArrayUtilsClass_whenCalledtoMap_thenCorrect() { + String[][] array = {{"1", "one", }, {"2", "two", }, {"3", "three"}}; + Map map = new HashMap(); + map.put("1", "one"); + map.put("2", "two"); + map.put("3", "three"); + assertThat(ArrayUtils.toMap(array)).isEqualTo(map); + } + + @Test + public void givenArrayUtilsClass_whenCallednullToEmptyStringArray_thenCorrect() { + String[] array = null; + assertThat(ArrayUtils.nullToEmpty(array)).isEmpty(); + } + + @Test + public void givenArrayUtilsClass_whenCallednullToEmptyObjectArray_thenCorrect() { + Object[] array = null; + assertThat(ArrayUtils.nullToEmpty(array)).isEmpty(); + } + + @Test + public void givenArrayUtilsClass_whenCalledsubarray_thenCorrect() { + int[] array = {1, 2, 3}; + int[] expected = {1}; + assertThat(ArrayUtils.subarray(array, 0, 1)).isEqualTo(expected); + } + + @Test + public void givenArrayUtilsClass_whenCalledisSameLength_thenCorrect() { + int[] array1 = {1, 2, 3}; + int[] array2 = {1, 2, 3}; + assertThat(ArrayUtils.isSameLength(array1, array2)).isTrue(); + } + + @Test + public void givenArrayUtilsClass_whenCalledreverse_thenCorrect() { + int[] array1 = {1, 2, 3}; + int[] array2 = {3, 2, 1}; + ArrayUtils.reverse(array1); + assertThat(array1).isEqualTo(array2); + } + + @Test + public void givenArrayUtilsClass_whenCalledIndexOf_thenCorrect() { + int[] array = {1, 2, 3}; + assertThat(ArrayUtils.indexOf(array, 1, 0)).isEqualTo(0); + } + + @Test + public void givenArrayUtilsClass_whenCalledcontains_thenCorrect() { + int[] array = {1, 2, 3}; + assertThat(ArrayUtils.contains(array, 1)).isTrue(); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java new file mode 100644 index 0000000000..f32980269a --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class BasicThreadFactoryUnitTest { + + @Test + public void givenBasicThreadFactoryInstance_whenCalledBuilder_thenCorrect() { + BasicThreadFactory factory = new BasicThreadFactory.Builder() + .namingPattern("workerthread-%d") + .daemon(true) + .priority(Thread.MAX_PRIORITY) + .build(); + assertThat(factory).isInstanceOf(BasicThreadFactory.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java new file mode 100644 index 0000000000..f55f239d75 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import org.apache.commons.lang3.reflect.ConstructorUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class ConstructorUtilsUnitTest { + + @Test + public void givenConstructorUtilsClass_whenCalledgetAccessibleConstructor_thenCorrect() { + assertThat(ConstructorUtils.getAccessibleConstructor(User.class, String.class, String.class)).isInstanceOf(Constructor.class); + } + + @Test + public void givenConstructorUtilsClass_whenCalledinvokeConstructor_thenCorrect() throws Exception { + assertThat(ConstructorUtils.invokeConstructor(User.class, "name", "email")).isInstanceOf(User.class); + } + + @Test + public void givenConstructorUtilsClass_whenCalledinvokeExactConstructor_thenCorrect() throws Exception { + String[] args = {"name", "email"}; + Class[] parameterTypes= {String.class, String.class}; + assertThat(ConstructorUtils.invokeExactConstructor(User.class, args, parameterTypes)).isInstanceOf(User.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java new file mode 100644 index 0000000000..8abb373e30 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import org.apache.commons.lang3.reflect.FieldUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class FieldUtilsUnitTest { + + private static User user; + + @BeforeClass + public static void setUpUserInstance() { + user = new User("Julie", "julie@domain.com"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetField_thenCorrect() { + assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetFieldForceAccess_thenCorrect() { + assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetDeclaredFieldForceAccess_thenCorrect() { + assertThat(FieldUtils.getDeclaredField(User.class, "name", true).getName()).isEqualTo("name"); + } + + @Test + public void givenFieldUtilsClass_whenCalledgetAllField_thenCorrect() { + assertThat(FieldUtils.getAllFields(User.class).length).isEqualTo(2); + } + + @Test + public void givenFieldUtilsClass_whenCalledreadField_thenCorrect() throws IllegalAccessException { + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + } + + @Test + public void givenFieldUtilsClass_whenCalledreadDeclaredField_thenCorrect() throws IllegalAccessException { + assertThat(FieldUtils.readDeclaredField(user, "name", true)).isEqualTo("Julie"); + } + + @Test + public void givenFieldUtilsClass_whenCalledwriteField_thenCorrect() throws IllegalAccessException { + FieldUtils.writeField(user, "name", "Julie", true); + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + + } + + @Test + public void givenFieldUtilsClass_whenCalledwriteDeclaredField_thenCorrect() throws IllegalAccessException { + FieldUtils.writeDeclaredField(user, "name", "Julie", true); + assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java new file mode 100644 index 0000000000..1a5094a16d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.math.Fraction; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class FractionUnitTest { + + @Test + public void givenFractionClass_whenCalledgetFraction_thenCorrect() { + assertThat(Fraction.getFraction(5, 6)).isInstanceOf(Fraction.class); + } + + @Test + public void givenTwoFractionInstances_whenCalledadd_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(1, 4); + Fraction fraction2 = Fraction.getFraction(3, 4); + assertThat(fraction1.add(fraction2).toString()).isEqualTo("1/1"); + } + + @Test + public void givenTwoFractionInstances_whenCalledsubstract_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(3, 4); + Fraction fraction2 = Fraction.getFraction(1, 4); + assertThat(fraction1.subtract(fraction2).toString()).isEqualTo("1/2"); + } + + @Test + public void givenTwoFractionInstances_whenCalledmultiply_thenCorrect() { + Fraction fraction1 = Fraction.getFraction(3, 4); + Fraction fraction2 = Fraction.getFraction(1, 4); + assertThat(fraction1.multiplyBy(fraction2).toString()).isEqualTo("3/16"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java new file mode 100644 index 0000000000..bbd24c8207 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java @@ -0,0 +1,17 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.builder.HashCodeBuilder; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class HashCodeBuilderUnitTest { + + @Test + public void givenHashCodeBuilderInstance_whenCalledtoHashCode_thenCorrect() { + int hashcode = new HashCodeBuilder(17, 37) + .append("John") + .append("john@domain.com") + .toHashCode(); + assertThat(hashcode).isEqualTo(1269178828); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java new file mode 100644 index 0000000000..28ed8d2514 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ImmutablePairUnitTest { + + private static ImmutablePair immutablePair; + + @BeforeClass + public static void setUpImmutablePairInstance() { + immutablePair = new ImmutablePair<>("leftElement", "rightElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledgetLeft_thenCorrect() { + assertThat(immutablePair.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledgetRight_thenCorrect() { + assertThat(immutablePair.getRight()).isEqualTo("rightElement"); + } + + @Test + public void givenImmutablePairInstance_whenCalledof_thenCorrect() { + assertThat(ImmutablePair.of("leftElement", "rightElement")).isInstanceOf(ImmutablePair.class); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenImmutablePairInstance_whenCalledSetValue_thenThrowUnsupportedOperationException() { + immutablePair.setValue("newValue"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java new file mode 100644 index 0000000000..a9dd3fa7c0 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.ImmutableTriple; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class ImmutableTripleUnitTest { + + private static ImmutableTriple immutableTriple; + + @BeforeClass + public static void setUpImmutableTripleInstance() { + immutableTriple = new ImmutableTriple<>("leftElement", "middleElement", "rightElement"); + } + + @Test + public void givenImmutableTripleInstance_whenCalledgetLeft_thenCorrect() { + assertThat(immutableTriple.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenImmutableTripleInstance_whenCalledgetMiddle_thenCorrect() { + assertThat(immutableTriple.getMiddle()).isEqualTo("middleElement"); + } + + @Test + public void givenImmutableInstance_whenCalledgetRight_thenCorrect() { + assertThat(immutableTriple.getRight()).isEqualTo("rightElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java new file mode 100644 index 0000000000..a08399f8de --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import com.baeldung.commons.lang3.beans.UserInitializer; +import org.apache.commons.lang3.concurrent.ConcurrentException; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class LazyInitializerUnitTest { + + @Test + public void givenLazyInitializerInstance_whenCalledget_thenCorrect() throws ConcurrentException { + UserInitializer userInitializer = new UserInitializer(); + assertThat(userInitializer.get()).isInstanceOf(User.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java new file mode 100644 index 0000000000..5e1d15f2f8 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java @@ -0,0 +1,15 @@ +package com.baeldung.commons.lang3.test; + +import com.baeldung.commons.lang3.beans.User; +import java.lang.reflect.Method; +import org.apache.commons.lang3.reflect.MethodUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class MethodUtilsUnitTest { + + @Test + public void givenMethodUtilsClass_whenCalledgetAccessibleMethod_thenCorrect() { + assertThat(MethodUtils.getAccessibleMethod(User.class, "getName")).isInstanceOf(Method.class); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java new file mode 100644 index 0000000000..02041f51e8 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.mutable.MutableObject; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MutableObjectUnitTest { + + private static MutableObject mutableObject; + + @BeforeClass + public static void setUpMutableObject() { + mutableObject = new MutableObject("Initial value"); + } + + @Test + public void givenMutableObject_whenCalledgetValue_thenCorrect() { + assertThat(mutableObject.getValue()).isInstanceOf(String.class); + } + + @Test + public void givenMutableObject_whenCalledsetValue_thenCorrect() { + mutableObject.setValue("Another value"); + assertThat(mutableObject.getValue()).isEqualTo("Another value"); + } + + @Test + public void givenMutableObject_whenCalledtoString_thenCorrect() { + assertThat(mutableObject.toString()).isEqualTo("Another value"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java new file mode 100644 index 0000000000..174ec70c4d --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.MutablePair; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MutablePairUnitTest { + + private static MutablePair mutablePair; + + @BeforeClass + public static void setUpMutablePairInstance() { + mutablePair = new MutablePair<>("leftElement", "rightElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledgetLeft_thenCorrect() { + assertThat(mutablePair.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledgetRight_thenCorrect() { + assertThat(mutablePair.getRight()).isEqualTo("rightElement"); + } + + @Test + public void givenMutablePairInstance_whenCalledsetLeft_thenCorrect() { + mutablePair.setLeft("newLeftElement"); + assertThat(mutablePair.getLeft()).isEqualTo("newLeftElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java new file mode 100644 index 0000000000..bdf254a102 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.math.NumberUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class NumberUtilsUnitTest { + + @Test + public void givenNumberUtilsClass_whenCalledcompareWithIntegers_thenCorrect() { + assertThat(NumberUtils.compare(1, 1)).isEqualTo(0); + } + + @Test + public void givenNumberUtilsClass_whenCalledcompareWithLongs_thenCorrect() { + assertThat(NumberUtils.compare(1L, 1L)).isEqualTo(0); + } + + @Test + public void givenNumberUtilsClass_whenCalledcreateNumber_thenCorrect() { + assertThat(NumberUtils.createNumber("123456")).isEqualTo(123456); + } + + @Test + public void givenNumberUtilsClass_whenCalledisDigits_thenCorrect() { + assertThat(NumberUtils.isDigits("123456")).isTrue(); + } + + @Test + public void givenNumberUtilsClass_whenCallemaxwithIntegerArray_thenCorrect() { + int[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.max(array)).isEqualTo(6); + } + + @Test + public void givenNumberUtilsClass_whenCalleminwithIntegerArray_thenCorrect() { + int[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.min(array)).isEqualTo(1); + } + + @Test + public void givenNumberUtilsClass_whenCalleminwithByteArray_thenCorrect() { + byte[] array = {1, 2, 3, 4, 5, 6}; + assertThat(NumberUtils.min(array)).isEqualTo((byte) 1); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java new file mode 100644 index 0000000000..ab39ba7bd9 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java @@ -0,0 +1,73 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.StringUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class StringUtilsUnitTest { + + @Test + public void givenStringUtilsClass_whenCalledisBlank_thenCorrect() { + assertThat(StringUtils.isBlank(" ")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisEmpty_thenCorrect() { + assertThat(StringUtils.isEmpty("")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAllLowerCase_thenCorrect() { + assertThat(StringUtils.isAllLowerCase("abd")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAllUpperCase_thenCorrect() { + assertThat(StringUtils.isAllUpperCase("ABC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisMixedCase_thenCorrect() { + assertThat(StringUtils.isMixedCase("abC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAlpha_thenCorrect() { + assertThat(StringUtils.isAlpha("abc")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledisAlphanumeric_thenCorrect() { + assertThat(StringUtils.isAlphanumeric("abc123")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontains_thenCorrect() { + assertThat(StringUtils.contains("abc", "ab")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontainsAny_thenCorrect() { + assertThat(StringUtils.containsAny("abc", 'a', 'b', 'c')).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledcontainsIgnoreCase_thenCorrect() { + assertThat(StringUtils.containsIgnoreCase("abc", "ABC")).isTrue(); + } + + @Test + public void givenStringUtilsClass_whenCalledswapCase_thenCorrect() { + assertThat(StringUtils.swapCase("abc")).isEqualTo("ABC"); + } + + @Test + public void givenStringUtilsClass_whenCalledreverse_thenCorrect() { + assertThat(StringUtils.reverse("abc")).isEqualTo("cba"); + } + + @Test + public void givenStringUtilsClass_whenCalleddifference_thenCorrect() { + assertThat(StringUtils.difference("abc", "abd")).isEqualTo("d"); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java new file mode 100644 index 0000000000..0efe97f912 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.commons.lang3.test; + +import java.io.File; +import org.apache.commons.lang3.JavaVersion; +import org.apache.commons.lang3.SystemUtils; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.Test; + +public class SystemsUtilsUnitTest { + + @Test + public void givenSystemUtilsClass_whenCalledgetJavaHome_thenCorrect() { + assertThat(SystemUtils.getJavaHome()).isEqualTo(new File("/usr/lib/jvm/java-8-oracle/jre")); + } + + @Test + public void givenSystemUtilsClass_whenCalledgetUserHome_thenCorrect() { + assertThat(SystemUtils.getUserHome()).isEqualTo(new File("/home/travis")); + } + + @Test + public void givenSystemUtilsClass_whenCalledisJavaVersionAtLeast_thenCorrect() { + assertThat(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_RECENT)).isTrue(); + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java new file mode 100644 index 0000000000..7d506bbbab --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.commons.lang3.test; + +import org.apache.commons.lang3.tuple.Triple; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TripleUnitTest { + + private static Triple triple; + + @BeforeClass + public static void setUpTripleInstance() { + triple = Triple.of("leftElement", "middleElement", "rightElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetLeft_thenCorrect() { + assertThat(triple.getLeft()).isEqualTo("leftElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetMiddle_thenCorrect() { + assertThat(triple.getMiddle()).isEqualTo("middleElement"); + } + + @Test + public void givenTripleInstance_whenCalledgetRight_thenCorrect() { + assertThat(triple.getRight()).isEqualTo("rightElement"); + } +} diff --git a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java index 4406494d30..e61f4158a7 100644 --- a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java +++ b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java @@ -4,10 +4,12 @@ import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.common.serialization.Serde; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.KafkaStreams; +import org.apache.kafka.streams.StreamsBuilder; import org.apache.kafka.streams.StreamsConfig; +import org.apache.kafka.streams.Topology; import org.apache.kafka.streams.kstream.KStream; -import org.apache.kafka.streams.kstream.KStreamBuilder; import org.apache.kafka.streams.kstream.KTable; +import org.apache.kafka.streams.kstream.Produced; import org.apache.kafka.test.TestUtils; import org.junit.Ignore; import org.junit.Test; @@ -36,20 +38,20 @@ public class KafkaStreamsLiveTest { streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath()); // when - KStreamBuilder builder = new KStreamBuilder(); + StreamsBuilder builder = new StreamsBuilder(); KStream textLines = builder.stream(inputTopic); Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS); KTable wordCounts = textLines.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase()))).groupBy((key, word) -> word).count(); - wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); + textLines.foreach((word, count) -> System.out.println("word: " + word + " -> " + count)); String outputTopic = "outputTopic"; final Serde stringSerde = Serdes.String(); - final Serde longSerde = Serdes.Long(); - wordCounts.to(stringSerde, longSerde, outputTopic); + final Serde longSerde = Serdes.String(); + textLines.to(outputTopic, Produced.with(stringSerde,longSerde)); - KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration); + KafkaStreams streams = new KafkaStreams(new Topology(), streamsConfiguration); streams.start(); // then diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java new file mode 100644 index 0000000000..2191396e5d --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 4. Using @Getter on a Boolean Field + * + */ +public class GetterBoolean { + + @Getter + private Boolean running = true; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java new file mode 100644 index 0000000000..5601f85b8b --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java @@ -0,0 +1,16 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 3. Using @Getter on a boolean Field + * + */ +public class GetterBooleanPrimitive { + + @Getter + private boolean running; + +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java new file mode 100644 index 0000000000..af29a33c20 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 3.2. Two boolean Fields With the Same Accessor Name + * + */ +public class GetterBooleanPrimitiveSameAccessor { + + @Getter + boolean running = true; + + @Getter + boolean isRunning = false; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java new file mode 100644 index 0000000000..d972273b71 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java @@ -0,0 +1,13 @@ +package com.baeldung.lombok.getter; + +import lombok.Getter; + +/** + * Related Article Sections: + * 3.1. A boolean Field Having the Same Name With Its Accessor + * + */ +public class GetterBooleanSameAccessor { + @Getter + private boolean isRunning = true; +} diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java new file mode 100644 index 0000000000..0d3b9a928a --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java @@ -0,0 +1,15 @@ +package com.baeldung.lombok.getter; + + +import lombok.Getter; + +/** + * Related Article Sections: + * 4. Using @Getter on a Boolean Field + * + */ +public class GetterBooleanType { + + @Getter + private Boolean running = true; +} diff --git a/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java new file mode 100644 index 0000000000..632594d575 --- /dev/null +++ b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.lombok.getter; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GetterBooleanUnitTest { + + @Test + public void whenBasicBooleanField_thenMethodNamePrefixedWithIsFollowedByFieldName() { + GetterBooleanPrimitive lombokExamples = new GetterBooleanPrimitive(); + assertFalse(lombokExamples.isRunning()); + } + + @Test + public void whenBooleanFieldPrefixedWithIs_thenMethodNameIsSameAsFieldName() { + GetterBooleanSameAccessor lombokExamples = new GetterBooleanSameAccessor(); + assertTrue(lombokExamples.isRunning()); + } + + @Test + public void whenTwoBooleanFieldsCauseNamingConflict_thenLombokMapsToFirstDeclaredField() { + GetterBooleanPrimitiveSameAccessor lombokExamples = new GetterBooleanPrimitiveSameAccessor(); + assertTrue(lombokExamples.isRunning() == lombokExamples.running); + assertFalse(lombokExamples.isRunning() == lombokExamples.isRunning); + } + + @Test + public void whenFieldOfBooleanType_thenLombokPrefixesMethodWithGetInsteadOfIs() { + GetterBooleanType lombokExamples = new GetterBooleanType(); + assertTrue(lombokExamples.getRunning()); + } +} diff --git a/metrics/pom.xml b/metrics/pom.xml index 86f197240b..9cf1ec588f 100644 --- a/metrics/pom.xml +++ b/metrics/pom.xml @@ -84,6 +84,13 @@ spectator-api ${spectator-api.version} + + + org.assertj + assertj-core + test + + diff --git a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java index e7f3d7ec72..689e23ad6d 100644 --- a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java @@ -1,8 +1,12 @@ package com.baeldung.metrics.micrometer; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.within; +import static org.assertj.core.api.Assertions.withinPercentage; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.collection.IsMapContaining.hasEntry; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import io.micrometer.atlas.AtlasMeterRegistry; @@ -31,8 +35,10 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import org.assertj.core.data.Percentage; import org.junit.Before; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import com.netflix.spectator.atlas.AtlasConfig; @@ -156,7 +162,8 @@ public class MicrometerAtlasIntegrationTest { timer.record(30, TimeUnit.MILLISECONDS); assertTrue(2 == timer.count()); - assertTrue(50 > timer.totalTime(TimeUnit.MILLISECONDS) && 45 <= timer.totalTime(TimeUnit.MILLISECONDS)); + + assertThat(timer.totalTime(TimeUnit.MILLISECONDS)).isBetween(40.0, 55.0); } @Test @@ -173,7 +180,7 @@ public class MicrometerAtlasIntegrationTest { } long timeElapsed = longTaskTimer.stop(currentTaskId); - assertTrue(timeElapsed / (int) 1e6 == 2); + assertEquals(2L, timeElapsed/((int) 1e6),1L); } @Test diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java index 134c3c91cf..b8a5b93e49 100644 --- a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java @@ -27,6 +27,9 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; +/** + * Atlas server needs to be up and running for this live test to work. + */ public class AtlasObserverLiveTest { private final String atlasUri = "http://localhost:7101/api/v1"; diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java index d810de155a..92bbd615b9 100644 --- a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java +++ b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java @@ -109,20 +109,20 @@ public class MetricTypeManualTest { .build(), MILLISECONDS); Stopwatch stopwatch = timer.start(); - MILLISECONDS.sleep(1); - timer.record(2, MILLISECONDS); + SECONDS.sleep(1); + timer.record(2, SECONDS); stopwatch.stop(); - assertEquals("timer should count 1 millisecond", 1, timer + assertEquals("timer should count 1 second", 1000, timer .getValue() - .intValue()); - assertEquals("timer should count 3 millisecond in total", 3, timer.getTotalTime() - .intValue()); + .intValue(),1000); + assertEquals("timer should count 3 second in total", 3000, timer.getTotalTime() + .intValue(),1000); assertEquals("timer should record 2 updates", 2, timer .getCount() .intValue()); - assertEquals("timer should have max 2", 2, timer.getMax(), 0.01); + assertEquals("timer should have max 2", 2000, timer.getMax(), 0.01); } @Test @@ -161,7 +161,6 @@ public class MetricTypeManualTest { } @Test - //== public void givenStatsTimer_whenExecuteTask_thenStatsCalculated() throws Exception { System.setProperty("netflix.servo", "1000"); StatsTimer timer = new StatsTimer(MonitorConfig @@ -178,21 +177,21 @@ public class MetricTypeManualTest { .build(), MILLISECONDS); Stopwatch stopwatch = timer.start(); - MILLISECONDS.sleep(1); - timer.record(3, MILLISECONDS); + SECONDS.sleep(1); + timer.record(3, SECONDS); stopwatch.stop(); stopwatch = timer.start(); - timer.record(6, MILLISECONDS); - MILLISECONDS.sleep(2); + timer.record(6, SECONDS); + SECONDS.sleep(2); stopwatch.stop(); - assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalTime()); - assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalMeasurement()); + assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalTime(),500); + assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalMeasurement(),500); assertEquals("timer should record 4 updates", 4, timer.getCount()); - assertEquals("stats timer value time-cost/update should be 2", 3, timer + assertEquals("stats timer value time-cost/update should be 2", 3000, timer .getValue() - .intValue()); + .intValue(),500); final Map metricMap = timer .getMonitors() @@ -235,4 +234,4 @@ public class MetricTypeManualTest { assertEquals("information collected", informational.getValue()); } -} +} \ No newline at end of file diff --git a/optaplanner/README.md b/optaplanner/README.md new file mode 100644 index 0000000000..d793be1f2a --- /dev/null +++ b/optaplanner/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [Guide to OptaPlanner](https://www.baeldung.com/opta-planner) diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java index 78c4116c67..ec0d4bca3c 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java @@ -78,9 +78,9 @@ public class PersistenceJPAConfig { final Properties hibernateProperties = new Properties(); hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); - hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); - // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); + hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false"); + + return hibernateProperties; } diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java index 1c8ce5400f..cf6e69eb39 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java @@ -5,7 +5,7 @@ import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatche public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class[] getRootConfigClasses() { - return new Class[] { PersistenceJNDIConfig.class }; + return new Class[] { PersistenceJPAConfig.class }; } @Override diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java similarity index 71% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java index af30ae461e..114cf48c7c 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.criteria.repository; +package org.baeldung.persistence.dao; -import org.baeldung.persistence.criteria.model.Book; +import org.baeldung.persistence.model.Book; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java similarity index 58% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java index 35330cfa3c..b939907572 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java @@ -1,8 +1,8 @@ -package org.baeldung.persistence.criteria.repository; +package org.baeldung.persistence.dao; import java.util.List; -import org.baeldung.persistence.criteria.model.Book; +import org.baeldung.persistence.model.Book; public interface BookRepositoryCustom { diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java similarity index 87% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java index f782d69e1e..6e9aa998d7 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.criteria.dao; +package org.baeldung.persistence.dao; import java.util.ArrayList; import java.util.List; @@ -10,8 +10,7 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import org.baeldung.persistence.criteria.model.Book; -import org.baeldung.persistence.criteria.repository.BookRepositoryCustom; +import org.baeldung.persistence.model.Book; import org.springframework.stereotype.Repository; @Repository diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java similarity index 63% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java index 7b1aff857e..88b769e9bf 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java @@ -1,12 +1,12 @@ -package org.baeldung.persistence.criteria.repository; +package org.baeldung.persistence.dao; -import static org.baeldung.persistence.criteria.repository.BookSpecifications.hasAuthor; -import static org.baeldung.persistence.criteria.repository.BookSpecifications.titleContains; +import static org.baeldung.persistence.dao.BookSpecifications.hasAuthor; +import static org.baeldung.persistence.dao.BookSpecifications.titleContains; import static org.springframework.data.jpa.domain.Specifications.where; import java.util.List; -import org.baeldung.persistence.criteria.model.Book; +import org.baeldung.persistence.model.Book; import org.springframework.stereotype.Service; @Service diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java similarity index 78% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java index 392b750977..ed9540060d 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.criteria.repository; +package org.baeldung.persistence.dao; -import org.baeldung.persistence.criteria.model.Book; +import org.baeldung.persistence.model.Book; import org.springframework.data.jpa.domain.Specification; public class BookSpecifications { diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java similarity index 91% rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java index beb6c0190c..754bd179d1 100644 --- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java +++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.criteria.model; +package org.baeldung.persistence.model; import javax.persistence.Entity; import javax.persistence.Id; diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence.xml b/persistence-modules/spring-jpa/src/main/resources/persistence.xml index 65bad29cdc..6304fa0a65 100644 --- a/persistence-modules/spring-jpa/src/main/resources/persistence.xml +++ b/persistence-modules/spring-jpa/src/main/resources/persistence.xml @@ -21,8 +21,6 @@ ${hibernate.hbm2ddl.auto} ${hibernate.dialect} - ${hibernate.cache.use_second_level_cache} - ${hibernate.cache.use_query_cache} diff --git a/pom.xml b/pom.xml index 7a7e2d7f64..4ffd9ba4a4 100644 --- a/pom.xml +++ b/pom.xml @@ -405,9 +405,10 @@ json jsoup testing-modules/junit-5 - jws + libraries libraries-data + libraries-security libraries-server linkrest logging-modules/log-mdc @@ -470,7 +471,7 @@ spring-boot-persistence spring-boot-security spring-boot-mvc - spring-boot-vue + spring-boot-vue spring-boot-logging-log4j2 spring-cloud-data-flow spring-cloud @@ -604,6 +605,80 @@ jnosql spring-boot-angular-ecommerce jta + + java-websocket + activejdbc + + + apache-bval + apache-shiro + apache-spark + + checker-plugin + + + core-java-sun + custom-pmd + dagger + data-structures + dubbo + + + + + jni + jooby + + + + ratpack + + spring-boot-autoconfiguration + spring-boot-custom-starter + spring-boot-jasypt + + spring-data-rest-querydsl + + spring-mobile + + spring-mvc-simple + + spring-rest-hal-browser + spring-rest-shell + spring-rest-template + spring-roo + spring-security-stormpath + sse-jaxrs + + stripe + + Twitter4J + wicket + xstream + cas/cas-secured-app + cas/cas-server + + + + + + + + + + + + + jenkins/hello-world + + + + spring-boot-custom-starter/greeter + spring-boot-h2/spring-boot-h2-database + + + + @@ -847,7 +922,80 @@ - + + java-websocket + + + + apache-bval + apache-shiro + apache-spark + + checker-plugin + + + core-java-sun + custom-pmd + dagger + data-structures + dubbo + + + + + jni + jooby + + + + ratpack + + spring-boot-autoconfiguration + spring-boot-custom-starter + + + spring-data-rest-querydsl + + spring-mobile + + spring-mvc-simple + + spring-rest-hal-browser + spring-rest-shell + spring-rest-template + spring-roo + spring-security-stormpath + sse-jaxrs + + stripe + + + wicket + xstream + cas/cas-secured-app + + + + + + + + + + + + + + jenkins/hello-world + + + + spring-boot-custom-starter/greeter + spring-boot-h2/spring-boot-h2-database + + + + diff --git a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java index 56650ba306..e3060b8e02 100644 --- a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java +++ b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java @@ -37,14 +37,14 @@ public class ReactorIntegrationTest { Flux.just(1, 2, 3, 4) .log() .map(i -> i * 2) - .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (two, one) -> String.format("First Flux: %d, Second Flux: %d", one, two)) + .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (one, two) -> String.format("First Flux: %d, Second Flux: %d", one, two)) .subscribe(elements::add); assertThat(elements).containsExactly( - "First Flux: 0, Second Flux: 2", - "First Flux: 1, Second Flux: 4", - "First Flux: 2, Second Flux: 6", - "First Flux: 3, Second Flux: 8"); + "First Flux: 2, Second Flux: 0", + "First Flux: 4, Second Flux: 1", + "First Flux: 6, Second Flux: 2", + "First Flux: 8, Second Flux: 3"); } @Test diff --git a/spring-4/pom.xml b/spring-4/pom.xml index cf10f64aa2..78939bba95 100644 --- a/spring-4/pom.xml +++ b/spring-4/pom.xml @@ -71,10 +71,8 @@ - UTF-8 1.0.1 1.16.18 - 1.8 1.4.197 diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 9f60b8a364..293edb5bda 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -1,5 +1,6 @@ - 4.0.0 com.baeldung @@ -134,7 +135,26 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + methods + true + + **/*IntegrationTest.java + **/*IntTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + @@ -142,6 +162,8 @@ 1.5.6 4.1 ${project.build.directory}/generated-snippets + 2.21.0 + diff --git a/spring-all/pom.xml b/spring-all/pom.xml index c4c4cf7963..bab2e431ec 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -45,6 +45,15 @@ spring-shell ${org.springframework.shell.version} + + org.springframework + spring-websocket + + + org.springframework + spring-messaging + + org.springframework @@ -190,7 +199,24 @@ - + + + dev + + true + + + dev + + + + prod + + prod + + + + org.baeldung.sample.App diff --git a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java index eb5543e3db..2d1905ee9c 100644 --- a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java +++ b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java @@ -2,9 +2,11 @@ package org.baeldung.profiles; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; @Configuration @ComponentScan("org.baeldung.profiles") +@PropertySource(value = "classpath:application.properties") public class SpringProfilesConfig { } diff --git a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java index 73df386aff..9257a3aa3a 100644 --- a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java +++ b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java @@ -13,21 +13,36 @@ import org.springframework.web.bind.annotation.RequestMapping; public class ScopesController { public static final Logger LOG = LoggerFactory.getLogger(ScopesController.class); - @Resource(name = "requestMessage") - HelloMessageGenerator requestMessage; + @Resource(name = "requestScopedBean") + HelloMessageGenerator requestScopedBean; - @Resource(name = "sessionMessage") - HelloMessageGenerator sessionMessage; + @Resource(name = "sessionScopedBean") + HelloMessageGenerator sessionScopedBean; - @RequestMapping("/scopes") - public String getScopes(final Model model) { - LOG.info("Request Message:" + requestMessage.getMessage()); - LOG.info("Session Message" + sessionMessage.getMessage()); - requestMessage.setMessage("Good morning!"); - sessionMessage.setMessage("Good afternoon!"); - model.addAttribute("requestMessage", requestMessage.getMessage()); - model.addAttribute("sessionMessage", sessionMessage.getMessage()); + @Resource(name = "applicationScopedBean") + HelloMessageGenerator applicationScopedBean; + + @RequestMapping("/scopes/request") + public String getRequestScopeMessage(final Model model) { + model.addAttribute("previousMessage", requestScopedBean.getMessage()); + requestScopedBean.setMessage("Request Scope Message!"); + model.addAttribute("currentMessage", requestScopedBean.getMessage()); return "scopesExample"; } + @RequestMapping("/scopes/session") + public String getSessionScopeMessage(final Model model) { + model.addAttribute("previousMessage", sessionScopedBean.getMessage()); + sessionScopedBean.setMessage("Session Scope Message!"); + model.addAttribute("currentMessage", sessionScopedBean.getMessage()); + return "scopesExample"; + } + + @RequestMapping("/scopes/application") + public String getApplicationScopeMessage(final Model model) { + model.addAttribute("previousMessage", applicationScopedBean.getMessage()); + applicationScopedBean.setMessage("Application Scope Message!"); + model.addAttribute("currentMessage", applicationScopedBean.getMessage()); + return "scopesExample"; + } } diff --git a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java index fb34725508..b5fe494ee2 100644 --- a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java +++ b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java @@ -27,19 +27,25 @@ public class ScopesConfig { @Bean @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator requestMessage() { + public HelloMessageGenerator requestScopedBean() { return new HelloMessageGenerator(); } @Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator sessionMessage() { + public HelloMessageGenerator sessionScopedBean() { return new HelloMessageGenerator(); } @Bean @Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS) - public HelloMessageGenerator globalSessionMessage() { + public HelloMessageGenerator applicationScopedBean() { + return new HelloMessageGenerator(); + } + + @Bean + @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS) + public HelloMessageGenerator websocketScopedBean() { return new HelloMessageGenerator(); } diff --git a/spring-all/src/main/resources/application.properties b/spring-all/src/main/resources/application.properties new file mode 100644 index 0000000000..cbfe3f2df2 --- /dev/null +++ b/spring-all/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.profiles.active=@spring.profiles.active@ \ No newline at end of file diff --git a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp index 7974cf0220..0946f1b5ef 100644 --- a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp +++ b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp @@ -2,9 +2,9 @@ -

Bean Scopes Examples

-
- Request Message: ${requestMessage }
- Session Message: ${sessionMessage } +

Bean Scopes Examples

+
Previous Message: ${previousMessage } +
Current Message: ${currentMessage } +
\ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java b/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java new file mode 100644 index 0000000000..929d088a14 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/profiles/SpringProfilesWithMavenPropertiesIntegrationTest.java @@ -0,0 +1,22 @@ +package org.baeldung.profiles; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SpringProfilesConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringProfilesWithMavenPropertiesIntegrationTest { + + @Autowired + DatasourceConfig datasourceConfig; + + @Test + public void testSpringProfiles() { + Assert.assertTrue(datasourceConfig instanceof DevDatasourceConfig); + } +} \ No newline at end of file diff --git a/spring-boot-h2/spring-boot-h2-database/pom.xml b/spring-boot-h2/spring-boot-h2-database/pom.xml index 4b660334da..94f2293c34 100644 --- a/spring-boot-h2/spring-boot-h2-database/pom.xml +++ b/spring-boot-h2/spring-boot-h2-database/pom.xml @@ -22,6 +22,8 @@ UTF-8 UTF-8 1.8 + + com.mycorp.starter.HelloWorldApplication diff --git a/spring-boot-h2/spring-boot-h2-remote-app/src/main/java/com/baeldung/h2db/demo/ClientSpringBootApp.java b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java similarity index 85% rename from spring-boot-h2/spring-boot-h2-remote-app/src/main/java/com/baeldung/h2db/demo/ClientSpringBootApp.java rename to spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java index 39e52afd2c..7402312e1c 100644 --- a/spring-boot-h2/spring-boot-h2-remote-app/src/main/java/com/baeldung/h2db/demo/ClientSpringBootApp.java +++ b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/client/ClientSpringBootApp.java @@ -1,4 +1,4 @@ -package com.baeldung.h2db.demo; +package com.baeldung.h2db.demo.client; import java.sql.ResultSet; import java.sql.SQLException; @@ -7,16 +7,20 @@ import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @SpringBootApplication +@ComponentScan("com.baeldung.h2db.demo.client") public class ClientSpringBootApp { @Autowired private JdbcTemplate jdbcTemplate; public static void main(String[] args) { + System.setProperty("spring.datasource.url","jdbc:h2:tcp://localhost:9091/mem:mydb"); SpringApplication.run(ClientSpringBootApp.class, args); } @@ -46,4 +50,4 @@ public class ClientSpringBootApp { } }); } -} \ No newline at end of file +} diff --git a/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/SpringBootApp.java b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java similarity index 88% rename from spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/SpringBootApp.java rename to spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java index 1fe080ec22..e75b42a934 100644 --- a/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/SpringBootApp.java +++ b/spring-boot-h2/spring-boot-h2-database/src/main/java/com/baeldung/h2db/demo/server/SpringBootApp.java @@ -1,4 +1,4 @@ -package com.baeldung.h2db.demo; +package com.baeldung.h2db.demo.server; import java.sql.ResultSet; import java.sql.SQLException; @@ -9,10 +9,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @SpringBootApplication +@ComponentScan("com.baeldung.h2db.demo.server") public class SpringBootApp { @Autowired @@ -24,8 +26,7 @@ public class SpringBootApp { @PostConstruct private void initDb() { - System.out.println(String.format( - "****** Creating table: %s, and Inserting test data ******", "Employees")); + System.out.println(String.format("****** Creating table: %s, and Inserting test data ******", "Employees")); String sqlStatements[] = { "drop table employees if exists", @@ -57,4 +58,4 @@ public class SpringBootApp { public Server inMemoryH2DatabaseServer() throws SQLException { return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9091"); } -} \ No newline at end of file +} diff --git a/spring-boot-h2/spring-boot-h2-remote-app/pom.xml b/spring-boot-h2/spring-boot-h2-remote-app/pom.xml deleted file mode 100644 index 8eb59d2098..0000000000 --- a/spring-boot-h2/spring-boot-h2-remote-app/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - 4.0.0 - - com.baeldung.h2db - spring-boot-h2-remote-app - 0.0.1-SNAPSHOT - jar - - Demo Spring Boot applications that access H2 in memory database created - in another Spring Boot application - - - - org.springframework.boot - spring-boot-starter-parent - 2.0.4.RELEASE - - - - - UTF-8 - UTF-8 - 1.8 - - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - com.h2database - h2 - - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - diff --git a/spring-boot-h2/spring-boot-h2-remote-app/src/main/resources/application.properties b/spring-boot-h2/spring-boot-h2-remote-app/src/main/resources/application.properties deleted file mode 100644 index 6c3446f03a..0000000000 --- a/spring-boot-h2/spring-boot-h2-remote-app/src/main/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.datasource.url=jdbc:h2:tcp://localhost:9091/mem:mydb -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password= -spring.jpa.hibernate.ddl-auto=create \ No newline at end of file diff --git a/spring-boot-jasypt/pom.xml b/spring-boot-jasypt/pom.xml index 212f524da6..de0df92678 100644 --- a/spring-boot-jasypt/pom.xml +++ b/spring-boot-jasypt/pom.xml @@ -5,7 +5,6 @@ com.example.jasypt spring-boot-jasypt - 0.0.1-SNAPSHOT jar spring-boot-jasypt Demo project for Spring Boot @@ -52,9 +51,6 @@ - UTF-8 - UTF-8 - 1.8 2.0.0 diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java similarity index 94% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java index 58c2dc7bb2..c24cfe6efa 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptIntegrationTest.java @@ -14,7 +14,7 @@ import com.baeldung.jasypt.Main; @RunWith(SpringRunner.class) @SpringBootTest(classes = {Main.class}) -public class CustomJasyptTest { +public class CustomJasyptIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java similarity index 95% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java index f9b66b5044..e8dda73b4a 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleIntegrationTest.java @@ -13,7 +13,7 @@ import com.baeldung.jasypt.simple.PropertyServiceForJasyptSimple; @RunWith(SpringRunner.class) @SpringBootTest -public class JasyptSimpleTest { +public class JasyptSimpleIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java similarity index 95% rename from spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java rename to spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java index d246c21036..5f5d409ab9 100644 --- a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterIntegrationTest.java @@ -14,7 +14,7 @@ import com.baeldung.jasypt.starter.PropertyServiceForJasyptStarter; @RunWith(SpringRunner.class) @SpringBootTest -public class JasyptWithStarterTest { +public class JasyptWithStarterIntegrationTest { @Autowired ApplicationContext appCtx; diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml index c4f9b12676..c3bad74352 100644 --- a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-jul/pom.xml @@ -1,15 +1,13 @@ 4.0.0 - com.baeldung - 0.0.1-SNAPSHOT disabling-console-jul - - org.springframework.boot - spring-boot-starter-parent - 2.0.4.RELEASE - + + com.baeldung + disabling-console-logging + 0.0.1-SNAPSHOT + @@ -45,9 +43,4 @@ - - UTF-8 - UTF-8 - 1.8 - \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml index 97d10c574a..f9b34ec7d9 100644 --- a/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml +++ b/spring-boot-logging-log4j2/disabling-console-logging/disabling-console-log4j2/pom.xml @@ -1,49 +1,42 @@ - 4.0.0 - com.baeldung - 0.0.1-SNAPSHOT - disabling-console-log4j2 - - org.springframework.boot - spring-boot-starter-parent - 2.0.4.RELEASE - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + disabling-console-log4j2 - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-logging - - - - - org.springframework.boot - spring-boot-starter-log4j2 - - + + com.baeldung + disabling-console-logging + 0.0.1-SNAPSHOT + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + - - UTF-8 - UTF-8 - 1.8 - + + + + org.springframework.boot + spring-boot-maven-plugin + + + \ No newline at end of file diff --git a/spring-boot-logging-log4j2/disabling-console-logging/pom.xml b/spring-boot-logging-log4j2/disabling-console-logging/pom.xml index bc248e49b2..39a4a40f12 100644 --- a/spring-boot-logging-log4j2/disabling-console-logging/pom.xml +++ b/spring-boot-logging-log4j2/disabling-console-logging/pom.xml @@ -1,8 +1,6 @@ 4.0.0 - 0.0.1-SNAPSHOT - com.baeldung disabling-console-logging pom Projects for Disabling Spring Boot Console Logging tutorials diff --git a/spring-boot-logging-log4j2/pom.xml b/spring-boot-logging-log4j2/pom.xml index ee4d07c3e8..7caf1e8690 100644 --- a/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-logging-log4j2/pom.xml @@ -3,9 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung spring-boot-logging-log4j2 - 0.0.1-SNAPSHOT pom Projects for Spring Boot Logging tutorials @@ -43,10 +41,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml index 1d4c8867fb..571794167e 100644 --- a/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml +++ b/spring-boot-logging-log4j2/spring-boot-logging-log4j2-app/pom.xml @@ -3,9 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung spring-boot-logging-log4j2-app - 0.0.1-SNAPSHOT jar Demo project for Spring Boot Logging with Log4J2 diff --git a/spring-boot-mvc/pom.xml b/spring-boot-mvc/pom.xml index e456155f36..06712e4791 100644 --- a/spring-boot-mvc/pom.xml +++ b/spring-boot-mvc/pom.xml @@ -2,12 +2,10 @@ 4.0.0 - com.baeldung spring-boot-mvc - 0.0.1-SNAPSHOT jar spring-boot-mvc - Demo project for Spring Boot + Module For Spring Boot MVC parent-boot-2 @@ -21,6 +19,32 @@ org.springframework.boot spring-boot-starter-web + + + com.sun.faces + jsf-api + 2.2.9 + + + org.apache.tomcat.embed + tomcat-embed-jasper + + + javax.faces + javax.faces-api + 2.1 + + + javax.servlet + jstl + 1.2 + + + com.sun.faces + jsf-impl + 2.2.8-02 + + org.springframework.boot @@ -46,16 +70,18 @@ org.springframework.boot spring-boot-maven-plugin + + com.baeldung.springbootmvc.SpringBootMvcApplication + JAR + - UTF-8 - UTF-8 - 1.8 1.10.0 + com.baeldung.springbootmvc.SpringBootMvcApplication diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java new file mode 100644 index 0000000000..030216b747 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanA.java @@ -0,0 +1,12 @@ +package com.baeldung.nosuchbeandefinitionexception; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class BeanA { + + @Autowired + BeanB dependency; + +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java new file mode 100644 index 0000000000..f0cc263504 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/BeanB.java @@ -0,0 +1,5 @@ +package com.baeldung.nosuchbeandefinitionexception; + +public class BeanB { + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java new file mode 100644 index 0000000000..8709cf85ac --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/nosuchbeandefinitionexception/NoSuchBeanDefinitionDemoApp.java @@ -0,0 +1,12 @@ +package com.baeldung.nosuchbeandefinitionexception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class NoSuchBeanDefinitionDemoApp { + + public static void main(String[] args) { + SpringApplication.run(NoSuchBeanDefinitionDemoApp.class, args); + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java new file mode 100644 index 0000000000..5b4250d5e3 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/JsfApplication.java @@ -0,0 +1,31 @@ +package com.baeldung.springbootmvc.jsfapplication; + +import javax.faces.webapp.FacesServlet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.baeldung.springbootmvc.jsfapplication.controller.JsfController; +import com.baeldung.springbootmvc.jsfapplication.model.TodoDao; +import com.baeldung.springbootmvc.jsfapplication.service.TodoService; + +@SpringBootApplication +@ComponentScan(basePackageClasses = { JsfController.class, TodoDao.class, TodoService.class }) +public class JsfApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(JsfApplication.class, args); + } + + @Bean + public ServletRegistrationBean servletRegistrationBean() { + FacesServlet servlet = new FacesServlet(); + ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.jsf"); + return servletRegistrationBean; + } + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java new file mode 100644 index 0000000000..a9d21175c7 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/controller/JsfController.java @@ -0,0 +1,19 @@ +package com.baeldung.springbootmvc.jsfapplication.controller; + +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Scope(value = "session") +@Component(value = "jsfController") +public class JsfController { + + public String loadTodoPage() { + checkPermission(); + return "/todo.xhtml"; + } + + private void checkPermission() { + // Details omitted + } + +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java new file mode 100644 index 0000000000..0b97c5a78e --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Dao.java @@ -0,0 +1,17 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +import java.util.Collection; +import java.util.Optional; + +public interface Dao { + + Optional get(int id); + + Collection getAll(); + + int save(T t); + + void update(T t); + + void delete(T t); +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java new file mode 100644 index 0000000000..7aa8480f43 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/Todo.java @@ -0,0 +1,32 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +public class Todo { + + private int id; + private String message; + private int priority; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java new file mode 100644 index 0000000000..96d44474af --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/model/TodoDao.java @@ -0,0 +1,48 @@ +package com.baeldung.springbootmvc.jsfapplication.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Component; + +@Component +public class TodoDao implements Dao { + + private List todoList = new ArrayList<>(); + + @Override + public Optional get(int id) { + return Optional.ofNullable(todoList.get(id)); + } + + @Override + public Collection getAll() { + return todoList.stream() + .filter(Objects::nonNull) + .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); + } + + @Override + public int save(Todo todo) { + todoList.add(todo); + int index = todoList.size() - 1; + todo.setId(index); + return index; + } + + @Override + public void update(Todo todo) { + todoList.set(todo.getId(), todo); + } + + @Override + public void delete(Todo todo) { + todoList.set(todo.getId(), null); + } + +} \ No newline at end of file diff --git a/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java new file mode 100644 index 0000000000..89af3c66b9 --- /dev/null +++ b/spring-boot-mvc/src/main/java/com/baeldung/springbootmvc/jsfapplication/service/TodoService.java @@ -0,0 +1,50 @@ +package com.baeldung.springbootmvc.jsfapplication.service; + +import java.util.Collection; +import java.util.Comparator; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import com.baeldung.springbootmvc.jsfapplication.model.Dao; +import com.baeldung.springbootmvc.jsfapplication.model.Todo; + +@Scope(value = "session") +@Component(value = "todoService") +public class TodoService { + + @Autowired + private Dao todoDao; + private Todo todo = new Todo(); + + public void save() { + todoDao.save(todo); + todo = new Todo(); + } + + public Collection getAllTodo() { + return todoDao.getAll(); + } + + public Collection getAllTodoSortedByPriority() { + return todoDao.getAll() + .stream() + .sorted(Comparator.comparingInt(Todo::getId)) + .collect(Collectors.toList()); + } + + public int saveTodo(Todo todo) { + validate(todo); + return todoDao.save(todo); + } + + private void validate(Todo todo) { + // Details omitted + } + + public Todo getTodo() { + return todo; + } +} diff --git a/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml b/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml new file mode 100644 index 0000000000..9e31a2e09d --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/WEB-INF/faces-config.xml @@ -0,0 +1,9 @@ + + + + org.springframework.web.jsf.el.SpringBeanFacesELResolver + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml b/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..e0cd4d8850 --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + + Faces Servlet + javax.faces.webapp.FacesServlet + 1 + + + Faces Servlet + *.jsf + + + com.sun.faces.forceLoadConfiguration + true + + \ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/index.xhtml b/spring-boot-mvc/src/main/webapp/index.xhtml new file mode 100644 index 0000000000..40042b812c --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/index.xhtml @@ -0,0 +1,20 @@ + + + + + TO-DO application + + +
+

Welcome in the TO-DO application!

+

+ This is a static message rendered from xhtml. + + + +

+
+
+
\ No newline at end of file diff --git a/spring-boot-mvc/src/main/webapp/todo.xhtml b/spring-boot-mvc/src/main/webapp/todo.xhtml new file mode 100644 index 0000000000..426e101908 --- /dev/null +++ b/spring-boot-mvc/src/main/webapp/todo.xhtml @@ -0,0 +1,38 @@ + + + + + TO-DO application + + +
+
+ List of TO-DO items +
+ + + Message + #{item.message} + + + Priority + #{item.priority} + + +
+
+
+ Add new to-do item: +
+ + + + + + + +
+
+
\ No newline at end of file diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index 7d180047de..d0095e9a8a 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -33,6 +33,9 @@ spring-cloud-contract spring-cloud-kubernetes spring-cloud-archaius + spring-cloud-functions + spring-cloud-vault + spring-cloud-security diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml b/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml new file mode 100644 index 0000000000..3ffbf8f619 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + dynamodb-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + com.amazonaws + aws-java-sdk-dynamodb + ${aws.sdk.dynamo.version} + + + com.github.derjust + spring-data-dynamodb + ${spring.dynamo.version} + + + com.netflix.archaius + archaius-aws + ${archaius.version} + + + org.projectlombok + lombok + provided + + + + + 1.11.407 + 5.0.3 + 0.7.6 + + diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java new file mode 100644 index 0000000000..ee08f2b1fb --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/DynamoSourcesApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.archaius.dynamosources; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class DynamoSourcesApplication { + + public static void main(String[] args) { + SpringApplication.run(DynamoSourcesApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java new file mode 100644 index 0000000000..7b533e8021 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/ApplicationPropertiesConfigurations.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.config; + +import java.util.Arrays; + +import org.apache.commons.configuration.AbstractConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; +import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; +import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; +import com.amazonaws.services.dynamodbv2.util.TableUtils; +import com.baeldung.spring.cloud.archaius.dynamosources.dynamodb.ArchaiusProperties; +import com.baeldung.spring.cloud.archaius.dynamosources.dynamodb.ArchaiusPropertiesRepository; +import com.netflix.config.DynamicConfiguration; +import com.netflix.config.FixedDelayPollingScheduler; +import com.netflix.config.PolledConfigurationSource; +import com.netflix.config.sources.DynamoDbConfigurationSource; + +@Configuration +public class ApplicationPropertiesConfigurations { + + @Autowired + AmazonDynamoDB amazonDynamoDb; + + @Autowired + private ArchaiusPropertiesRepository repository; + + @Bean + public AbstractConfiguration addApplicationPropertiesSource() { + // Normally, the DB Table would be already created and populated. + // In this case, we'll do it just before creating the archaius config source that uses it + initDatabase(); + PolledConfigurationSource source = new DynamoDbConfigurationSource(amazonDynamoDb); + return new DynamicConfiguration(source, new FixedDelayPollingScheduler()); + } + + private void initDatabase() { + // Create the table + DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDb); + CreateTableRequest tableRequest = mapper.generateCreateTableRequest(ArchaiusProperties.class); + tableRequest.setProvisionedThroughput(new ProvisionedThroughput(1L, 1L)); + TableUtils.createTableIfNotExists(amazonDynamoDb, tableRequest); + + // Populate the table + ArchaiusProperties property = new ArchaiusProperties("baeldung.archaius.properties.one", "one FROM:dynamoDB"); + ArchaiusProperties property3 = new ArchaiusProperties("baeldung.archaius.properties.three", "three FROM:dynamoDB"); + repository.saveAll(Arrays.asList(property, property3)); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java new file mode 100644 index 0000000000..8f12051a7f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/config/DynamoDbConfiguration.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.config; + +import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; + +@Configuration +@EnableDynamoDBRepositories(basePackages = "com.baeldung.spring.cloud.archaius.dynamosources.dynamodb") +public class DynamoDbConfiguration { + + @Value("${amazon.dynamodb.endpoint}") + private String amazonDynamoDBEndpoint; + + @Value("${aws.accessKeyId}") + private String amazonDynamoDBAccessKeyId; + + @Value("${aws.secretKey}") + private String amazonDynamoDBSecretKey; + + @Bean + public AmazonDynamoDB amazonDynamoDB() { + AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard() + .withCredentials(amazonAWSCredentials()) + .withEndpointConfiguration(setupEndpointConfiguration()) + .build(); + + return amazonDynamoDB; + } + + private AWSCredentialsProvider amazonAWSCredentials() { + return new AWSStaticCredentialsProvider(new BasicAWSCredentials(amazonDynamoDBAccessKeyId, amazonDynamoDBSecretKey)); + } + + private EndpointConfiguration setupEndpointConfiguration() { + return new EndpointConfiguration(amazonDynamoDBEndpoint, Regions.DEFAULT_REGION.getName()); + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..2ac5055fe3 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/controller/ConfigPropertiesController.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java new file mode 100644 index 0000000000..016f8433cf --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusProperties.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.dynamodb; + +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@DynamoDBTable(tableName = "archaiusProperties") +public class ArchaiusProperties { + + @DynamoDBHashKey + @DynamoDBAttribute + private String key; + + @DynamoDBAttribute + private String value; +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java new file mode 100644 index 0000000000..fbcc953261 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/java/com/baeldung/spring/cloud/archaius/dynamosources/dynamodb/ArchaiusPropertiesRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.spring.cloud.archaius.dynamosources.dynamodb; + +import org.springframework.data.repository.CrudRepository; + +public interface ArchaiusPropertiesRepository extends CrudRepository { + +} diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties new file mode 100644 index 0000000000..3823d2685f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/main/resources/application.properties @@ -0,0 +1,6 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +amazon.dynamodb.endpoint=http://localhost:8000/ +aws.accessKeyId=key +aws.secretKey=key2 diff --git a/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java new file mode 100644 index 0000000000..3802cb99cd --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/dynamodb-config/src/test/java/com/baeldung/spring/cloud/archaius/dynamosources/ArchaiusDynamoDbLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.dynamosources; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusDynamoDbLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:dynamoDB"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:dynamoDB"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml b/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml new file mode 100644 index 0000000000..bb283576d8 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + jdbc-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java new file mode 100644 index 0000000000..ee7beec87b --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/JdbcSourcesApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JdbcSourcesApplication { + + public static void main(String[] args) { + SpringApplication.run(JdbcSourcesApplication.class, args); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java new file mode 100644 index 0000000000..f3eed0c2b5 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/config/ApplicationPropertiesConfigurations.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.config; + +import javax.sql.DataSource; + +import org.apache.commons.configuration.AbstractConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.netflix.config.DynamicConfiguration; +import com.netflix.config.FixedDelayPollingScheduler; +import com.netflix.config.PolledConfigurationSource; +import com.netflix.config.sources.JDBCConfigurationSource; + +@Configuration +public class ApplicationPropertiesConfigurations { + + @Autowired + DataSource h2DataSource; + + @Bean + public AbstractConfiguration addApplicationPropertiesSource() { + PolledConfigurationSource source = new JDBCConfigurationSource(h2DataSource, "select distinct key, value from properties", "key", "value"); + return new DynamicConfiguration(source, new FixedDelayPollingScheduler()); + } + +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..a793f39b29 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/controller/ConfigPropertiesController.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java new file mode 100644 index 0000000000..cc2783b506 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/java/com/baeldung/spring/cloud/archaius/jdbconfig/jdbc/Properties.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig.jdbc; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Properties { + + @Id + private String key; + + @SuppressWarnings("unused") + private String value; +} diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties new file mode 100644 index 0000000000..eca873f897 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +spring.h2.console.enabled=true diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql new file mode 100644 index 0000000000..eb80126d48 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/main/resources/data.sql @@ -0,0 +1,5 @@ +insert into properties +values('baeldung.archaius.properties.one', 'one FROM:jdbc_source'); + +insert into properties +values('baeldung.archaius.properties.three', 'three FROM:jdbc_source'); \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java new file mode 100644 index 0000000000..91d5f5754e --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/jdbc-config/src/test/java/com/baeldung/spring/cloud/archaius/jdbconfig/ArchaiusJDBCSourceLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.jdbconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusJDBCSourceLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:jdbc_source"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:jdbc_source"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-archaius/pom.xml b/spring-cloud/spring-cloud-archaius/pom.xml index cd102f86cd..fd3e34e463 100644 --- a/spring-cloud/spring-cloud-archaius/pom.xml +++ b/spring-cloud/spring-cloud-archaius/pom.xml @@ -21,6 +21,9 @@ basic-config additional-sources-simple extra-configs + jdbc-config + dynamodb-config + zookeeper-config diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml new file mode 100644 index 0000000000..8f8ec99ad8 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + zookeeper-config + jar + + + com.baeldung.spring.cloud + spring-cloud-archaius + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-zookeeper-config + ${cloud.zookeeper.version} + + + org.apache.zookeeper + zookeeper + + + + + org.apache.zookeeper + zookeeper + ${zookeeper.version} + + + org.slf4j + slf4j-log4j12 + + + + + + + 2.0.0.RELEASE + 3.4.13 + + diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java new file mode 100644 index 0000000000..12119e3e29 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ZookeeperConfigApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ZookeeperConfigApplication { + + public static void main(String[] args) { + SpringApplication.run(ZookeeperConfigApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java new file mode 100644 index 0000000000..59ef10aaf7 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/config/ZookeeperConfigsInitializer.java @@ -0,0 +1,58 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig.config; + +import org.apache.curator.framework.CuratorFramework; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * + * Ideally, we wouldn't need to initialize the zookeeper config values. + * Here we do it to verify that configurations are being retrieved. + * + */ +@Component +public class ZookeeperConfigsInitializer { + + private static final String CONFIG_BASE_NODE_PATH = "/config"; + private static final String APPLICATION_BASE_NODE_PATH = CONFIG_BASE_NODE_PATH + "/application"; + + @Autowired + CuratorFramework client; + + @EventListener + public void appReady(ApplicationReadyEvent event) throws Exception { + String pathOne = APPLICATION_BASE_NODE_PATH + "/baeldung.archaius.properties.one"; + String valueOne = "one FROM:zookeeper"; + String pathThree = APPLICATION_BASE_NODE_PATH + "/baeldung.archaius.properties.three"; + String valueThree = "three FROM:zookeeper"; + createBaseNodes(); + setValue(pathOne, valueOne); + setValue(pathThree, valueThree); + } + + private void setValue(String path, String value) throws Exception { + if (client.checkExists() + .forPath(path) == null) { + client.create() + .forPath(path, value.getBytes()); + } else { + client.setData() + .forPath(path, value.getBytes()); + } + } + + private void createBaseNodes() throws Exception { + if (client.checkExists() + .forPath(CONFIG_BASE_NODE_PATH) == null) { + client.create() + .forPath(CONFIG_BASE_NODE_PATH); + } + if (client.checkExists() + .forPath(APPLICATION_BASE_NODE_PATH) == null) { + client.create() + .forPath(APPLICATION_BASE_NODE_PATH); + } + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java new file mode 100644 index 0000000000..c8a5e53ee4 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/controller/ConfigPropertiesController.java @@ -0,0 +1,51 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig.controller; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicStringProperty; + +@RestController +public class ConfigPropertiesController { + + @Value("${baeldung.archaius.properties.one:not found!}") + private String propertyOneWithValue; + + @Value("${baeldung.archaius.properties.two:not found!}") + private String propertyTwoWithValue; + + @Value("${baeldung.archaius.properties.three:not found!}") + private String propertyThreeWithValue; + + private DynamicStringProperty propertyOneWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.one", "not found!"); + + private DynamicStringProperty propertyTwoWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.two", "not found!"); + + private DynamicStringProperty propertyThreeWithDynamic = DynamicPropertyFactory.getInstance() + .getStringProperty("baeldung.archaius.properties.three", "not found!"); + + @GetMapping("/properties-from-dynamic") + public Map getPropertiesFromDynamic() { + Map properties = new HashMap<>(); + properties.put(propertyOneWithDynamic.getName(), propertyOneWithDynamic.get()); + properties.put(propertyTwoWithDynamic.getName(), propertyTwoWithDynamic.get()); + properties.put(propertyThreeWithDynamic.getName(), propertyThreeWithDynamic.get()); + return properties; + } + + @GetMapping("/properties-from-value") + public Map getPropertiesFromValue() { + Map properties = new HashMap<>(); + properties.put("baeldung.archaius.properties.one", propertyOneWithValue); + properties.put("baeldung.archaius.properties.two", propertyTwoWithValue); + properties.put("baeldung.archaius.properties.three", propertyThreeWithValue); + return properties; + } +} diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties new file mode 100644 index 0000000000..91ad18a932 --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8082 +baeldung.archaius.properties.one=one FROM:application.properties +baeldung.archaius.properties.two=two FROM:application.properties +spring.application.name=zookeeper-config diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java new file mode 100644 index 0000000000..ff4358cb8f --- /dev/null +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/src/test/java/com/baeldung/spring/cloud/archaius/zookeeperconfig/ArchaiusZookeeperLiveTest.java @@ -0,0 +1,53 @@ +package com.baeldung.spring.cloud.archaius.zookeeperconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class ArchaiusZookeeperLiveTest { + + private static final String BASE_URL = "http://localhost:8082"; + + private static final String DYNAMIC_PROPERTIES_URL = "/properties-from-dynamic"; + private static final Map EXPECTED_ARCHAIUS_PROPERTIES = createExpectedArchaiusProperties(); + + private static Map createExpectedArchaiusProperties() { + Map map = new HashMap<>(); + map.put("baeldung.archaius.properties.one", "one FROM:zookeeper"); + map.put("baeldung.archaius.properties.two", "two FROM:application.properties"); + map.put("baeldung.archaius.properties.three", "three FROM:zookeeper"); + return map; + } + + @Autowired + ConfigurableApplicationContext context; + + @Autowired + private TestRestTemplate template; + + private Map exchangeAsMap(String uri, ParameterizedTypeReference> responseType) { + return template.exchange(uri, HttpMethod.GET, null, responseType) + .getBody(); + } + + @Test + public void givenNonDefaultConfigurationFilesSetup_whenRequestProperties_thenEndpointRetrievesValuesInFiles() { + Map initialResponse = this.exchangeAsMap(BASE_URL + DYNAMIC_PROPERTIES_URL, new ParameterizedTypeReference>() { + }); + + assertThat(initialResponse).containsAllEntriesOf(EXPECTED_ARCHAIUS_PROPERTIES); + } +} diff --git a/spring-cloud/spring-cloud-functions/README.MD b/spring-cloud/spring-cloud-functions/README.MD new file mode 100644 index 0000000000..c766dd1dc6 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/README.MD @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Serverless Functions with Spring Cloud Function](https://www.baeldung.com/spring-cloud-function) diff --git a/spring-cloud/spring-cloud-functions/pom.xml b/spring-cloud/spring-cloud-functions/pom.xml new file mode 100644 index 0000000000..8b2b0ad385 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + com.baeldung.spring + cloudfunction-aws + 0.0.1-SNAPSHOT + jar + + cloudfunction-aws + Demo project for Spring Cloud Function + + + org.springframework.boot + spring-boot-starter-parent + 2.0.4.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.0.1.RELEASE + 2.0.2 + + + + + org.springframework.cloud + spring-cloud-function-adapter-aws + ${spring-cloud-function.version} + + + + + org.springframework.cloud + spring-cloud-starter-function-web + 1.0.1.RELEASE + + + com.amazonaws + aws-lambda-java-events + ${aws-lambda-events.version} + provided + + + com.amazonaws + aws-lambda-java-core + 1.1.0 + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.springframework.boot.experimental + spring-boot-thin-layout + 1.0.10.RELEASE + + + + + org.apache.maven.plugins + maven-shade-plugin + + false + true + aws + + + + + + diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java new file mode 100644 index 0000000000..34e97d3b6c --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionAwsApplication.java @@ -0,0 +1,23 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +@SpringBootApplication +public class CloudFunctionAwsApplication { + + public static void main(String[] args) { + SpringApplication.run(CloudFunctionAwsApplication.class, args); + } + + @Bean + public Function reverseString() { + return value -> new StringBuilder(value).reverse().toString(); + } + +} diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java new file mode 100644 index 0000000000..52514dcd12 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/StringReverseHandler.java @@ -0,0 +1,7 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler; + +public class StringReverseHandler extends SpringBootRequestHandler { + +} diff --git a/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java new file mode 100644 index 0000000000..c443b98c18 --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/java/com/baeldung/spring/cloudfunction/aws/functions/Greeter.java @@ -0,0 +1,11 @@ +package com.baeldung.spring.cloudfunction.functions.aws; + +import java.util.function.Function; + +public class Greeter implements Function { + + @Override + public String apply(String s) { + return "Hello " + s + ", and welcome to Spring Cloud Function!!!"; + } +} diff --git a/spring-cloud/spring-cloud-functions/src/main/resources/application.properties b/spring-cloud/spring-cloud-functions/src/main/resources/application.properties new file mode 100644 index 0000000000..b445bfa4ed --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.cloud.function.scan.packages: com.baeldung.spring.cloudfunction.functions.aws \ No newline at end of file diff --git a/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java new file mode 100644 index 0000000000..6039debe3f --- /dev/null +++ b/spring-cloud/spring-cloud-functions/src/test/java/com/baeldung/spring/cloudfunction/aws/CloudFunctionApplicationTests.java @@ -0,0 +1,33 @@ +package com.baeldung.spring.cloudfunction.aws; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class CloudFunctionApplicationTests { + + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Test + public void givenAString_whenReverseStringCloudFunctionInvoked_thenStringIsReversed() { + assertThat(this.testRestTemplate.getForObject("http://localhost:" + port + "/reverseString/HelloWorld", String.class)).isEqualTo("dlroWolleH"); + } + + @Test + public void givenAString_whenGreeterCloudFunctionInvoked_thenPrintsGreeting() { + assertThat(this.testRestTemplate.getForObject("http://localhost:" + port + "/greeter/BaeldungUser", String.class)).isEqualTo("Hello BaeldungUser, and welcome to Spring Cloud Function!!!"); + } + +} diff --git a/spring-cloud/spring-cloud-security/README.md b/spring-cloud/spring-cloud-security/README.md deleted file mode 100644 index 39af52c077..0000000000 --- a/spring-cloud/spring-cloud-security/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# README # - -This README would normally document whatever steps are necessary to get your application up and running. - -### What is this repository for? ### - -* Quick summary -* Version -* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo) - -### How do I get set up? ### - -* Summary of set up -* Configuration -* Dependencies -* Database configuration -* How to run tests -* Deployment instructions - -### Contribution guidelines ### - -* Writing tests -* Code review -* Other guidelines - -### Who do I talk to? ### - -* Repo owner or admin -* Other community or team contact \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-client/pom.xml b/spring-cloud/spring-cloud-security/auth-client/pom.xml index f2d6308374..340c276c2d 100644 --- a/spring-cloud/spring-cloud-security/auth-client/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-client/pom.xml @@ -2,18 +2,15 @@ 4.0.0 - com.baeldung auth-client - 0.0.1-SNAPSHOT jar auth-client - Demo project for Spring Boot - + Spring Cloud Security APP Client Module + - parent-boot-1 + spring-cloud-security com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + 1.0.0-SNAPSHOT @@ -88,9 +85,6 @@ - UTF-8 - UTF-8 - 1.8 2.1.0 Dalston.SR4 diff --git a/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java b/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java similarity index 87% rename from spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java index ca89575ee0..37cff095db 100644 --- a/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationTests.java +++ b/spring-cloud/spring-cloud-security/auth-client/src/test/java/com/example/springoath2/Springoath2ApplicationIntegrationTest.java @@ -9,7 +9,7 @@ import com.baeldung.CloudSite; @RunWith(SpringRunner.class) @SpringBootTest(classes = CloudSite.class) -public class Springoath2ApplicationTests { +public class Springoath2ApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-security/auth-resource/pom.xml b/spring-cloud/spring-cloud-security/auth-resource/pom.xml index 0115259108..09474b2a4d 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-resource/pom.xml @@ -3,21 +3,18 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung auth-resource - 0.0.1-SNAPSHOT jar auth-resource - Demo project for Spring Boot + Spring Cloud Security APP Resource Module - parent-boot-1 + spring-cloud-security com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + 1.0.0-SNAPSHOT - + org.springframework.security.oauth @@ -60,9 +57,6 @@ - UTF-8 - UTF-8 - 1.8 Edgware.RELEASE diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java similarity index 85% rename from spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java rename to spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java index e0fe7006d9..3caa06ba4d 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationTests.java +++ b/spring-cloud/spring-cloud-security/auth-resource/src/test/java/com/baeldung/service/personservice/PersonserviceApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class PersonserviceApplicationTests { +public class PersonserviceApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-cloud/spring-cloud-security/auth-server/pom.xml b/spring-cloud/spring-cloud-security/auth-server/pom.xml index b4367935e3..92f92808f6 100644 --- a/spring-cloud/spring-cloud-security/auth-server/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-server/pom.xml @@ -2,15 +2,13 @@ 4.0.0 - com.baeldung auth-server - 0.0.1-SNAPSHOT - + Spring Cloud Security APP Server Module + - parent-boot-1 + spring-cloud-security com.baeldung - 0.0.1-SNAPSHOT - ../../../parent-boot-1 + 1.0.0-SNAPSHOT diff --git a/spring-cloud/spring-cloud-security/pom.xml b/spring-cloud/spring-cloud-security/pom.xml new file mode 100644 index 0000000000..1cf8751548 --- /dev/null +++ b/spring-cloud/spring-cloud-security/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + spring-cloud-security + pom + 1.0.0-SNAPSHOT + spring-cloud-security + + + parent-boot-1 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-1 + + + + auth-client + auth-resource + auth-server + + + diff --git a/spring-cloud/spring-cloud-stream-starters/twitter/twitter b/spring-cloud/spring-cloud-stream-starters/twitter/twitter deleted file mode 160000 index f9673ef0c1..0000000000 --- a/spring-cloud/spring-cloud-stream-starters/twitter/twitter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f9673ef0c11c51b327555aaca61ee196935f998b diff --git a/spring-boot-h2/spring-boot-h2-remote-app/.gitignore b/spring-cloud/spring-cloud-vault/.gitignore similarity index 85% rename from spring-boot-h2/spring-boot-h2-remote-app/.gitignore rename to spring-cloud/spring-cloud-vault/.gitignore index 82eca336e3..e6237b6f81 100644 --- a/spring-boot-h2/spring-boot-h2-remote-app/.gitignore +++ b/spring-cloud/spring-cloud-vault/.gitignore @@ -22,4 +22,8 @@ /nbbuild/ /dist/ /nbdist/ -/.nb-gradle/ \ No newline at end of file +/.nb-gradle/ + +## Extra +/vault-data/ +*.log diff --git a/spring-cloud/spring-cloud-vault/database-setup.sql b/spring-cloud/spring-cloud-vault/database-setup.sql new file mode 100644 index 0000000000..4bb1293f74 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/database-setup.sql @@ -0,0 +1,20 @@ +-- +-- Sample schema for testing vault database secrets +-- +create schema fakebank; +use fakebank; +create table account( + id decimal(16,0), + name varchar(30), + branch_id decimal(16,0), + customer_id decimal(16,0), + primary key (id)); + +-- +-- MySQL user that will be used by Vault to create other users on demand +-- +create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!' +grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option; +grant create user on *.* to 'fakebank-admin' with grant option; + +flush privileges; diff --git a/spring-cloud/spring-cloud-vault/pom.xml b/spring-cloud/spring-cloud-vault/pom.xml new file mode 100644 index 0000000000..68b8e44875 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + org.baeldung.spring.cloud + spring-cloud-vault + jar + + spring-cloud-vault + Demo project for Spring Boot + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + + UTF-8 + UTF-8 + 1.8 + Finchley.SR1 + + + + + + + + + org.springframework.cloud + spring-cloud-starter-vault-config + + + + org.springframework.cloud + spring-cloud-vault-config-databases + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + mysql + mysql-connector-java + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-cloud/spring-cloud-vault/sample-policy.hcl b/spring-cloud/spring-cloud-vault/sample-policy.hcl new file mode 100644 index 0000000000..554888661e --- /dev/null +++ b/spring-cloud/spring-cloud-vault/sample-policy.hcl @@ -0,0 +1,6 @@ +path "secret/fakebank" { + capabilities = ["read"] + allowed_parameters = { + "api_key" = [] + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java new file mode 100644 index 0000000000..81ece1ca4c --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.spring.cloud.vaultsample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class VaultSampleApplication { + + public static void main(String[] args) { + SpringApplication.run(VaultSampleApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/application.yml b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml new file mode 100644 index 0000000000..3d347ec855 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/resources/application.yml @@ -0,0 +1,6 @@ +spring: + application: + name: fakebank + + datasource: + url: jdbc:mysql://localhost:3306/fakebank diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000..1e837c4920 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/main/resources/bootstrap.yml @@ -0,0 +1,37 @@ +spring: + cloud: + vault: + uri: https://localhost:8200 + connection-timeout: 5000 + read-timeout: 15000 + config: + order: -10 + + ssl: + trust-store: classpath:/vault.jks + trust-store-password: changeit + + generic: + enabled: true + application-name: fakebank + + kv: + enabled: false + backend: kv + application-name: fakebank + + database: + enabled: true + role: fakebank-accounts-rw +# backend: database +# username-property: spring.datasource.username +# password-property: spring.datasource.password + + + + + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks b/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks new file mode 100644 index 0000000000..7090707543 Binary files /dev/null and b/spring-cloud/spring-cloud-vault/src/main/resources/vault.jks differ diff --git a/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java new file mode 100644 index 0000000000..7a9c5ba11a --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/java/org/baeldung/spring/cloud/vaultsample/VaultSampleApplicationLiveTest.java @@ -0,0 +1,66 @@ +package org.baeldung.spring.cloud.vaultsample; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; + +import javax.sql.DataSource; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class VaultSampleApplicationLiveTest { + + @Autowired + Environment env; + + @Autowired + DataSource datasource; + + + @Test + public void whenGenericBackendEnabled_thenEnvHasAccessToVaultSecrets() { + + String fooValue = env.getProperty("foo"); + assertEquals("test-bar", fooValue); + + } + + @Test + public void whenKvBackendEnabled_thenEnvHasAccessToVaultSecrets() { + + String fooValue = env.getProperty("foo.versioned"); + assertEquals("bar1", fooValue); + + + } + + + @Test + public void whenDatabaseBackendEnabled_thenDatasourceUsesVaultCredentials() { + + try (Connection c = datasource.getConnection()) { + + ResultSet rs = c.createStatement() + .executeQuery("select 1"); + + rs.next(); + Long value = rs.getLong(1); + + assertEquals(Long.valueOf(1), value); + + } catch (SQLException sex) { + throw new RuntimeException(sex); + } + + } + +} diff --git a/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties b/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..8c54227dda --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/resources/bootstrap.properties @@ -0,0 +1,3 @@ +spring.cloud.vault.token=b93d1b0d-15b5-f69e-d311-352a65fa7bc8 + +logging.level.org.springframework=INFO \ No newline at end of file diff --git a/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks b/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks new file mode 100644 index 0000000000..7090707543 Binary files /dev/null and b/spring-cloud/spring-cloud-vault/src/test/resources/vault.jks differ diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert new file mode 100644 index 0000000000..6a598df419 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.cert @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgIJAKoy5OBgOKYwMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xODA4MDkwMTM1MzJaFw0yODA4MDYwMTM1MzJaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMXiHqB5dYdxJ1+abSG55gb3NNo3fzNbkjp/tAIl1FUeyCyyP/yERrkUkhFj +4gg/q1YHUO/ftc0PdL/JBaVBTKnzsxgp7hY/dUEkZqXZ649X0UrJIRd13w5N71cL +P1+PjCrqokMVceU18kK7CyaOmiTKYFmt/RTJQLmFQspmJXNSiq7zUvAgyvoY5TzJ +n7MuSobHXq17pnlm+XbnAgDJUt9yR6BC2dFF20iZU4uTXy2VRngfLey3p+6in0TO +jD4cEMJqwgUbjiI8m/hESCketVkq0W0qkkVfWBNzz5qqGHNRbhZBwT7SM0MuXum+ +qEY7n7jcQAk5BDb613liVQjQ0tkCAwEAAaNQME4wHQYDVR0OBBYEFHYjQ0/HJgXd +BnqM4jLPjmygfi8fMB8GA1UdIwQYMBaAFHYjQ0/HJgXdBnqM4jLPjmygfi8fMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABSf++sinLT9dFnC+B6ut5Zp +haTL7PA1/CdmhTdE2vlFPGGw2BD4c/gphBsHKSNHE96irTqFXI/kl6labQpZ5P8G +JORLfaAyl58UT1FayxL4ISzwsp+UrqO60vxkYyLkbEJjuaxIv11oOoFDIp5oBTqe +BVoCfcTjYtTr+IwwlypLPrVTnDNGX5oPIBbTUFvR0t5RaLZgmXLT78ERhWOLINqh +Yi6j7fYaRm/C5IQ8N/TASot7V0SMH2Rt6PrzJb5SLV8r+yozg2BSfU6hZUyKwABR +N3zppKvKzdhlVo9OuSW3x4Tb3V+CVE/8CmTwRfhab9SCmvmaa2FxI+8/2OPVWDU= +-----END CERTIFICATE----- diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key new file mode 100644 index 0000000000..eba611823a --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxeIeoHl1h3EnX5ptIbnmBvc02jd/M1uSOn+0AiXUVR7ILLI/ +/IRGuRSSEWPiCD+rVgdQ79+1zQ90v8kFpUFMqfOzGCnuFj91QSRmpdnrj1fRSskh +F3XfDk3vVws/X4+MKuqiQxVx5TXyQrsLJo6aJMpgWa39FMlAuYVCymYlc1KKrvNS +8CDK+hjlPMmfsy5KhsderXumeWb5ducCAMlS33JHoELZ0UXbSJlTi5NfLZVGeB8t +7Len7qKfRM6MPhwQwmrCBRuOIjyb+ERIKR61WSrRbSqSRV9YE3PPmqoYc1FuFkHB +PtIzQy5e6b6oRjufuNxACTkENvrXeWJVCNDS2QIDAQABAoIBACEyB5VACtlHwCUn +kLshplbwzWr1+F6zM9qgZaAenHoTCd2FoXpI7lxJ+R71tItRsvphi9BRpPvbZehu +XoYUaDnyac7Z6djNmGvvIVEdN4j6YF+9UdHPsjWCGW5uspjjSc5BQisiw9KBtDxB +iGNVdMJLONKSf2wnPrZgho3RiOLJX/poPyGTkMHuhBVvo4oy7Ax3XalaAcufgqwm +YBQJ1Tka+33EUiLkxzJTXxNbIAI2scP8jhGn6mokS0V4gZPxJKUZEyydXRWwi6ex +ua/7q76ELJS5b+xKRYfGsvavFDx8R+LqX8oegALD33ki3rm1MQW7GmikRL98+EVW +Q9mQsqECgYEA/IrP8vycbJOgn1vriNItFcZtczSBlrXCRF0up2cqKMs9c+T5i51x +ZKXK5lo3DfMT+YDM+iiGZ9+vM0UA2VxbFD3XV9mQDBaNC+Duknqxx+OLmWva9YwR +nMaevqVV9LCn+GgUcK+IygEnpzpdP4q8YcXAfGAnZgnihN/AUYAaB70CgYEAyJe4 +yO0S9gAH5aoDdooL0YXrH/Dzd+fAgNsawLhoOltcoZqZFWeAllM0GsrCpfTRltuy +dn9ca3YK0GlWl7h5rDle1HO3nhp1FcpeG1oxmkeQta3PG66uUuMccTAljCLFrEe3 +DguH8+qdjhLk+ZnUB9AVkS79pzdwuEHVljCK600CgYB6mMygkh9B2lzkX9Q0xItc +gcqKXdf3GN9pHq9SVxOxYBDCHUtDirgMeyvHrc4COJneyrc3TcsJzB4aToo9+sbA +SdErdZOnOp9YP+axN1zsw7r2TNSr1UaLjCRuOodC1SuFvMkHdz95iRv946h2+1u+ +PyjVeDxIHc5YYOLU7dI1JQKBgQDF5KDBYNm25brkwcCe3nvgXfzjyyN25KUOupn/ +DS6Oe/m72Lgz3KOIKleaIvS7IvbunJnIu8dioNb0Wye5kJ5A4WyDrhG1IabnM3l6 +BJYw/W9vPSS4y7FhRnuV0wkH4nofh7S5X3jlk02Sj2NkN3Vtq8TLMY++uzwyG4jq +ncM/dQKBgQC+6mA5OfbVN4lRn+zrSiIH5gpvZYPh9wXeTnDWHa13sJsu3e8AQxtk +TfE0W13UV5jhGL8Wvyyxn+doGFTdcZapOlwuoQ6RcgHcVQm2sOl60GAa4idmm0A6 +TcgnIOTyVRlNBoWLCfN83BlGz4gcDpnuZZ/0JuguixgLS323hQlLvg== +-----END RSA PRIVATE KEY----- diff --git a/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl new file mode 100644 index 0000000000..c880f2d744 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/src/test/vault-config/vault-test.hcl @@ -0,0 +1,20 @@ +/* + * Sample configuration file for tests + */ + +// Enable UI +ui = true + +// Filesystem storage +storage "file" { + path = "./vault-data" +} + +// TCP Listener using a self-signed certificate +listener "tcp" { + address = "127.0.0.1:8200" + tls_cert_file = "./src/test/vault-config/localhost.cert" + tls_key_file = "./src/test/vault-config/localhost.key" +} + + diff --git a/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt new file mode 100644 index 0000000000..b965a95321 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-cheatsheet.txt @@ -0,0 +1,82 @@ +== Vault server bootstrap + +1. Run vaul-start in one shell + +2. Open another shell and execute the command below: +> vault operator init + +Vault will output the unseal keys and root token: STORE THEM SAFELY !!! + +Example output: +Unseal Key 1: OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +Unseal Key 2: iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +Unseal Key 3: K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF +Unseal Key 4: +5zhysLAO4hIdZs0kiZpkrRovw11uQacfloiBwnZBJA/ +Unseal Key 5: GDwSq18lXV3Cw4MoHsKIH137kuI0mdl36UiD9WxOdulc + +Initial Root Token: d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 + +... + +== Admin token setup + +1. Set the VAULT_TOKEN environment variable with the root token value +export VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Linux) +set VAULT_TOKEN=d341fdaf-1cf9-936a-3c38-cf5eec94b5c0 (Windows) + +2. Create another admin token + +>vault token create -display-name=admin +Key Value +--- ----- +token 3779c3ca-9f5e-1d8f-3842-efa96d88de43 <=== this is the new root token +token_accessor 2dfa4031-973b-cf88-c749-ee6f520ecaea +token_duration ∞ +token_renewable false +token_policies ["root"] +identity_policies [] +policies ["root"] + +3. Create ~/.vault-secret with your root token +4. Unset the VAULT_TOKEN environment variable ! + +=== Test DB setup (MySQL only, for now) + +1. Create test db +2. Create admin account used to create dynamic accounts: + +create schema fakebank; +create user 'fakebank-admin'@'%' identified by 'Sup&rSecre7!' +grant all privileges on fakebank.* to 'fakebank-admin'@'%' with grant option; +grant create user on *.* to 'fakebank-admin' with grant option; +flush privileges; + + +=== Database secret backend setup +> vault secrets enable database + +==== Create db configuration +> vault write database/config/mysql-fakebank ^ + plugin_name=mysql-legacy-database-plugin ^ + connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/fakebank" ^ + allowed_roles="*" ^ + username="fakebank-admin" ^ + password="Sup&rSecre7!" + +==== Create roles +> vault write database/roles/fakebank-accounts-ro ^ + db_name=mysql-fakebank ^ + creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON fakebank.* TO '{{name}}'@'%';" ^ + default_ttl="1h" ^ + max_ttl="24h" + +> vault write database/roles/fakebank-accounts-rw ^ + db_name=mysql-fakebank ^ + creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT,INSERT,UPDATE ON fakebank.* TO '{{name}}'@'%';" ^ + default_ttl="1m" ^ + max_ttl="2m" + +=== Get credentials +> vault read database/creds/fakebank-accounts-rw + + diff --git a/spring-cloud/spring-cloud-vault/vault-env.bat b/spring-cloud/spring-cloud-vault/vault-env.bat new file mode 100644 index 0000000000..d7aa5da215 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-env.bat @@ -0,0 +1,5 @@ +@echo off +echo Setting environment variables to access local vault.. +set VAULT_ADDR=https://localhost:8200 +set VAULT_CACERT=%~dp0%/src/test/vault-config/localhost.cert +rem set VAULT_TLS_SERVER_NAME=localhost diff --git a/spring-cloud/spring-cloud-vault/vault-env.sh b/spring-cloud/spring-cloud-vault/vault-env.sh new file mode 100644 index 0000000000..06077cee2e --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-env.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo Setting environment variables to access local vault.. +SCRIPTPATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd ) +export VAULT_ADDR=https://localhost:8200 +export VAULT_CACERT=$SCRIPTPATH/src/test/vault-config/localhost.cert +export VAULT_TLS_SERVER_NAME=localhost diff --git a/spring-cloud/spring-cloud-vault/vault-start.bat b/spring-cloud/spring-cloud-vault/vault-start.bat new file mode 100644 index 0000000000..e8f6ce4c9f --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-start.bat @@ -0,0 +1,3 @@ +echo Starting vault server... +pushd %~dp0% +vault server -config %~dp0%/src/test/vault-config/vault-test.hcl diff --git a/spring-cloud/spring-cloud-vault/vault-start.sh b/spring-cloud/spring-cloud-vault/vault-start.sh new file mode 100644 index 0000000000..d5af7cfee6 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +pushd $SCRIPTPATH +echo Starting vault server... +vault server -config $SCRIPTPATH/src/test/vault-config/vault-test.hcl diff --git a/spring-cloud/spring-cloud-vault/vault-unseal.bat b/spring-cloud/spring-cloud-vault/vault-unseal.bat new file mode 100644 index 0000000000..8133f90892 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-unseal.bat @@ -0,0 +1,7 @@ + +call %~dp0%/vault-env.bat + +vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF diff --git a/spring-cloud/spring-cloud-vault/vault-unseal.sh b/spring-cloud/spring-cloud-vault/vault-unseal.sh new file mode 100644 index 0000000000..699b383801 --- /dev/null +++ b/spring-cloud/spring-cloud-vault/vault-unseal.sh @@ -0,0 +1,8 @@ +#!/bin/bash +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +. $SCRIPTPATH/vault-env.sh + +# Please replace the unseal keys below for your own +vault operator unseal OfCseaSZzjTZmrxhfx+5clKobwLGCNiJdAlfixSG9E3o +vault operator unseal iplVLPTHW0n0WL5XuI6QWwyNtWbKTek1SoKcG0gR7vdT +vault operator unseal K0TleK3OYUvWFF+uIDsQuf5a+/gkv1PtZ3O47ornzRoF diff --git a/spring-core/src/main/java/com/baeldung/definition/Config.java b/spring-core/src/main/java/com/baeldung/definition/Config.java new file mode 100644 index 0000000000..126e6259ca --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/Config.java @@ -0,0 +1,16 @@ +package com.baeldung.definition; + +import com.baeldung.definition.domain.Address; +import com.baeldung.definition.domain.Company; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackageClasses = Company.class) +public class Config { + @Bean + public Address getAddress() { + return new Address("High Street", 1000); + } +} diff --git a/spring-core/src/main/java/com/baeldung/definition/domain/Address.java b/spring-core/src/main/java/com/baeldung/definition/domain/Address.java new file mode 100644 index 0000000000..91be18398e --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/domain/Address.java @@ -0,0 +1,14 @@ +package com.baeldung.definition.domain; + +import lombok.Data; + +@Data +public class Address { + private String street; + private int number; + + public Address(String street, int number) { + this.street = street; + this.number = number; + } +} diff --git a/spring-core/src/main/java/com/baeldung/definition/domain/Company.java b/spring-core/src/main/java/com/baeldung/definition/domain/Company.java new file mode 100644 index 0000000000..eabde8afdf --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/definition/domain/Company.java @@ -0,0 +1,14 @@ +package com.baeldung.definition.domain; + +import lombok.Data; +import org.springframework.stereotype.Component; + +@Data +@Component +public class Company { + private Address address; + + public Company(Address address) { + this.address = address; + } +} diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java b/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java index 1e6fad63aa..e0fe01acdd 100644 --- a/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/app/PurchaseDeptService.java @@ -1,13 +1,14 @@ package com.baeldung.dependency.exception.app; import com.baeldung.dependency.exception.repository.InventoryRepository; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; @Service public class PurchaseDeptService { private InventoryRepository repository; - public PurchaseDeptService(InventoryRepository repository) { + public PurchaseDeptService(@Qualifier("dresses") InventoryRepository repository) { this.repository = repository; } } \ No newline at end of file diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/app/CustomConfiguration.java b/spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java similarity index 73% rename from spring-core/src/main/java/com/baeldung/dependency/exception/app/CustomConfiguration.java rename to spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java index 4366cb617a..e45438a9fe 100644 --- a/spring-core/src/main/java/com/baeldung/dependency/exception/app/CustomConfiguration.java +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/app/SpringDependenciesExampleApplication.java @@ -6,8 +6,8 @@ import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(basePackages = "com.baeldung.dependency.exception") -public class CustomConfiguration { +public class SpringDependenciesExampleApplication { public static void main(String[] args) { - SpringApplication.run(CustomConfiguration.class, args); + SpringApplication.run(SpringDependenciesExampleApplication.class, args); } } diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java index 4a6c836143..5a1371ce04 100644 --- a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/DressRepository.java @@ -1,9 +1,10 @@ package com.baeldung.dependency.exception.repository; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Repository; -@Primary +@Qualifier("dresses") @Repository public class DressRepository implements InventoryRepository { } diff --git a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java index 60495914cd..227d8934b6 100644 --- a/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java +++ b/spring-core/src/main/java/com/baeldung/dependency/exception/repository/ShoeRepository.java @@ -1,7 +1,9 @@ package com.baeldung.dependency.exception.repository; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; +@Qualifier("shoes") @Repository public class ShoeRepository implements InventoryRepository { } diff --git a/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java b/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java new file mode 100644 index 0000000000..0057611308 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/definition/SpringBeanIntegrationTest.java @@ -0,0 +1,18 @@ +package com.baeldung.definition; + +import com.baeldung.definition.domain.Company; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.Assert.assertEquals; + +public class SpringBeanIntegrationTest { + @Test + public void whenUsingIoC_thenDependenciesAreInjected() { + ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); + Company company = context.getBean("company", Company.class); + assertEquals("High Street", company.getAddress().getStreet()); + assertEquals(1000, company.getAddress().getNumber()); + } +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java new file mode 100644 index 0000000000..a575f0b915 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/InventoryRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.domain.MerchandiseEntity; +import org.springframework.data.repository.CrudRepository; + +public interface InventoryRepository extends CrudRepository { +} diff --git a/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java b/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java new file mode 100644 index 0000000000..bfc690e0e2 --- /dev/null +++ b/spring-data-jpa/src/main/java/com/baeldung/domain/MerchandiseEntity.java @@ -0,0 +1,66 @@ +package com.baeldung.domain; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.math.BigDecimal; + +@Entity +public class MerchandiseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String title; + + private BigDecimal price; + + private String brand; + + public MerchandiseEntity() { + } + + public MerchandiseEntity(String title, BigDecimal price) { + this.title = title; + this.price = price; + } + + public Long getId() { + return id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + @Override + public String toString() { + return "MerchandiseEntity{" + + "id=" + id + + ", title='" + title + '\'' + + ", price=" + price + + ", brand='" + brand + '\'' + + '}'; + } +} diff --git a/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java new file mode 100644 index 0000000000..9d6334445c --- /dev/null +++ b/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/InventoryRepositoryIntegrationTest.java @@ -0,0 +1,60 @@ +package com.baeldung.dao.repositories; + +import com.baeldung.config.PersistenceConfiguration; +import com.baeldung.domain.MerchandiseEntity; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.junit4.SpringRunner; + +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@DataJpaTest(excludeAutoConfiguration = {PersistenceConfiguration.class}) +public class InventoryRepositoryIntegrationTest { + + private static final String ORIGINAL_TITLE = "Pair of Pants"; + private static final String UPDATED_TITLE = "Branded Luxury Pants"; + private static final String UPDATED_BRAND = "Armani"; + private static final String ORIGINAL_SHORTS_TITLE = "Pair of Shorts"; + + @Autowired + private InventoryRepository repository; + + @Test + public void shouldCreateNewEntryInDB() { + MerchandiseEntity pants = new MerchandiseEntity(ORIGINAL_TITLE, BigDecimal.ONE); + pants = repository.save(pants); + + MerchandiseEntity shorts = new MerchandiseEntity(ORIGINAL_SHORTS_TITLE, new BigDecimal(3)); + shorts = repository.save(shorts); + + assertNotNull(pants.getId()); + assertNotNull(shorts.getId()); + assertNotEquals(pants.getId(), shorts.getId()); + } + + @Test + public void shouldUpdateExistingEntryInDB() { + MerchandiseEntity pants = new MerchandiseEntity(ORIGINAL_TITLE, BigDecimal.ONE); + pants = repository.save(pants); + + Long originalId = pants.getId(); + + pants.setTitle(UPDATED_TITLE); + pants.setPrice(BigDecimal.TEN); + pants.setBrand(UPDATED_BRAND); + + MerchandiseEntity result = repository.save(pants); + + assertEquals(originalId, result.getId()); + assertEquals(UPDATED_TITLE, result.getTitle()); + assertEquals(BigDecimal.TEN, result.getPrice()); + assertEquals(UPDATED_BRAND, result.getBrand()); + } +} diff --git a/spring-rest-embedded-tomcat/pom.xml b/spring-rest-embedded-tomcat/pom.xml index 9f6eb0d703..3cbbf63d94 100644 --- a/spring-rest-embedded-tomcat/pom.xml +++ b/spring-rest-embedded-tomcat/pom.xml @@ -3,7 +3,6 @@ 4.0.0 org.baeldung.embedded spring-rest-embedded-tomcat - 0.0.1-SNAPSHOT spring-rest-embedded-tomcat war @@ -61,33 +60,8 @@ - - spring-rest-embedded-tomcat - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - - 2.9.2 - 1.8 - 1.8 4.0.0 9.0.1 4.5.3 diff --git a/spring-rest-shell/pom.xml b/spring-rest-shell/pom.xml index 2f7d1c8933..7a604946b6 100644 --- a/spring-rest-shell/pom.xml +++ b/spring-rest-shell/pom.xml @@ -2,9 +2,7 @@ 4.0.0 - com.baeldung spring-rest-shell - 0.0.1-SNAPSHOT jar spring-rest-shell A simple project to demonstrate Spring REST Shell features. @@ -48,10 +46,4 @@ - - UTF-8 - UTF-8 - 1.8 - - diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java new file mode 100644 index 0000000000..fd270686a2 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/IpApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.ip; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class IpApplication extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(IpApplication.class, args); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java new file mode 100644 index 0000000000..078dd81259 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/CustomIpAuthenticationProvider.java @@ -0,0 +1,53 @@ +package org.baeldung.ip.config; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Component; + +@Component +public class CustomIpAuthenticationProvider implements AuthenticationProvider { + + Set whitelist = new HashSet(); + + public CustomIpAuthenticationProvider() { + super(); + whitelist.add("11.11.11.11"); + whitelist.add("127.0.0.1"); + } + + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + WebAuthenticationDetails details = (WebAuthenticationDetails) auth.getDetails(); + String userIp = details.getRemoteAddress(); + if(! whitelist.contains(userIp)){ + throw new BadCredentialsException("Invalid IP Address"); + } + final String name = auth.getName(); + final String password = auth.getCredentials().toString(); + + if (name.equals("john") && password.equals("123")) { + List authorities =new ArrayList(); + authorities.add(new SimpleGrantedAuthority("ROLE_USER")); + return new UsernamePasswordAuthenticationToken(name, password, authorities); + } + else{ + throw new BadCredentialsException("Invalid username or password"); + } + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java new file mode 100644 index 0000000000..3a8032a734 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityConfig.java @@ -0,0 +1,36 @@ +package org.baeldung.ip.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity//(debug = true) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomIpAuthenticationProvider authenticationProvider; + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + auth.inMemoryAuthentication().withUser("john").password("{noop}123").authorities("ROLE_USER"); + // auth.authenticationProvider(authenticationProvider); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers("/login").permitAll() +// .antMatchers("/foos/**").hasIpAddress("11.11.11.11") + .antMatchers("/foos/**").access("isAuthenticated() and hasIpAddress('11.11.11.11')") + .anyRequest().authenticated() + .and().formLogin().permitAll() + .and().csrf().disable(); + // @formatter:on + } + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java new file mode 100644 index 0000000000..1d22ca4c67 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/config/SecurityXmlConfig.java @@ -0,0 +1,9 @@ +package org.baeldung.ip.config; + + +//@Configuration +//@EnableWebSecurity +//@ImportResource({ "classpath:spring-security-ip.xml" }) +public class SecurityXmlConfig { + +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java new file mode 100644 index 0000000000..940194c421 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/ip/web/MainController.java @@ -0,0 +1,42 @@ +package org.baeldung.ip.web; + +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.http.HttpServletRequest; + +import org.baeldung.custom.persistence.model.Foo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +public class MainController { + + @Autowired + @Qualifier("springSecurityFilterChain") + private Filter springSecurityFilterChain; + + @RequestMapping(method = RequestMethod.GET, value = "/filters") + @ResponseBody + public void getFilters() { + FilterChainProxy filterChainProxy = (FilterChainProxy) springSecurityFilterChain; + List list = filterChainProxy.getFilterChains(); + list.stream() + .flatMap(chain -> chain.getFilters().stream()) + .forEach(filter -> System.out.println(filter.getClass())); + } + + @RequestMapping(method = RequestMethod.GET, value = "/foos/{id}") + @ResponseBody + public Foo findById(@PathVariable final long id, HttpServletRequest request) { + return new Foo("Sample"); + } + +} diff --git a/spring-security-mvc-boot/src/main/resources/application.properties b/spring-security-mvc-boot/src/main/resources/application.properties index f015086a4f..25eac743d1 100644 --- a/spring-security-mvc-boot/src/main/resources/application.properties +++ b/spring-security-mvc-boot/src/main/resources/application.properties @@ -6,4 +6,7 @@ spring.datasource.password= spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.database=H2 spring.jpa.show-sql=false -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect \ No newline at end of file +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + + +#logging.level.org.springframework.security.web.FilterChainProxy=DEBUG \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml b/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml new file mode 100644 index 0000000000..31796ad134 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/spring-security-ip.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java new file mode 100644 index 0000000000..e12e2f87b0 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/IpLiveTest.java @@ -0,0 +1,27 @@ +package org.baeldung.web; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.restassured.RestAssured; +import io.restassured.response.Response; + +import org.junit.Test; + + +public class IpLiveTest { + + @Test + public void givenUser_whenGetHomePage_thenOK() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/"); + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("Welcome")); + } + + @Test + public void givenUserWithWrongIP_whenGetFooById_thenForbidden() { + final Response response = RestAssured.given().auth().form("john", "123").get("http://localhost:8082/foos/1"); + assertEquals(403, response.getStatusCode()); + assertTrue(response.asString().contains("Forbidden")); + } + +} \ No newline at end of file diff --git a/spring-security-mvc-socket/README.md b/spring-security-mvc-socket/README.md index 828d9a3448..3daf9199e6 100644 --- a/spring-security-mvc-socket/README.md +++ b/spring-security-mvc-socket/README.md @@ -1,3 +1,10 @@ +To build the project, run the command: mvn clean install. This will build a war file in the target folder that you can deploye on a server like Tomcat. + +Alternatively, run the project from an IDE. + +To login, use credentials from the data.sql file in src/main/resource, eg: user/password. + + ### Relevant Articles: - [Intro to Security and WebSockets](http://www.baeldung.com/spring-security-websockets) -- [Spring WebSockets: Specific User Chat](http://www.baeldung.com/spring-websocket-specific-user-chat) \ No newline at end of file +- [Spring WebSockets: Specific User Chat](https://www.baeldung.com/spring-websockets-send-message-to-user) diff --git a/spring-security-mvc-socket/pom.xml b/spring-security-mvc-socket/pom.xml index b7559753b5..ade24d8f7b 100644 --- a/spring-security-mvc-socket/pom.xml +++ b/spring-security-mvc-socket/pom.xml @@ -151,7 +151,7 @@
- + org.apache.tomcat.maven @@ -171,7 +171,6 @@ - spring-security-mvc-socket diff --git a/spring-security-openid/pom.xml b/spring-security-openid/pom.xml index a2c0b6b119..4343996e02 100644 --- a/spring-security-openid/pom.xml +++ b/spring-security-openid/pom.xml @@ -3,9 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung spring-security-openid - 0.0.1-SNAPSHOT war spring-security-openid Spring OpenID sample project diff --git a/spring-security-rest/pom.xml b/spring-security-rest/pom.xml index 5bde78db7e..57ce5ddb92 100644 --- a/spring-security-rest/pom.xml +++ b/spring-security-rest/pom.xml @@ -300,7 +300,7 @@ 2.9.0 - 2.7.0 + 2.9.2 2.6 diff --git a/spring-swagger-codegen/pom.xml b/spring-swagger-codegen/pom.xml index d14dcc3176..8e551d850f 100644 --- a/spring-swagger-codegen/pom.xml +++ b/spring-swagger-codegen/pom.xml @@ -1,7 +1,6 @@ 4.0.0 - com.baeldung spring-swagger-codegen 0.0.1-SNAPSHOT pom diff --git a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml index 0f1cfa27ac..06a92ffae7 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-api-client/pom.xml @@ -38,23 +38,6 @@ - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - - loggerPath - conf/log4j.properties - - - -Xms512m -Xmx1500m - methods - pertest - - - org.apache.maven.plugins diff --git a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml index 281ed59857..0fb5cf8e75 100644 --- a/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml +++ b/spring-swagger-codegen/spring-swagger-codegen-app/pom.xml @@ -1,11 +1,8 @@ 4.0.0 - - com.baeldung spring-swagger-codegen-app - 0.0.1-SNAPSHOT - + com.baeldung spring-swagger-codegen @@ -37,7 +34,6 @@ - 1.8 0.0.1-SNAPSHOT 1.5.10.RELEASE diff --git a/spring-vertx/pom.xml b/spring-vertx/pom.xml index 69a043ed01..790eeff128 100644 --- a/spring-vertx/pom.xml +++ b/spring-vertx/pom.xml @@ -3,9 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung spring-vertx - 0.0.1-SNAPSHOT jar Spring Vertx A demo project with vertx spring integration @@ -57,31 +55,10 @@ org.springframework.boot spring-boot-maven-plugin - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - 3 - true - - **/*IntegrationTest.java - **/*IntTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - **/JdbcTest.java - **/*LiveTest.java - - - - - UTF-8 - UTF-8 - 1.8 3.4.1 diff --git a/testing-modules/gatling/pom.xml b/testing-modules/gatling/pom.xml index 1e134ad1a3..8d4c89ec62 100644 --- a/testing-modules/gatling/pom.xml +++ b/testing-modules/gatling/pom.xml @@ -7,13 +7,13 @@ gatling 1.0-SNAPSHOT - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ - - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + io.gatling.highcharts @@ -76,21 +76,24 @@ simulation - - io.gatling - gatling-maven-plugin - ${gatling-maven-plugin.version} - - - test - - execute - - - - - - + + io.gatling + gatling-maven-plugin + ${gatling-maven-plugin.version} + + + test + + execute + + + true + + + + + + @@ -123,10 +126,10 @@ 1.8 1.8 UTF-8 - 2.11.12 - 2.2.5 + 2.12.6 + 2.3.1 3.2.2 - 2.2.1 + 2.2.4 diff --git a/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java b/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java new file mode 100644 index 0000000000..d545daf0df --- /dev/null +++ b/testing-modules/spring-testing/src/main/java/com/baeldung/testpropertysource/ClassUsingProperty.java @@ -0,0 +1,15 @@ +package com.baeldung.testpropertysource; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class ClassUsingProperty { + + @Value("${baeldung.testpropertysource.one}") + private String propertyOne; + + public String retrievePropertyOne() { + return propertyOne; + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..f983abdd54 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource +public class DefaultTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("default-value"); + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..93d4cc58da --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/LocationTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource(locations = "/other-location.properties") +public class LocationTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("other-location-value"); + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java new file mode 100644 index 0000000000..d98e2b9f98 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/testpropertysource/PropertiesTestPropertySourceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.testpropertysource; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ClassUsingProperty.class) +@TestPropertySource(locations = "/other-location.properties", properties = "baeldung.testpropertysource.one=other-properties-value") +public class PropertiesTestPropertySourceIntegrationTest { + + @Autowired + ClassUsingProperty classUsingProperty; + + @Test + public void givenDefaultTestPropertySource_whenVariableOneRetrieved_thenValueInDefaultFileReturned() { + String output = classUsingProperty.retrievePropertyOne(); + + assertThat(output).isEqualTo("other-properties-value"); + } +} diff --git a/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties b/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties new file mode 100644 index 0000000000..a443a2b776 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/com/baeldung/testpropertysource/DefaultTestPropertySourceIntegrationTest.properties @@ -0,0 +1 @@ +baeldung.testpropertysource.one=default-value \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/resources/other-location.properties b/testing-modules/spring-testing/src/test/resources/other-location.properties new file mode 100644 index 0000000000..6ef791ec75 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/other-location.properties @@ -0,0 +1 @@ +baeldung.testpropertysource.one=other-location-value \ No newline at end of file diff --git a/twilio/pom.xml b/twilio/pom.xml index 8683192b5c..610cc04b60 100644 --- a/twilio/pom.xml +++ b/twilio/pom.xml @@ -2,11 +2,15 @@ 4.0.0 - - com.baeldung twilio 1.0-SNAPSHOT + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + com.twilio.sdk @@ -15,9 +19,4 @@ - - 1.8 - 1.8 - -