diff --git a/algorithms/README.md b/algorithms/README.md index b0c5ee9d77..5f101c296c 100644 --- a/algorithms/README.md +++ b/algorithms/README.md @@ -14,3 +14,4 @@ - [Bubble Sort in Java](http://www.baeldung.com/java-bubble-sort) - [Introduction to JGraphT](http://www.baeldung.com/jgrapht) - [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm) +- [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance) diff --git a/apache-spark/README.md b/apache-spark/README.md new file mode 100644 index 0000000000..fb8059eb27 --- /dev/null +++ b/apache-spark/README.md @@ -0,0 +1,3 @@ +### Relevant articles + +- [Introduction to Apache Spark](http://www.baeldung.com/apache-spark) diff --git a/cas/cas-secured-app/pom.xml b/cas/cas-secured-app/pom.xml index f66d54ae67..543354e8b3 100644 --- a/cas/cas-secured-app/pom.xml +++ b/cas/cas-secured-app/pom.xml @@ -65,6 +65,24 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + @@ -107,4 +125,5 @@ + diff --git a/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationTests.java b/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java similarity index 84% rename from cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationTests.java rename to cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java index 09dbaf0c61..2f2644e2ea 100644 --- a/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationTests.java +++ b/cas/cas-secured-app/src/test/java/com/baeldung/cassecuredapp/CasSecuredAppApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class CasSecuredAppApplicationTests { +public class CasSecuredAppApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/cas/cas-server/src/main/resources/application.properties b/cas/cas-server/src/main/resources/application.properties index afacd4cbc1..018fd351ff 100644 --- a/cas/cas-server/src/main/resources/application.properties +++ b/cas/cas-server/src/main/resources/application.properties @@ -109,7 +109,7 @@ cas.authn.jdbc.query[0].sql=SELECT * FROM users WHERE email = ? cas.authn.jdbc.query[0].url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC cas.authn.jdbc.query[0].dialect=org.hibernate.dialect.MySQLDialect cas.authn.jdbc.query[0].user=root -cas.authn.jdbc.query[0].password= +cas.authn.jdbc.query[0].password=root cas.authn.jdbc.query[0].ddlAuto=none #cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver diff --git a/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql b/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql new file mode 100644 index 0000000000..79a4a48a82 --- /dev/null +++ b/cas/cas-server/src/main/resources/create_test_db_and_users_tbl.sql @@ -0,0 +1,16 @@ +-- Dumping database structure for test +CREATE DATABASE IF NOT EXISTS `test` /*!40100 DEFAULT CHARACTER SET latin1 */; +USE `test`; + +-- Dumping structure for table test.users +CREATE TABLE IF NOT EXISTS `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `email` varchar(50) DEFAULT NULL, + `password` text DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1; + +/*!40000 ALTER TABLE `users` DISABLE KEYS */; +INSERT INTO `users` (`id`, `email`, `password`) VALUES + (1, 'test@test.com', 'Mellon'); +/*!40000 ALTER TABLE `users` ENABLE KEYS */; \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java new file mode 100644 index 0000000000..034e6785a4 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithAnnotation.java @@ -0,0 +1,5 @@ +package com.baeldung.annotations; + +@Deprecated +class ClassWithAnnotation { +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java new file mode 100644 index 0000000000..6f5da03b74 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithDeprecatedMethod.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class ClassWithDeprecatedMethod { + + @Deprecated + static void deprecatedMethod() { + + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java new file mode 100644 index 0000000000..cfa91f5951 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSafeVarargs.java @@ -0,0 +1,11 @@ +package com.baeldung.annotations; + +class ClassWithSafeVarargs { + + @SafeVarargs + final void iterateOverVarargs(T... args) { + for (T x : args) { + // do stuff with x + } + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java new file mode 100644 index 0000000000..fe22ec1c24 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/ClassWithSuppressWarnings.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class ClassWithSuppressWarnings { + + @SuppressWarnings("deprecation") + void useDeprecatedMethod() { + ClassWithDeprecatedMethod.deprecatedMethod(); // no warning is generated here + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java b/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java new file mode 100644 index 0000000000..4f16b27281 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/IntConsumer.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +@FunctionalInterface +interface IntConsumer { + + void accept(Integer number); + +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/Interval.java b/core-java-8/src/main/java/com/baeldung/annotations/Interval.java new file mode 100644 index 0000000000..f73e6e5b14 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/Interval.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import java.lang.annotation.Repeatable; + +@Repeatable(Intervals.class) +@interface Interval { + int hour() default 1; +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java b/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java new file mode 100644 index 0000000000..2e11de8215 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/IntervalUsage.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +public class IntervalUsage { + + @Interval(hour = 17) + @Interval(hour = 13) + void doPeriodicCleanup() { + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java b/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java new file mode 100644 index 0000000000..af469f18cc --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/Intervals.java @@ -0,0 +1,5 @@ +package com.baeldung.annotations; + +@interface Intervals { + Interval[] value(); +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java new file mode 100644 index 0000000000..6e71f446b0 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotation.java @@ -0,0 +1,11 @@ +package com.baeldung.annotations; + +import java.lang.annotation.*; + +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.LOCAL_VARIABLE, ElementType.FIELD}) +@interface MyAnnotation { + +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java new file mode 100644 index 0000000000..37f40a624e --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyAnnotationTarget.java @@ -0,0 +1,16 @@ +package com.baeldung.annotations; + +class MyAnnotationTarget { + + // this is OK + @MyAnnotation + String someField; + + // @MyAnnotation <- this is invalid usage! + void doSomething() { + + // this also works + @MyAnnotation + String localVariable; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java b/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java new file mode 100644 index 0000000000..a4385bc786 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyOperation.java @@ -0,0 +1,6 @@ +package com.baeldung.annotations; + +interface MyOperation { + + void perform(); +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java b/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java new file mode 100644 index 0000000000..e6a8ce76d3 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/annotations/MyOperationImpl.java @@ -0,0 +1,9 @@ +package com.baeldung.annotations; + +class MyOperationImpl implements MyOperation { + + @Override + public void perform() { + + } +} \ No newline at end of file diff --git a/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateConverter.java b/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateConverter.java new file mode 100644 index 0000000000..8788aac747 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateConverter.java @@ -0,0 +1,35 @@ +/** + * + */ +package com.baeldung.datetime; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.util.Date into java.time.LocalDate. + * + * @author abialas + * + */ +public class DateToLocalDateConverter { + + public static LocalDate convertToLocalDateViaInstant(Date dateToConvert) { + return dateToConvert.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + } + + public static LocalDate convertToLocalDateViaSqlDate(Date dateToConvert) { + return new java.sql.Date(dateToConvert.getTime()).toLocalDate(); + } + + public static LocalDate convertToLocalDateViaMilisecond(Date dateToConvert) { + return Instant.ofEpochMilli(dateToConvert.getTime()) + .atZone(ZoneId.systemDefault()) + .toLocalDate(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateTimeConverter.java b/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateTimeConverter.java new file mode 100644 index 0000000000..f994023526 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/DateToLocalDateTimeConverter.java @@ -0,0 +1,35 @@ +/** + * + */ +package com.baeldung.datetime; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.util.Date into java.time.LocalDateTime. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverter { + + public static LocalDateTime convertToLocalDateTimeViaInstant(Date dateToConvert) { + return dateToConvert.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + + public static LocalDateTime convertToLocalDateTimeViaSqlTimestamp(Date dateToConvert) { + return new java.sql.Timestamp(dateToConvert.getTime()).toLocalDateTime(); + } + + public static LocalDateTime convertToLocalDateTimeViaMilisecond(Date dateToConvert) { + return Instant.ofEpochMilli(dateToConvert.getTime()) + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/datetime/LocalDateTimeToDateConverter.java b/core-java-8/src/main/java/com/baeldung/datetime/LocalDateTimeToDateConverter.java new file mode 100644 index 0000000000..ef72c8b4fb --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/LocalDateTimeToDateConverter.java @@ -0,0 +1,27 @@ +/** + * + */ +package com.baeldung.datetime; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.time.LocalDateTime into java.util.Date. + * + * @author abialas + * + */ +public class LocalDateTimeToDateConverter { + + public static Date convertToDateViaSqlTimestamp(LocalDateTime dateToConvert) { + return java.sql.Timestamp.valueOf(dateToConvert); + } + + public static Date convertToDateViaInstant(LocalDateTime dateToConvert) { + return java.util.Date.from(dateToConvert.atZone(ZoneId.systemDefault()) + .toInstant()); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/datetime/LocalDateToDateConverter.java b/core-java-8/src/main/java/com/baeldung/datetime/LocalDateToDateConverter.java new file mode 100644 index 0000000000..8050815799 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/datetime/LocalDateToDateConverter.java @@ -0,0 +1,28 @@ +/** + * + */ +package com.baeldung.datetime; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows different ways of converting java.time.LocalDate into java.util.Date. + * + * @author abialas + * + */ +public class LocalDateToDateConverter { + + public static Date convertToDateViaSqlDate(LocalDate dateToConvert) { + return java.sql.Date.valueOf(dateToConvert); + } + + public static Date convertToDateViaInstant(LocalDate dateToConvert) { + return java.util.Date.from(dateToConvert.atStartOfDay() + .atZone(ZoneId.systemDefault()) + .toInstant()); + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java new file mode 100644 index 0000000000..3a1016c63b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java @@ -0,0 +1,55 @@ +package com.baeldung.timezonedisplay; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class TimezoneDisplay { + + public enum OffsetBase { + GMT, UTC + } + + public List getTimeZoneList(OffsetBase base) { + Set availableZoneIds = ZoneId.getAvailableZoneIds(); + + LocalDateTime now = LocalDateTime.now(); + return availableZoneIds + .stream() + .map(ZoneId::of) + .sorted(new ZoneComparator()) + .map(id -> String.format("(%s%s) %s", base, getOffset(now, id), id.getId())) + .collect(Collectors.toList()); + } + + private String getOffset(LocalDateTime dateTime, ZoneId id) { + return dateTime + .atZone(id) + .getOffset() + .getId() + .replace("Z", "+00:00"); + } + + private class ZoneComparator implements Comparator { + + @Override + public int compare(ZoneId zoneId1, ZoneId zoneId2) { + LocalDateTime now = LocalDateTime.now(); + + ZoneOffset offset1 = now + .atZone(zoneId1) + .getOffset(); + + ZoneOffset offset2 = now + .atZone(zoneId2) + .getOffset(); + + return offset1.compareTo(offset2); + } + } + +} diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java new file mode 100644 index 0000000000..aa9f84e21a --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java @@ -0,0 +1,18 @@ +package com.baeldung.timezonedisplay; + +import java.util.List; + +public class TimezoneDisplayApp { + + public static void main(String... args) { + TimezoneDisplay display = new TimezoneDisplay(); + + System.out.println("Time zones in UTC:"); + List utc = display.getTimeZoneList(TimezoneDisplay.OffsetBase.UTC); + utc.forEach(System.out::println); + + System.out.println("Time zones in GMT:"); + List gmt = display.getTimeZoneList(TimezoneDisplay.OffsetBase.GMT); + gmt.forEach(System.out::println); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateConverterTest.java b/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateConverterTest.java new file mode 100644 index 0000000000..5de6ae3e59 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateConverterTest.java @@ -0,0 +1,72 @@ +/** + * + */ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link DateToLocalDateConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateConverterTest { + + @Test + public void shouldReturn10thNovember2010WhenConvertViaInstant() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaInstant(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaMiliseconds() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaMilisecond(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlDate() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDate = DateToLocalDateConverter.convertToLocalDateViaSqlDate(dateToConvert); + + // then + assertEquals(2010, localDate.get(ChronoField.YEAR)); + assertEquals(11, localDate.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDate.get(ChronoField.DAY_OF_MONTH)); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateTimeConverterTest.java b/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateTimeConverterTest.java new file mode 100644 index 0000000000..6d8fb8ea93 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/DateToLocalDateTimeConverterTest.java @@ -0,0 +1,78 @@ +/** + * + */ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link DateToLocalDateTimeConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverterTest { + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaInstant(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaMiliseconds() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaMilisecond(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaSqlTimestamp() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTimeViaSqlTimestamp(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/LocalDateTimeToDateConverterTest.java b/core-java-8/src/test/java/com/baeldung/datetime/LocalDateTimeToDateConverterTest.java new file mode 100644 index 0000000000..519fa69f04 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/LocalDateTimeToDateConverterTest.java @@ -0,0 +1,61 @@ +/** + * + */ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDateTime; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link LocalDateTimeToDateConverter} class. + * + * @author abialas + * + */ +public class LocalDateTimeToDateConverterTest { + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { + // given + LocalDateTime dateToConvert = LocalDateTime.of(2010, 11, 10, 8, 20); + + // when + Date date = LocalDateTimeToDateConverter.convertToDateViaInstant(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(8, calendar.get(Calendar.HOUR)); + assertEquals(20, calendar.get(Calendar.MINUTE)); + assertEquals(0, calendar.get(Calendar.SECOND)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlTimestamp() { + // given + LocalDateTime dateToConvert = LocalDateTime.of(2010, 11, 10, 8, 20); + + // when + Date date = LocalDateTimeToDateConverter.convertToDateViaSqlTimestamp(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + assertEquals(8, calendar.get(Calendar.HOUR)); + assertEquals(20, calendar.get(Calendar.MINUTE)); + assertEquals(0, calendar.get(Calendar.SECOND)); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/datetime/LocalDateToDateConverterTest.java b/core-java-8/src/test/java/com/baeldung/datetime/LocalDateToDateConverterTest.java new file mode 100644 index 0000000000..c1da3af052 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/datetime/LocalDateToDateConverterTest.java @@ -0,0 +1,55 @@ +/** + * + */ +package com.baeldung.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +/** + * + * JUnits for {@link LocalDateToDateConverter} class. + * + * @author abialas + * + */ +public class LocalDateToDateConverterTest { + + @Test + public void shouldReturn10thNovember2010WhenConvertViaInstant() { + // given + LocalDate dateToConvert = LocalDate.of(2010, 11, 10); + + // when + Date date = LocalDateToDateConverter.convertToDateViaInstant(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + } + + @Test + public void shouldReturn10thNovember2010WhenConvertViaSqlDate() { + // given + LocalDate dateToConvert = LocalDate.of(2010, 11, 10); + + // when + Date date = LocalDateToDateConverter.convertToDateViaSqlDate(dateToConvert); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + + // then + assertEquals(2010, calendar.get(Calendar.YEAR)); + assertEquals(10, calendar.get(Calendar.MONTH)); + assertEquals(10, calendar.get(Calendar.DAY_OF_MONTH)); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java new file mode 100644 index 0000000000..bafa9ebff1 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java @@ -0,0 +1,22 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows a way to convert java.util.Date into java.time.LocalDate with new Java 1.9. + * + * @author abialas + * + */ +public class DateToLocalDateConverter { + + public static LocalDate convertToLocalDate(Date dateToConvert) { + return LocalDate.ofInstant(dateToConvert.toInstant(), ZoneId.systemDefault()); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java new file mode 100644 index 0000000000..538d5a9f63 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java @@ -0,0 +1,22 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * Class which shows a way to convert java.util.Date into java.time.LocalDateTime with new Java 1.9. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverter { + + public static LocalDateTime convertToLocalDateTime(Date dateToConvert) { + return LocalDateTime.ofInstant(dateToConvert.toInstant(), ZoneId.systemDefault()); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java new file mode 100644 index 0000000000..2e0fb0dedd --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java @@ -0,0 +1,41 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDate; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +import com.baeldung.java9.datetime.DateToLocalDateConverter; + +/** + * JUnits for {@link DateToLocalDateConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateConverterTest { + + @Test + public void shouldReturn10thNovember2010WhenConvertToLocalDate() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10); + Date dateToConvert = calendar.getTime(); + + // when + LocalDate localDateTime = DateToLocalDateConverter.convertToLocalDate(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + } + +} diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java new file mode 100644 index 0000000000..49988c8b33 --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java @@ -0,0 +1,43 @@ +/** + * + */ +package com.baeldung.java9.datetime; + +import static org.junit.Assert.assertEquals; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.Date; + +import org.junit.Test; + +import com.baeldung.java9.datetime.DateToLocalDateTimeConverter; + +/** + * JUnits for {@link DateToLocalDateTimeConverter} class. + * + * @author abialas + * + */ +public class DateToLocalDateTimeConverterTest { + + @Test + public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() { + // given + Calendar calendar = Calendar.getInstance(); + calendar.set(2010, 10, 10, 8, 20); + Date dateToConvert = calendar.getTime(); + + // when + LocalDateTime localDateTime = DateToLocalDateTimeConverter.convertToLocalDateTime(dateToConvert); + + // then + assertEquals(2010, localDateTime.get(ChronoField.YEAR)); + assertEquals(11, localDateTime.get(ChronoField.MONTH_OF_YEAR)); + assertEquals(10, localDateTime.get(ChronoField.DAY_OF_MONTH)); + assertEquals(8, localDateTime.get(ChronoField.HOUR_OF_DAY)); + assertEquals(20, localDateTime.get(ChronoField.MINUTE_OF_HOUR)); + } + +} diff --git a/core-java-concurrency/README.md b/core-java-concurrency/README.md index f1d95482d4..48c5f2a50c 100644 --- a/core-java-concurrency/README.md +++ b/core-java-concurrency/README.md @@ -30,3 +30,4 @@ - [Guide to Volatile Keyword in Java](http://www.baeldung.com/java-volatile) - [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent) - [Semaphores in Java](http://www.baeldung.com/java-semaphore) +- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread) diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java new file mode 100644 index 0000000000..0e72821a88 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/stopping/ControlSubThread.java @@ -0,0 +1,52 @@ +package com.baeldung.concurrent.stopping; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class ControlSubThread implements Runnable { + + private Thread worker; + private int interval = 100; + private AtomicBoolean running = new AtomicBoolean(false); + private AtomicBoolean stopped = new AtomicBoolean(true); + + + public ControlSubThread(int sleepInterval) { + interval = sleepInterval; + } + + public void start() { + worker = new Thread(this); + worker.start(); + } + + public void stop() { + running.set(false); + } + + public void interrupt() { + running.set(false); + worker.interrupt(); + } + + boolean isRunning() { + return running.get(); + } + + boolean isStopped() { + return stopped.get(); + } + + public void run() { + running.set(true); + stopped.set(false); + while (running.get()) { + try { + Thread.sleep(interval); + } catch (InterruptedException e) { + // no-op, just loop again + } + // do something + } + stopped.set(true); + } +} diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java new file mode 100644 index 0000000000..8c1bdbf787 --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/stopping/StopThreadTest.java @@ -0,0 +1,50 @@ +package com.baeldung.concurrent.stopping; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class StopThreadTest { + + @Test + public void whenStoppedThreadIsStopped() throws InterruptedException { + + int interval = 100; + + ControlSubThread controlSubThread = new ControlSubThread(interval); + controlSubThread.start(); + + // Give things a chance to get set up + Thread.sleep(interval); + assertTrue(controlSubThread.isRunning()); + assertFalse(controlSubThread.isStopped()); + + // Stop it and make sure the flags have been reversed + controlSubThread.stop(); + Thread.sleep(interval); + assertTrue(controlSubThread.isStopped()); + } + + + @Test + public void whenInterruptedThreadIsStopped() throws InterruptedException { + + int interval = 5000; + + ControlSubThread controlSubThread = new ControlSubThread(interval); + controlSubThread.start(); + + // Give things a chance to get set up + Thread.sleep(100); + assertTrue(controlSubThread.isRunning()); + assertFalse(controlSubThread.isStopped()); + + // Stop it and make sure the flags have been reversed + controlSubThread.interrupt(); + + // Wait less than the time we would normally sleep, and make sure we exited. + Thread.sleep(interval/10); + assertTrue(controlSubThread.isStopped()); + } +} diff --git a/core-java/README.md b/core-java/README.md index b4b8d9062e..14058474a1 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -114,4 +114,8 @@ - [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) - [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int) - [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns) +- [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) +- [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static) +- [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) +- [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) diff --git a/core-java/pom.xml b/core-java/pom.xml index dbf61c3acf..77000b8741 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -460,7 +460,7 @@ 1.1.7 - 22.0 + 23.0 3.5 1.55 1.10 diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java new file mode 100644 index 0000000000..46d97d1a15 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface AbstractFactory { + Animal getAnimal(String toyType) ; + Color getColor(String colorType); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java new file mode 100644 index 0000000000..7ab166e16a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java @@ -0,0 +1,18 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class AbstractPatternDriver { + public static void main(String[] args) { + AbstractFactory abstractFactory; + + //creating a brown toy dog + abstractFactory = FactoryProvider.getFactory("Toy"); + Animal toy = abstractFactory.getAnimal("Dog"); + + abstractFactory = FactoryProvider.getFactory("Color"); + Color color = abstractFactory.getColor("Brown"); + + String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound(); + + System.out.println(result); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java new file mode 100644 index 0000000000..59c1336053 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java @@ -0,0 +1,6 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface Animal { + String getType(); + String makeSound(); +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java new file mode 100644 index 0000000000..49583c3a98 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java @@ -0,0 +1,21 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class AnimalFactory implements AbstractFactory { + + @Override + public Animal getAnimal(String animalType) { + if ("Dog".equalsIgnoreCase(animalType)) { + return new Dog(); + } else if ("Duck".equalsIgnoreCase(animalType)) { + return new Duck(); + } + + return null; + } + + @Override + public Color getColor(String color) { + throw new UnsupportedOperationException(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java new file mode 100644 index 0000000000..f251285ebf --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Brown implements Color { + + @Override + public String getColor() { + return "brown"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java new file mode 100644 index 0000000000..897bb71f38 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java @@ -0,0 +1,5 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public interface Color { + String getColor(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java new file mode 100644 index 0000000000..8f7559ff27 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java @@ -0,0 +1,21 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class ColorFactory implements AbstractFactory { + + @Override + public Color getColor(String colorType) { + if ("Brown".equalsIgnoreCase(colorType)) { + return new Brown(); + } else if ("White".equalsIgnoreCase(colorType)) { + return new White(); + } + + return null; + } + + @Override + public Animal getAnimal(String toyType) { + throw new UnsupportedOperationException(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java new file mode 100644 index 0000000000..002b5665d3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Dog implements Animal { + + @Override + public String getType() { + return "Dog"; + } + + @Override + public String makeSound() { + return "Barks"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java new file mode 100644 index 0000000000..5603ad6eee --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class Duck implements Animal { + + @Override + public String getType() { + return "Duck"; + } + + @Override + public String makeSound() { + return "Squeks"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java new file mode 100644 index 0000000000..fcbee1e6de --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java @@ -0,0 +1,15 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class FactoryProvider { + public static AbstractFactory getFactory(String choice){ + + if("Toy".equalsIgnoreCase(choice)){ + return new AnimalFactory(); + } + else if("Color".equalsIgnoreCase(choice)){ + return new ColorFactory(); + } + + return null; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java new file mode 100644 index 0000000000..62ef8048ea --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +public class White implements Color { + + @Override + public String getColor() { + return "White"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java new file mode 100644 index 0000000000..355fa74895 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java @@ -0,0 +1,64 @@ +package com.baeldung.designpatterns.creational.builder; + +public class BankAccount { + private String name; + private String accountNumber; + private String email; + private boolean newsletter; + + //The constructor that takes a builder from which it will create object + //the access to this is only provided to builder + private BankAccount(BankAccountBuilder builder) { + this.name = builder.name; + this.accountNumber = builder.accountNumber; + this.email = builder.email; + this.newsletter = builder.newsletter; + } + + public static class BankAccountBuilder { + private String name; + private String accountNumber; + private String email; + private boolean newsletter; + + //All Mandatory parameters goes with this constructor + public BankAccountBuilder(String name, String accountNumber) { + this.name = name; + this.accountNumber = accountNumber; + } + + //setters for optional parameters which returns this same builder + //to support fluent design + public BankAccountBuilder withEmail(String email) { + this.email = email; + return this; + } + + public BankAccountBuilder wantNewsletter(boolean newsletter) { + this.newsletter = newsletter; + return this; + } + + //the actual build method that prepares and returns a BankAccount object + public BankAccount build() { + return new BankAccount(this); + } + } + + //getters + public String getName() { + return name; + } + + public String getAccountNumber() { + return accountNumber; + } + + public String getEmail() { + return email; + } + + public boolean isNewsletter() { + return newsletter; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java new file mode 100644 index 0000000000..d92a70e664 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java @@ -0,0 +1,16 @@ +package com.baeldung.designpatterns.creational.builder; + +public class BuilderPatternDriver { + public static void main(String[] args) { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .withEmail("jon@example.com") + .wantNewsletter(true) + .build(); + + System.out.println("Name: " + newAccount.getName()); + System.out.println("AccountNumber:" + newAccount.getAccountNumber()); + System.out.println("Email: " + newAccount.getEmail()); + System.out.println("Want News letter?: " + newAccount.isNewsletter()); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java new file mode 100644 index 0000000000..64ee307bb8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java @@ -0,0 +1,16 @@ +package com.baeldung.designpatterns.creational.factory; + +public class FactoryDriver { + public static void main(String[] args) { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(4); + System.out.println("The shape with 4 sides is a " + p.getType()); + + //get the shape which has 4 sides + p = factory.getPolygon(8); + System.out.println("The shape with 8 sides is a " + p.getType()); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java new file mode 100644 index 0000000000..935fc2f04c --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Heptagon implements Polygon { + + @Override + public String getType() { + return "Heptagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java new file mode 100644 index 0000000000..fc62302dc8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Octagon implements Polygon { + + @Override + public String getType() { + return "Octagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java new file mode 100644 index 0000000000..65d109b10b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Pentagon implements Polygon { + + @Override + public String getType() { + return "Pentagon"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java new file mode 100644 index 0000000000..8364e546b0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java @@ -0,0 +1,5 @@ +package com.baeldung.designpatterns.creational.factory; + +public interface Polygon { + String getType(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java new file mode 100644 index 0000000000..406f0f5274 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java @@ -0,0 +1,22 @@ +package com.baeldung.designpatterns.creational.factory; + +public class PolygonFactory { + public Polygon getPolygon(int numberOfSides) { + if(numberOfSides == 3) { + return new Triangle(); + } + if(numberOfSides == 4) { + return new Square(); + } + if(numberOfSides == 5) { + return new Pentagon(); + } + if(numberOfSides == 4) { + return new Heptagon(); + } + else if(numberOfSides == 8) { + return new Octagon(); + } + return null; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java new file mode 100644 index 0000000000..805c1c9ae3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Square implements Polygon { + + @Override + public String getType() { + return "Square"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java new file mode 100644 index 0000000000..8a8832d8a1 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java @@ -0,0 +1,10 @@ +package com.baeldung.designpatterns.creational.factory; + +public class Triangle implements Polygon { + + @Override + public String getType() { + return "Triangle"; + } + +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java new file mode 100644 index 0000000000..1a5ac82c89 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java @@ -0,0 +1,13 @@ +package com.baeldung.designpatterns.creational.singleton; + +public class Singleton { + private Singleton() {} + + private static class SingletonHolder { + public static final Singleton instance = new Singleton(); + } + + public static Singleton getInstance() { + return SingletonHolder.instance; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java new file mode 100644 index 0000000000..1955008d3e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java @@ -0,0 +1,8 @@ +package com.baeldung.designpatterns.creational.singleton; + +public class SingletonDriver { + public static void main(String[] args) { + Singleton instance = Singleton.getInstance(); + System.out.println(instance.toString()); + } +} diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java new file mode 100644 index 0000000000..4882ebe175 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java @@ -0,0 +1,43 @@ +package com.baeldung.timezonedisplay; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +public class TimezoneDisplayJava7 { + + public enum OffsetBase { + GMT, UTC + } + + public List getTimeZoneList(TimezoneDisplayJava7.OffsetBase base) { + String[] availableZoneIds = TimeZone.getAvailableIDs(); + List result = new ArrayList<>(availableZoneIds.length); + + for (String zoneId : availableZoneIds) { + TimeZone curTimeZone = TimeZone.getTimeZone(zoneId); + + String offset = calculateOffset(curTimeZone.getRawOffset()); + + result.add(String.format("(%s%s) %s", base, offset, zoneId)); + } + + Collections.sort(result); + + return result; + } + + private String calculateOffset(int rawOffset) { + if (rawOffset == 0) { + return "+00:00"; + } + long hours = TimeUnit.MILLISECONDS.toHours(rawOffset); + long minutes = TimeUnit.MILLISECONDS.toMinutes(rawOffset); + minutes = Math.abs(minutes - TimeUnit.HOURS.toMinutes(hours)); + + return String.format("%+03d:%02d", hours, Math.abs(minutes)); + } + +} diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java new file mode 100644 index 0000000000..9f20667660 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java @@ -0,0 +1,23 @@ +package com.baeldung.timezonedisplay; + +import java.util.List; + +public class TimezoneDisplayJava7App { + + public static void main(String... args) { + TimezoneDisplayJava7 display = new TimezoneDisplayJava7(); + + System.out.println("Time zones in UTC:"); + List utc = display.getTimeZoneList(TimezoneDisplayJava7.OffsetBase.UTC); + for (String timeZone : utc) { + System.out.println(timeZone); + } + + System.out.println("Time zones in GMT:"); + List gmt = display.getTimeZoneList(TimezoneDisplayJava7.OffsetBase.GMT); + for (String timeZone : gmt) { + System.out.println(timeZone); + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java b/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java new file mode 100644 index 0000000000..973436a26a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/copyfiles/FileCopierTest.java @@ -0,0 +1,70 @@ +package com.baeldung.copyfiles; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Test; +import static org.assertj.core.api.Assertions.*; + +public class FileCopierTest { + File original = new File("src/test/resources/original.txt"); + + @Before + public void init() throws IOException { + if (!original.exists()) + Files.createFile(original.toPath()); + } + + @Test + public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithIo.txt"); + try (InputStream in = new BufferedInputStream(new FileInputStream(original)); + OutputStream out = new BufferedOutputStream(new FileOutputStream(copied))) { + byte[] buffer = new byte[1024]; + int lengthRead; + while ((lengthRead = in.read(buffer)) > 0) { + out.write(buffer, 0, lengthRead); + out.flush(); + } + } + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } + + @Test + public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + FileUtils.copyFile(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } + + @Test + public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException { + Path copied = Paths.get("src/test/resources/copiedWithNio.txt"); + Path originalPath = original.toPath(); + Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING); + assertThat(copied).exists(); + assertThat(Files.readAllLines(originalPath).equals(Files.readAllLines(copied))); + } + + @Test + public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException { + File copied = new File("src/test/resources/copiedWithApacheCommons.txt"); + com.google.common.io.Files.copy(original, copied); + assertThat(copied).exists(); + assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath()))); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java new file mode 100644 index 0000000000..dc02b976a0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java @@ -0,0 +1,23 @@ +package com.baeldung.designpatterns.creational.abstractfactory; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class AbstractPatternIntegrationTest { + @Test + public void givenAbstractFactory_whenGettingObjects_thenSuccessful() { + AbstractFactory abstractFactory; + + //creating a brown toy dog + abstractFactory = FactoryProvider.getFactory("Toy"); + Animal toy = abstractFactory.getAnimal("Dog"); + + abstractFactory = FactoryProvider.getFactory("Color"); + Color color = abstractFactory.getColor("Brown"); + + String result = "A " + toy.getType() + " with " + color.getColor() + " color " + toy.makeSound(); + assertEquals("A Dog with brown color Barks", result); + } + +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java new file mode 100644 index 0000000000..898330b26e --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.designpatterns.creational.builder; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BuilderPatternIntegrationTest { + @Test + public void whenCreatingObjectThroughBuilder_thenObjectValid() { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .withEmail("jon@example.com") + .wantNewsletter(true) + .build(); + + assertEquals(newAccount.getName(), "Jon"); + assertEquals(newAccount.getAccountNumber(), "22738022275"); + assertEquals(newAccount.getEmail(), "jon@example.com"); + assertEquals(newAccount.isNewsletter(), true); + } + + @Test + public void whenSkippingOptionalParameters_thenObjectValid() { + BankAccount newAccount = new BankAccount + .BankAccountBuilder("Jon", "22738022275") + .build(); + + assertEquals(newAccount.getName(), "Jon"); + assertEquals(newAccount.getAccountNumber(), "22738022275"); + assertEquals(newAccount.getEmail(), null); + assertEquals(newAccount.isNewsletter(), false); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java new file mode 100644 index 0000000000..ed0419c16d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java @@ -0,0 +1,32 @@ +package com.baeldung.designpatterns.creational.factory; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class FactoryIntegrationTest { + + @Test + public void whenUsingFactoryForSquare_thenCorrectObjectReturned() { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(4); + String result = "The shape with 4 sides is a " + p.getType(); + + assertEquals("The shape with 4 sides is a Square", result); + } + + @Test + public void whenUsingFactoryForOctagon_thenCorrectObjectReturned() { + Polygon p; + PolygonFactory factory = new PolygonFactory(); + + //get the shape which has 4 sides + p = factory.getPolygon(8); + String result = "The shape with 8 sides is a " + p.getType(); + + assertEquals("The shape with 8 sides is a Octagon", result); + } +} diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java new file mode 100644 index 0000000000..a3d5b7a14d --- /dev/null +++ b/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.designpatterns.creational.singleton; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class SingletonIntegrationTest { + + @Test + /** + * Although there is absolutely no way to determine whether + * a class is Singleton, in this test case, we will just + * check for two objects if they point to same instance or + * not. We will also check for their hashcode. + */ + public void whenGettingMultipleObjects_thenAllPointToSame() { + //first object + Singleton obj1 = Singleton.getInstance(); + + //Second object + Singleton obj2 = Singleton.getInstance(); + + assertTrue(obj1 == obj2); + assertEquals(obj1.hashCode(), obj2.hashCode()); + } + +} diff --git a/core-java/src/test/resources/original.txt b/core-java/src/test/resources/original.txt new file mode 100644 index 0000000000..cf8c89d389 --- /dev/null +++ b/core-java/src/test/resources/original.txt @@ -0,0 +1,2 @@ +#Copy a File with Java (www.Baeldung.com) +Copying Files with Java is Fun! \ No newline at end of file diff --git a/deeplearning4j/README.md b/deeplearning4j/README.md index 729ab101fd..7f9c92ec73 100644 --- a/deeplearning4j/README.md +++ b/deeplearning4j/README.md @@ -2,4 +2,4 @@ This is a sample project for the [deeplearning4j](https://deeplearning4j.org) library. ### Relevant Articles: -- [A Guide to deeplearning4j](http://www.baeldung.com/a-guide-to-deeplearning4j/) +- [A Guide to deeplearning4j](http://www.baeldung.com/deeplearning4j) diff --git a/drools/README.MD b/drools/README.MD index e3f00f5047..b2259e2878 100644 --- a/drools/README.MD +++ b/drools/README.MD @@ -1,4 +1,3 @@ ### Relevant Articles: - [Introduction to Drools](http://www.baeldung.com/drools) - [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel) -- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel) diff --git a/drools/pom.xml b/drools/pom.xml index 971bd5f4b8..5f228802fa 100644 --- a/drools/pom.xml +++ b/drools/pom.xml @@ -1,68 +1,87 @@ - 4.0.0 - - drools - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + drools + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + 4.4.6 - 7.1.0.Beta2 + 7.4.1.Final 3.13 - - - org.apache.httpcomponents - httpcore - ${http-component-version} - - - - org.kie - kie-ci - ${drools-version} - - - org.drools - drools-decisiontables - ${drools-version} - + + + org.apache.httpcomponents + httpcore + ${http-component-version} + + + + org.kie + kie-ci + ${drools-version} + + + org.drools + drools-decisiontables + ${drools-version} + - - org.drools - drools-core - ${drools-version} - - - org.drools - drools-compiler - ${drools-version} - - - org.apache.poi - poi - ${apache-poi-version} - + + org.drools + drools-core + ${drools-version} + + + org.drools + drools-compiler + ${drools-version} + + + org.apache.poi + poi + ${apache-poi-version} + - - org.apache.poi - poi-ooxml - ${apache-poi-version} - + + org.apache.poi + poi-ooxml + ${apache-poi-version} + - - org.springframework - spring-core - 4.3.6.RELEASE - + + org.springframework + spring-core + 4.3.6.RELEASE + - + - \ No newline at end of file + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + 3 + true + + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + **/JdbcTest.java + **/*LiveTest.java + + + + + + + diff --git a/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java index a27f0efe51..57376e9c4a 100644 --- a/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java +++ b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java @@ -26,16 +26,13 @@ public class TestEJBServlet extends HttpServlet { PrintWriter out = response.getWriter(); out.println(""); - out.println("Users"); out.println(""); - out.println("List of users:"); - out.println(""); for (User user : users) { - out.println(""); - out.print("" + user.getUsername() + ""); - out.print("" + user.getEmail() + ""); - out.println(""); + out.print(user.getUsername()); + out.print(" " + user.getEmail() + " "); } + out.println(""); + out.println(""); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { diff --git a/gradle/.gitignore b/gradle/.gitignore new file mode 100644 index 0000000000..da88288c09 --- /dev/null +++ b/gradle/.gitignore @@ -0,0 +1 @@ +/.gradle/ diff --git a/gradle/.travis.yml b/gradle/.travis.yml new file mode 100644 index 0000000000..b2b534799b --- /dev/null +++ b/gradle/.travis.yml @@ -0,0 +1,27 @@ +# More details on how to configure the Travis build +# https://docs.travis-ci.com/user/customizing-the-build/ + +# Speed up build with travis caches +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ + +language: java + +jdk: + - oraclejdk8 + +#Skipping install step to avoid having Travis run arbitrary './gradlew assemble' task +# https://docs.travis-ci.com/user/customizing-the-build/#Skipping-the-Installation-Step +install: + - true + +#Don't build tags +branches: + except: + - /^v\d/ + +#Build and perform release (if needed) +script: + - ./gradlew build -s && ./gradlew ciPerformRelease \ No newline at end of file diff --git a/gradle/build.gradle b/gradle/build.gradle index fc561987f7..dcc592a2b4 100644 --- a/gradle/build.gradle +++ b/gradle/build.gradle @@ -1,25 +1,35 @@ -apply plugin: 'java' -apply plugin: 'maven' - -repositories{ - mavenCentral() +allprojects { + repositories { + jcenter() + } } -dependencies{ - compile 'org.springframework:spring-context:4.3.5.RELEASE' -} -task hello { - println "this Baeldung's tutorial is ${awesomeness}" +subprojects { + + version = '1.0' } -uploadArchives { - repositories { - mavenDeployer { - repository(url: 'http://yourmavenrepo/repository') { - authentication(userName: 'user', password: 'password'); - } - - } - } +apply plugin: 'eclipse' + +println 'This will be executed during the configuration phase.' + +task configured { + println 'This will also be executed during the configuration phase.' +} + +task execFirstTest { + doLast { + println 'This will be executed during the execution phase.' + } +} + +task execSecondTest { + doFirst { + println 'This will be executed first during the execution phase.' + } + doLast { + println 'This will be executed last during the execution phase.' + } + println 'This will be executed during the configuration phase as well.' } diff --git a/gradle/gradle.properties b/gradle/gradle.properties deleted file mode 100644 index 41701e5a19..0000000000 --- a/gradle/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -awesomeness=awesome -group=com.baeldung.tutorial -version=1.0.1 diff --git a/gradle/gradle/shipkit.gradle b/gradle/gradle/shipkit.gradle new file mode 100644 index 0000000000..144c01dc05 --- /dev/null +++ b/gradle/gradle/shipkit.gradle @@ -0,0 +1,41 @@ +//This default Shipkit configuration file was created automatically and is intended to be checked-in. +//Default configuration is sufficient for local testing and trying out Shipkit. +//To leverage Shipkit fully, please fix the TODO items, refer to our Getting Started Guide for help: +// +// https://github.com/mockito/shipkit/blob/master/docs/getting-started.md +// +shipkit { + //TODO is the repository correct? + gitHub.repository = "unspecified-user/unspecified-repo" + + //TODO generate and use your own read-only GitHub personal access token + gitHub.readOnlyAuthToken = "76826c9ec886612f504d12fd4268b16721c4f85d" + + //TODO generate GitHub write token, and ensure your Travis CI has this env variable exported + gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") +} + +allprojects { + plugins.withId("com.jfrog.bintray") { + + //Bintray configuration is handled by JFrog Bintray Gradle Plugin + //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin + bintray { + + //TODO sign up for free open source account with https://bintray.com, then look up your API key on your profile page in Bintray + key = '7ea297848ca948adb7d3ee92a83292112d7ae989' + //TODO don't check in the key, remove above line and use env variable exported on CI: + //key = System.getenv("BINTRAY_API_KEY") + + pkg { + //TODO configure Bintray settings per your project (https://github.com/bintray/gradle-bintray-plugin) + repo = 'bootstrap' + user = 'shipkit-bootstrap-bot' + userOrg = 'shipkit-bootstrap' + name = 'maven' + licenses = ['MIT'] + labels = ['continuous delivery', 'release automation', 'shipkit'] + } + } + } +} diff --git a/gradle/gradle/wrapper/gradle-wrapper.jar b/gradle/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 3391a4cdf6..0000000000 Binary files a/gradle/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle/gradle/wrapper/gradle-wrapper.properties index b601d97764..ebf7ae9184 100644 --- a/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat Dec 31 15:46:08 BRT 2016 +#Thu Oct 12 16:43:02 BDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip diff --git a/gradle/gradletaskdemo/aplugin.gradle b/gradle/gradletaskdemo/aplugin.gradle new file mode 100644 index 0000000000..ca96c50b54 --- /dev/null +++ b/gradle/gradletaskdemo/aplugin.gradle @@ -0,0 +1,5 @@ +task fromPlugin { + doLast { + println "I'm from plugin" + } +} \ No newline at end of file diff --git a/gradle/gradletaskdemo/build.gradle b/gradle/gradletaskdemo/build.gradle new file mode 100644 index 0000000000..58dadd7460 --- /dev/null +++ b/gradle/gradletaskdemo/build.gradle @@ -0,0 +1,110 @@ +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.shipkit:shipkit:0.9.117" + } +} + + +plugins { + id 'java' +} + + +apply from: 'aplugin.gradle' +apply plugin: 'org.shipkit.bintray-release' + + +//hello task +task hello { + doLast { + println 'Baeldung' + } +} + +//Groovy in gradle task +task toLower { + doLast { + String someString = 'HELLO FROM BAELDUNG' + println "Original: " + someString + println "Lower case: " + someString.toLowerCase() + } +} + + +// Task dependencies +task helloGradle { + doLast { + println 'Hello Gradle!' + } +} + +task fromBaeldung(dependsOn: helloGradle) { + doLast { + println "I'm from Baeldung" + } +} + + +//Adding behavior to a task via api +task helloBaeldung { + doLast { + println 'I will be executed second' + } +} + +helloBaeldung.doFirst { + println 'I will be executed first' +} + +helloBaeldung.doLast { + println 'I will be executed third' +} + +helloBaeldung { + doLast { + println 'I will be executed fourth' + } +} + + + + +//Adding extra task properties +task ourTask { + ext.theProperty = "theValue" +} + +task printTaskProperty { + doLast { + println ourTask.theProperty + } +} + + + +//Declaring dependencies +dependencies { + compile group: + 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE' + compile 'org.springframework:spring-core:4.3.5.RELEASE', + 'org.springframework:spring-aop:4.3.5.RELEASE' + compile( + [group: 'org.springframework', name: 'spring-core', version: '4.3.5.RELEASE'], + [group: 'org.springframework', name: 'spring-aop', version: '4.3.5.RELEASE'] + ) + testCompile('org.hibernate:hibernate-core:5.2.12.Final') { + transitive = true + } + runtime(group: 'org.hibernate', name: 'hibernate-core', version: '5.2.12.Final') { + transitive = false + } + runtime "org.codehaus.groovy:groovy-all:2.4.11@jar" + runtime group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.11', ext: 'jar' + + compile fileTree(dir: 'libs', include: '*.jar') +} diff --git a/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF b/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF new file mode 100644 index 0000000000..59499bce4a --- /dev/null +++ b/gradle/gradletaskdemo/build/tmp/jar/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/gradle/gradlew b/gradle/gradlew index 9d82f78915..27309d9231 100644 --- a/gradle/gradlew +++ b/gradle/gradlew @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then diff --git a/gradle/gradlew.bat b/gradle/gradlew.bat index 8a0b282aa6..832fdb6079 100644 --- a/gradle/gradlew.bat +++ b/gradle/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args diff --git a/gradle/greeter/.gitignore b/gradle/greeter/.gitignore new file mode 100644 index 0000000000..e93e09f86e --- /dev/null +++ b/gradle/greeter/.gitignore @@ -0,0 +1,3 @@ +/.gradle +/build +/bin diff --git a/gradle/greeter/build.gradle b/gradle/greeter/build.gradle new file mode 100644 index 0000000000..6f43f23494 --- /dev/null +++ b/gradle/greeter/build.gradle @@ -0,0 +1,18 @@ +apply plugin : 'java' +apply plugin : 'application' + + + +dependencies { + compile project(':greeting-library') + compile project(':greeting-library-java') +} + +mainClassName = 'greeter.Greeter' +run { + if (project.hasProperty("appArgs")) { + args Eval.me(appArgs) + } + else + args = ["Baeldung"]; +} diff --git a/gradle/greeter/src/main/java/greeter/Greeter.java b/gradle/greeter/src/main/java/greeter/Greeter.java new file mode 100644 index 0000000000..7b59f0c4bc --- /dev/null +++ b/gradle/greeter/src/main/java/greeter/Greeter.java @@ -0,0 +1,13 @@ +package greeter; + +import baeldunggreeter.Formatter; + +public class Greeter { + public static void main(String[] args) { + final String output = GreetingFormatter + .greeting(args[0]); + String date = Formatter.getFormattedDate(); + System.out.println(output); + System.out.println("Today is :" + date); + } +} diff --git a/gradle/greeter/src/test/java/greetertest/TestGreeting.java b/gradle/greeter/src/test/java/greetertest/TestGreeting.java new file mode 100644 index 0000000000..0ae5fab631 --- /dev/null +++ b/gradle/greeter/src/test/java/greetertest/TestGreeting.java @@ -0,0 +1,11 @@ + + + + +public class TestGreeting{ + + + + + +} \ No newline at end of file diff --git a/gradle/greeting-library-java/.gitignore b/gradle/greeting-library-java/.gitignore new file mode 100644 index 0000000000..348c102afc --- /dev/null +++ b/gradle/greeting-library-java/.gitignore @@ -0,0 +1,2 @@ +/build +/bin diff --git a/gradle/greeting-library-java/build.gradle b/gradle/greeting-library-java/build.gradle new file mode 100644 index 0000000000..34931bd0cd --- /dev/null +++ b/gradle/greeting-library-java/build.gradle @@ -0,0 +1,9 @@ +apply plugin :'java' +//apply plugin : 'application' + + + +dependencies{ + compile group: 'joda-time', name: 'joda-time', version: '2.9.9' + testCompile group: 'junit', name: 'junit', version: '4.12' +} diff --git a/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java b/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java new file mode 100644 index 0000000000..367e992c1b --- /dev/null +++ b/gradle/greeting-library-java/src/main/java/baeldunggreeter/Formatter.java @@ -0,0 +1,14 @@ +package baeldunggreeter; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Formatter { + public static String getFormattedDate() { + DateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } +} diff --git a/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java b/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java new file mode 100644 index 0000000000..49efc934a5 --- /dev/null +++ b/gradle/greeting-library-java/src/test/java/baeldunggreetertest/FormatterTest.java @@ -0,0 +1,23 @@ +package baeldunggreetertest; + +import static org.junit.Assert.assertTrue; + +import java.util.Date; +import java.util.regex.Pattern; + +import org.junit.Test; + +import baeldunggreeter.Formatter; + +public class FormatterTest { + + @Test + public void testFormatter() { + + String dateRegex1 = "^((19|20)\\d\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01]) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])$"; + String dateString = Formatter.getFormattedDate(); + assertTrue(Pattern + .matches(dateRegex1, dateString)); + + } +} \ No newline at end of file diff --git a/gradle/greeting-library/.gitignore b/gradle/greeting-library/.gitignore new file mode 100644 index 0000000000..84c048a73c --- /dev/null +++ b/gradle/greeting-library/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy b/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy new file mode 100644 index 0000000000..94c863e294 --- /dev/null +++ b/gradle/greeting-library/bin/greeter/GreetingFormatter.groovy @@ -0,0 +1,10 @@ +package greeter + +import groovy.transform.CompileStatic + +@CompileStatic +class GreetingFormatter{ + static String greeting(final String name) { + "Hello, ${name.capitalize()}" + } +} diff --git a/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy b/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy new file mode 100644 index 0000000000..f1c1211552 --- /dev/null +++ b/gradle/greeting-library/bin/greeter/GreetingFormatterSpec.groovy @@ -0,0 +1,13 @@ +package greeter + +import spock.lang.Specification + +class GreetingFormatterSpec extends Specification { + + def 'Creating a greeting'() { + + expect: 'The greeeting to be correctly capitalized' + GreetingFormatter.greeting('gradlephant') == 'Hello, Gradlephant' + + } +} diff --git a/gradle/greeting-library/build.gradle b/gradle/greeting-library/build.gradle new file mode 100644 index 0000000000..eb526b3b03 --- /dev/null +++ b/gradle/greeting-library/build.gradle @@ -0,0 +1,9 @@ +apply plugin : 'groovy' + +dependencies { + compile 'org.codehaus.groovy:groovy:2.4.12' + + testCompile 'org.spockframework:spock-core:1.0-groovy-2.4', { + exclude module : 'groovy-all' + } +} diff --git a/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy b/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy new file mode 100644 index 0000000000..db8a035b67 --- /dev/null +++ b/gradle/greeting-library/src/main/groovy/greeter/GreetingFormatter.groovy @@ -0,0 +1,10 @@ +package greeter + +import groovy.transform.CompileStatic + +@CompileStatic +class GreetingFormatter{ + static String greeting(final String name) { + "Hello, ${name.capitalize()}" + } +} \ No newline at end of file diff --git a/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy b/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy new file mode 100644 index 0000000000..f1c1211552 --- /dev/null +++ b/gradle/greeting-library/src/test/groovy/greeter/GreetingFormatterSpec.groovy @@ -0,0 +1,13 @@ +package greeter + +import spock.lang.Specification + +class GreetingFormatterSpec extends Specification { + + def 'Creating a greeting'() { + + expect: 'The greeeting to be correctly capitalized' + GreetingFormatter.greeting('gradlephant') == 'Hello, Gradlephant' + + } +} diff --git a/gradle/settings.gradle b/gradle/settings.gradle new file mode 100644 index 0000000000..38704681bd --- /dev/null +++ b/gradle/settings.gradle @@ -0,0 +1,10 @@ +rootProject.name = 'gradletutorial' + + +include 'greeting-library' +include 'greeting-library-java' +include 'greeter' +include 'gradletaskdemo' + + +println 'This will be executed during the initialization phase.' diff --git a/gradle/src/main/java/Main.java b/gradle/src/main/java/Main.java deleted file mode 100644 index 10edd1840b..0000000000 --- a/gradle/src/main/java/Main.java +++ /dev/null @@ -1,5 +0,0 @@ -public class Main{ - public static void main(String[] args){ - System.out.println("Baeldung Rocks"); - } -} diff --git a/gradle/version.properties b/gradle/version.properties new file mode 100644 index 0000000000..565e9213ae --- /dev/null +++ b/gradle/version.properties @@ -0,0 +1,3 @@ +#Version of the produced binaries. This file is intended to be checked-in. +#It will be automatically bumped by release automation. +version=0.0.1 diff --git a/guava-modules/README.md b/guava-modules/README.md new file mode 100644 index 0000000000..79e45a89e7 --- /dev/null +++ b/guava-modules/README.md @@ -0,0 +1,3 @@ + +## Guava Modules + diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index c44a80cbd9..c3bf8c2aa9 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -12,6 +12,16 @@ import com.baeldung.hibernate.pojo.Course; import com.baeldung.hibernate.pojo.Student; 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.Person; +import com.baeldung.hibernate.pojo.inheritance.Pet; +import com.baeldung.hibernate.pojo.inheritance.Vehicle; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; @@ -50,6 +60,16 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(OrderEntry.class); metadataSources.addAnnotatedClass(OrderEntryIdClass.class); metadataSources.addAnnotatedClass(UserProfile.class); + metadataSources.addAnnotatedClass(Book.class); + metadataSources.addAnnotatedClass(MyEmployee.class); + metadataSources.addAnnotatedClass(MyProduct.class); + metadataSources.addAnnotatedClass(Pen.class); + metadataSources.addAnnotatedClass(Person.class); + metadataSources.addAnnotatedClass(Animal.class); + metadataSources.addAnnotatedClass(Pet.class); + metadataSources.addAnnotatedClass(Vehicle.class); + metadataSources.addAnnotatedClass(Car.class); + metadataSources.addAnnotatedClass(Bag.class); Metadata metadata = metadataSources.buildMetadata(); return metadata.getSessionFactoryBuilder() diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java new file mode 100644 index 0000000000..6fe7f915fc --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Animal.java @@ -0,0 +1,40 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Animal { + + @Id + private long animalId; + + private String species; + + public Animal() {} + + public Animal(long animalId, String species) { + this.animalId = animalId; + this.species = species; + } + + public long getAnimalId() { + return animalId; + } + + public void setAnimalId(long animalId) { + this.animalId = animalId; + } + + public String getSpecies() { + return species; + } + + public void setSpecies(String species) { + this.species = species; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java new file mode 100644 index 0000000000..fa6e1b4bef --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Bag.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; + +import org.hibernate.annotations.Polymorphism; +import org.hibernate.annotations.PolymorphismType; + +@Entity +@Polymorphism(type = PolymorphismType.EXPLICIT) +public class Bag implements Item { + + @Id + private long bagId; + + private String type; + + public Bag(long bagId, String type) { + this.bagId = bagId; + this.type = type; + } + + public long getBagId() { + return bagId; + } + + public void setBagId(long bagId) { + this.bagId = bagId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java new file mode 100644 index 0000000000..36ca8dd77c --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Book.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +@Entity +@DiscriminatorValue("1") +public class Book extends MyProduct { + private String author; + + public Book() { + } + + public Book(long productId, String name, String author) { + super(productId, name); + this.author = author; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java new file mode 100644 index 0000000000..49d1f7749a --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Car.java @@ -0,0 +1,25 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; + +@Entity +public class Car extends Vehicle { + private String engine; + + public Car() { + } + + public Car(long vehicleId, String manufacturer, String engine) { + super(vehicleId, manufacturer); + this.engine = engine; + } + + public String getEngine() { + return engine; + } + + public void setEngine(String engine) { + this.engine = engine; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java new file mode 100644 index 0000000000..9656030736 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Item.java @@ -0,0 +1,5 @@ +package com.baeldung.hibernate.pojo.inheritance; + +public interface Item { + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java new file mode 100644 index 0000000000..9a6bce16cf --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyEmployee.java @@ -0,0 +1,22 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; + +@Entity +public class MyEmployee extends Person { + private String company; + + public MyEmployee(long personId, String name, String company) { + super(personId, name); + this.company = company; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java new file mode 100644 index 0000000000..13f04d8904 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/MyProduct.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorColumn; +import javax.persistence.DiscriminatorType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +import org.hibernate.annotations.DiscriminatorFormula; + +@Entity +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "product_type", discriminatorType = DiscriminatorType.INTEGER) +// @DiscriminatorFormula("case when author is not null then 1 else 2 end") +public class MyProduct { + @Id + private long productId; + + private String name; + + public MyProduct() { + } + + public MyProduct(long productId, String name) { + super(); + this.productId = productId; + this.name = name; + } + + public long getProductId() { + return productId; + } + + public void setProductId(long productId) { + this.productId = productId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java new file mode 100644 index 0000000000..32b77e52af --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pen.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +@Entity +@DiscriminatorValue("2") +public class Pen extends MyProduct { + private String color; + + public Pen() { + } + + public Pen(long productId, String name, String color) { + super(productId, name); + this.color = color; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java new file mode 100644 index 0000000000..99084b88af --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +@MappedSuperclass +public class Person { + + @Id + private long personId; + + private String name; + + public Person() { + } + + public Person(long personId, String name) { + this.personId = personId; + this.name = name; + } + + public long getPersonId() { + return personId; + } + + public void setPersonId(long personId) { + this.personId = personId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java new file mode 100644 index 0000000000..870b3cd684 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Pet.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; + +@Entity +@PrimaryKeyJoinColumn(name = "petId") +public class Pet extends Animal { + private String name; + + public Pet() { + } + + public Pet(long animalId, String species, String name) { + super(animalId, species); + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java new file mode 100644 index 0000000000..b2a920573e --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/inheritance/Vehicle.java @@ -0,0 +1,40 @@ +package com.baeldung.hibernate.pojo.inheritance; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +public class Vehicle { + @Id + private long vehicleId; + + private String manufacturer; + + public Vehicle() { + } + + public Vehicle(long vehicleId, String manufacturer) { + this.vehicleId = vehicleId; + this.manufacturer = manufacturer; + } + + public long getVehicleId() { + return vehicleId; + } + + public void setVehicleId(long vehicleId) { + this.vehicleId = vehicleId; + } + + public String getManufacturer() { + return manufacturer; + } + + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java new file mode 100644 index 0000000000..0f35dbb8af --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/InheritanceMappingIntegrationTest.java @@ -0,0 +1,89 @@ +package com.baeldung.hibernate; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; + +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +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.Pen; +import com.baeldung.hibernate.pojo.inheritance.Pet; + +public class InheritanceMappingIntegrationTest { + private Session session; + + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory() + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void givenSubclasses_whenQuerySingleTableSuperclass_thenOk() { + Book book = new Book(1, "1984", "George Orwell"); + session.save(book); + Pen pen = new Pen(2, "my pen", "blue"); + session.save(pen); + + assertThat(session.createQuery("from MyProduct") + .getResultList() + .size()).isEqualTo(2); + } + + @Test + public void givenSubclasses_whenQueryMappedSuperclass_thenOk() { + MyEmployee emp = new MyEmployee(1, "john", "baeldung"); + session.save(emp); + + assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Person") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryJoinedTableSuperclass_thenOk() { + Pet pet = new Pet(1, "dog", "lassie"); + session.save(pet); + + assertThat(session.createQuery("from Animal") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryTablePerClassSuperclass_thenOk() { + Car car = new Car(1, "audi", "xyz"); + session.save(car); + + assertThat(session.createQuery("from Vehicle") + .getResultList() + .size()).isEqualTo(1); + } + + @Test + public void givenSubclasses_whenQueryNonMappedInterface_thenOk() { + Bag bag = new Bag(1, "large"); + session.save(bag); + + assertThat(session.createQuery("from com.baeldung.hibernate.pojo.inheritance.Item") + .getResultList() + .size()).isEqualTo(0); + } +} diff --git a/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java new file mode 100644 index 0000000000..15b07ee03a --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/DefaultOrderOfExecutionTest.java @@ -0,0 +1,33 @@ +package com.baeldung.junit5; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.DEFAULT) +public class DefaultOrderOfExecutionTest { + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } + + @AfterClass + public static void assertOutput() { + assertEquals(output.toString(), "cab"); + } +} diff --git a/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java new file mode 100644 index 0000000000..189efc8945 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/JVMOrderOfExecutionTest.java @@ -0,0 +1,26 @@ +package com.baeldung.junit5; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.JVM) +public class JVMOrderOfExecutionTest { + + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } +} \ No newline at end of file diff --git a/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java b/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java new file mode 100644 index 0000000000..88de057fc8 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/NameAscendingOrderOfExecutionTest.java @@ -0,0 +1,33 @@ +package com.baeldung.junit5; + +import static org.junit.Assert.assertEquals; + +import org.junit.AfterClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class NameAscendingOrderOfExecutionTest { + private static StringBuilder output = new StringBuilder(""); + + @Test + public void secondTest() { + output.append("b"); + } + + @Test + public void thirdTest() { + output.append("c"); + } + + @Test + public void firstTest() { + output.append("a"); + } + + @AfterClass + public static void assertOutput() { + assertEquals(output.toString(), "abc"); + } +} diff --git a/libraries/README.md b/libraries/README.md index c6bbb5634c..ae2522ca9e 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -39,7 +39,6 @@ - [Introduction to Apache Commons CSV](http://www.baeldung.com/apache-commons-csv) - [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference) - [Introduction to NoException](http://www.baeldung.com/no-exception) -- [Introduction to FunctionalJava](http://www.baeldung.com/functional-java) - [Apache Commons IO](http://www.baeldung.com/apache-commons-io) - [Introduction to Conflict-Free Replicated Data Types](http://www.baeldung.com/java-conflict-free-replicated-data-types) - [Introduction to javax.measure](http://www.baeldung.com/javax-measure) @@ -53,7 +52,13 @@ - [Using Pairs in Java](http://www.baeldung.com/java-pairs) - [Apache Commons Collections Bag](http://www.baeldung.com/apache-commons-bag) - [Introduction to Caffeine](http://www.baeldung.com/java-caching-caffeine) -+-[Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) +- [Introduction to Chronicle Queue](http://www.baeldung.com/java-chronicle-queue) +- [Introduction To Docx4J](http://www.baeldung.com/docx4j) +- [Introduction to StreamEx](http://www.baeldung.com/streamex) +- [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) +- [Intro to JDO Queries 2/2](http://www.baeldung.com/jdo-queries) +- [Guide to google-http-client](http://www.baeldung.com/google-http-client) + The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. diff --git a/logging-modules/README.md b/logging-modules/README.md new file mode 100644 index 0000000000..23458cf30b --- /dev/null +++ b/logging-modules/README.md @@ -0,0 +1,3 @@ + +## Logging Modules + diff --git a/lucene/pom.xml b/lucene/pom.xml new file mode 100644 index 0000000000..42b81a7d4a --- /dev/null +++ b/lucene/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + lucene + 0.0.1-SNAPSHOT + lucene + An Apache Lucene demo application + + + + + org.apache.lucene + lucene-core + 7.1.0 + + + + org.apache.lucene + lucene-queryparser + 7.1.0 + + + + junit + junit + 4.12 + test + + + + + \ No newline at end of file diff --git a/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java new file mode 100644 index 0000000000..40a35fad86 --- /dev/null +++ b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java @@ -0,0 +1,78 @@ +package com.baeldung.lucene; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.queryparser.classic.ParseException; +import org.apache.lucene.queryparser.classic.QueryParser; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; + +public class InMemoryLuceneIndex { + + private Directory memoryIndex; + private StandardAnalyzer analyzer; + + public InMemoryLuceneIndex(Directory memoryIndex, StandardAnalyzer analyzer) { + super(); + this.memoryIndex = memoryIndex; + this.analyzer = analyzer; + } + + /** + * + * @param title + * @param body + */ + public void indexDocument(String title, String body) { + + IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); + try { + IndexWriter writter = new IndexWriter(memoryIndex, indexWriterConfig); + Document document = new Document(); + + document.add(new TextField("title", title, Field.Store.YES)); + document.add(new TextField("body", body, Field.Store.YES)); + + writter.addDocument(document); + writter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public List searchIndex(String inField, String queryString) { + try { + Query query = new QueryParser(inField, analyzer).parse(queryString); + + IndexReader indexReader = DirectoryReader.open(memoryIndex); + IndexSearcher searcher = new IndexSearcher(indexReader); + TopDocs topDocs = searcher.search(query, 10); + List documents = new ArrayList<>(); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + documents.add(searcher.doc(scoreDoc.doc)); + } + + return documents; + } catch (IOException | ParseException e) { + e.printStackTrace(); + } + return null; + + } + +} + + diff --git a/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java b/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java new file mode 100644 index 0000000000..c3a498a4b8 --- /dev/null +++ b/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java @@ -0,0 +1,23 @@ +package com.baeldung.lucene; + +import java.util.List; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.store.RAMDirectory; +import org.junit.Assert; +import org.junit.Test; + +public class LuceneInMemorySearchTest { + + @Test + public void givenSearchQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Hello world", "Some hello world "); + + List documents = inMemoryLuceneIndex.searchIndex("body", "world"); + + Assert.assertEquals("Hello world", documents.get(0).get("title")); + } + +} diff --git a/metrics/README.md b/metrics/README.md index 09fe925604..c7772bffa0 100644 --- a/metrics/README.md +++ b/metrics/README.md @@ -2,3 +2,4 @@ - [Intro to Dropwizard Metrics](http://www.baeldung.com/dropwizard-metrics) - [Introduction to Netflix Servo](http://www.baeldung.com/netflix-servo) +- [Quick Guide to Micrometer](http://www.baeldung.com/micrometer) diff --git a/patterns/README.md b/patterns/README.md index bcd54a64b1..67d84154cb 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -1,3 +1,4 @@ ###Relevant Articles: - [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern) - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) +- [Implementing the Template Method Pattern in Java](http://www.baeldung.com/template-method-pattern-in-java) diff --git a/patterns/pom.xml b/patterns/pom.xml index c40d7c58b7..68e5316f64 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -9,6 +9,7 @@ front-controller intercepting-filter + template-method @@ -51,4 +52,4 @@ 3.0.0 9.4.0.v20161208 - + \ No newline at end of file diff --git a/patterns/template-method/pom.xml b/patterns/template-method/pom.xml index c3b6a084ac..4b863fe0a4 100644 --- a/patterns/template-method/pom.xml +++ b/patterns/template-method/pom.xml @@ -1,15 +1,17 @@ 4.0.0 - com.baeldung.templatemethodpattern - templatemethodpattern + com.baeldung.templatemethod + template-method 1.0 jar - - UTF-8 - 1.8 - 1.8 - + + com.baeldung.patterns + patterns-parent + 1.0.0-SNAPSHOT + .. + + junit @@ -18,4 +20,18 @@ test + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + + + + UTF-8 + 1.8 + 1.8 + \ No newline at end of file diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java index 5570c2e1dd..bd383b4568 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java @@ -1,11 +1,11 @@ package com.baeldung.templatemethodpattern.application; import com.baeldung.templatemethodpattern.model.Computer; +import com.baeldung.templatemethodpattern.model.StandardComputer; +import com.baeldung.templatemethodpattern.model.HighEndComputer; import com.baeldung.templatemethodpattern.model.ComputerBuilder; import com.baeldung.templatemethodpattern.model.HighEndComputerBuilder; import com.baeldung.templatemethodpattern.model.StandardComputerBuilder; -import com.baeldung.templatemethodpattern.model.HighEndComputer; -import com.baeldung.templatemethodpattern.model.StandardComputer; public class Application { diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java index d422204b82..128eec59ad 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java @@ -5,33 +5,15 @@ import java.util.Map; import java.util.ArrayList; import java.util.List; -public abstract class ComputerBuilder { +public class Computer { - protected Map computerParts = new HashMap<>(); - protected List moterboardSetupStatus = new ArrayList<>(); + private Map computerParts = new HashMap<>(); - public final Computer buildComputer() { - addMotherboard(); - setupMotherboard(); - addProcessor(); - return getComputer(); + public Computer(Map computerParts) { + this.computerParts = computerParts; } - public abstract void addMotherboard(); - - public abstract void setupMotherboard(); - - public abstract void addProcessor(); - - public List getMotherboardSetupStatus() { - return moterboardSetupStatus; - } - public Map getComputerParts() { return computerParts; } - - private Computer getComputer() { - return new Computer(computerParts); - } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java index f264d33215..39052f4776 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java @@ -8,7 +8,7 @@ import java.util.Map; public abstract class ComputerBuilder { protected Map computerParts = new HashMap<>(); - protected List moterboardSetupStatus = new ArrayList<>(); + protected List motherboardSetupStatus = new ArrayList<>(); public final Computer buildComputer() { addMotherboard(); @@ -20,13 +20,13 @@ public abstract class ComputerBuilder { public abstract void addMotherboard(); public abstract void setupMotherboard(); - + public abstract void addProcessor(); public List getMotherboardSetupStatus() { - return moterboardSetupStatus; + return motherboardSetupStatus; } - + public Map getComputerParts() { return computerParts; } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java index 8d80e1e108..16d89f1ad6 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java @@ -1,26 +1,10 @@ package com.baeldung.templatemethodpattern.model; -public class HighEndComputer extends Computer { +import java.util.Map; - @Override - public void addMotherboard() { - computerParts.put("Motherboard", "High-end Motherboard"); - } +public class HighEndComputer extends Computer { - @Override - public void setupMotherboard() { - moterboardSetupStatus.add("Screwing the high-end motherboard to the case."); - moterboardSetupStatus.add("Pluging in the power supply connectors."); - moterboardSetupStatus.forEach(step -> System.out.println(step)); - } - - @Override - public void addProcessor() { - computerParts.put("Processor", "High-end Processor"); - } - - @Override - public void addMotherboard() { - computerParts.put("Motherboard", "High End Motherboard"); - } + public HighEndComputer(Map computerParts) { + super(computerParts); + } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java index cf53a2ae6c..baa800ca8f 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java @@ -9,13 +9,13 @@ public class HighEndComputerBuilder extends ComputerBuilder { @Override public void setupMotherboard() { - moterboardSetupStatus.add("Screwing the high-end motherboard to the case."); - moterboardSetupStatus.add("Pluging in the power supply connectors."); - moterboardSetupStatus.forEach(step -> System.out.println(step)); + motherboardSetupStatus.add("Screwing the high-end motherboard to the case."); + motherboardSetupStatus.add("Pluging in the power supply connectors."); + motherboardSetupStatus.forEach(step -> System.out.println(step)); } @Override public void addProcessor() { - computerParts.put("Processor", "High-end Processor"); + computerParts.put("Processor", "High-end Processor"); } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java index 8410ad88ee..14d32d7b64 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java @@ -1,25 +1,10 @@ package com.baeldung.templatemethodpattern.model; - + +import java.util.Map; + public class StandardComputer extends Computer { - public void addMotherboard() { - computerParts.put("Motherboard", "Standard Motherboard"); - } - - @Override - public void setupMotherboard() { - moterboardSetupStatus.add("Screwing the standard motherboard to the case."); - moterboardSetupStatus.add("Pluging in the power supply connectors."); - moterboardSetupStatus.forEach(step -> System.out.println(step)); - } - - @Override - public void addProcessor() { - computerParts.put("Processor", "Standard Processor"); - } - - @Override - public void addMotherboard() { - computerParts.put("Motherboard", "Standard Motherboard"); - } + public StandardComputer(Map computerParts) { + super(computerParts); + } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java index 1d9bd0e00f..78547dc38b 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java @@ -9,9 +9,9 @@ public class StandardComputerBuilder extends ComputerBuilder { @Override public void setupMotherboard() { - moterboardSetupStatus.add("Screwing the standard motherboard to the case."); - moterboardSetupStatus.add("Pluging in the power supply connectors."); - moterboardSetupStatus.forEach(step -> System.out.println(step)); + motherboardSetupStatus.add("Screwing the standard motherboard to the case."); + motherboardSetupStatus.add("Pluging in the power supply connectors."); + motherboardSetupStatus.forEach(step -> System.out.println(step)); } @Override diff --git a/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java b/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java index df5751fb03..1d608ff2c2 100644 --- a/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java +++ b/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java @@ -29,12 +29,12 @@ public class TemplateMethodPatternTest { @Test public void givenStandardMotherBoard_whenAddingMotherBoard_thenEqualAssertion() { - standardComputer.addMotherboard(); - assertEquals("Standard Motherboard", standardComputer.getComputerParts().get("Motherboard")); + standardComputerBuilder.addMotherboard(); + assertEquals("Standard Motherboard", standardComputerBuilder.getComputerParts().get("Motherboard")); } @Test - public void givenStandardMotheroboard_whenSetup_thenTwoEqualAssertions() { + public void givenStandardMotherboard_whenSetup_thenTwoEqualAssertions() { standardComputerBuilder.setupMotherboard(); assertEquals("Screwing the standard motherboard to the case.", standardComputerBuilder.getMotherboardSetupStatus().get(0)); assertEquals("Pluging in the power supply connectors.", standardComputerBuilder.getMotherboardSetupStatus().get(1)); diff --git a/persistence-modules/README.md b/persistence-modules/README.md new file mode 100644 index 0000000000..6c2b1d2ca9 --- /dev/null +++ b/persistence-modules/README.md @@ -0,0 +1,3 @@ + +## Persistence Modules + diff --git a/pom.xml b/pom.xml index b9186f9304..20f7c4ffad 100644 --- a/pom.xml +++ b/pom.xml @@ -261,6 +261,7 @@ saas deeplearning4j spring-boot-admin + lucene diff --git a/rxjava/README.md b/rxjava/README.md index 71231cc391..c88ec36991 100644 --- a/rxjava/README.md +++ b/rxjava/README.md @@ -8,3 +8,4 @@ - [Observable Utility Operators in RxJava](http://www.baeldung.com/rxjava-observable-operators) - [Introduction to rxjava-jdbc](http://www.baeldung.com/rxjava-jdbc) - [Schedulers in RxJava](http://www.baeldung.com/rxjava-schedulers) +- [Mathematical and Aggregate Operators in RxJava](http://www.baeldung.com/rxjava-math) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index e9a65232d2..7e30179f07 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.M3 + 2.0.0.M6 @@ -99,6 +99,11 @@ spring-boot-starter-test test + + org.springframework.security + spring-security-test + test + org.apache.commons @@ -189,7 +194,7 @@ 1.0.0 5.0.0 2.20 - 5.0.0.RELEASE + 5.0.1.RELEASE 1.0.1.RELEASE 1.1.3 1.0 diff --git a/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java b/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java new file mode 100644 index 0000000000..02c91a1879 --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/SpringSecurity5Application.java @@ -0,0 +1,34 @@ +package com.baeldung; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; +import org.springframework.web.reactive.config.EnableWebFlux; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; +import reactor.ipc.netty.NettyContext; +import reactor.ipc.netty.http.server.HttpServer; + +@ComponentScan(basePackages = {"com.baeldung.security"}) +@EnableWebFlux +public class SpringSecurity5Application { + + public static void main(String[] args) { + try (AnnotationConfigApplicationContext context = + new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) { + context.getBean(NettyContext.class).onClose().block(); + } + } + + @Bean + public NettyContext nettyContext(ApplicationContext context) { + HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context) + .build(); + ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler); + HttpServer httpServer = HttpServer.create("localhost", 8080); + return httpServer.newHandler(adapter).block(); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/GreetController.java b/spring-5/src/main/java/com/baeldung/security/GreetController.java new file mode 100644 index 0000000000..6b69e3bc9b --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/GreetController.java @@ -0,0 +1,37 @@ +package com.baeldung.security; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +import java.security.Principal; + +@RestController +public class GreetController { + + private GreetService greetService; + + public GreetController(GreetService greetService) { + this.greetService = greetService; + } + + @GetMapping("/") + public Mono greet(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Hello, %s", name)); + } + + @GetMapping("/admin") + public Mono greetAdmin(Mono principal) { + return principal + .map(Principal::getName) + .map(name -> String.format("Admin access: %s", name)); + } + + @GetMapping("/greetService") + public Mono greetService() { + return greetService.greet(); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/GreetService.java b/spring-5/src/main/java/com/baeldung/security/GreetService.java new file mode 100644 index 0000000000..7622b360be --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/GreetService.java @@ -0,0 +1,15 @@ +package com.baeldung.security; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +@Service +public class GreetService { + + @PreAuthorize("hasRole('ADMIN')") + public Mono greet() { + return Mono.just("Hello from service!"); + } + +} diff --git a/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java new file mode 100644 index 0000000000..a9e44a2eee --- /dev/null +++ b/spring-5/src/main/java/com/baeldung/security/SecurityConfig.java @@ -0,0 +1,42 @@ +package com.baeldung.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.server.SecurityWebFilterChain; + +@EnableWebFluxSecurity +@EnableReactiveMethodSecurity +public class SecurityConfig { + + @Bean + public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) { + return http.authorizeExchange() + .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") + .anyExchange().authenticated() + .and().formLogin() + .and().build(); + } + + @Bean + public MapReactiveUserDetailsService userDetailsService() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user") + .password("password") + .roles("USER") + .build(); + + UserDetails admin = User.withDefaultPasswordEncoder() + .username("admin") + .password("password") + .roles("ADMIN") + .build(); + + return new MapReactiveUserDetailsService(user, admin); + } + +} diff --git a/spring-5/src/main/resources/application.properties b/spring-5/src/main/resources/application.properties index 886ea1978b..ccec014c2b 100644 --- a/spring-5/src/main/resources/application.properties +++ b/spring-5/src/main/resources/application.properties @@ -1,6 +1,3 @@ server.port=8081 -security.user.name=user -security.user.password=pass - logging.level.root=INFO \ No newline at end of file diff --git a/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java b/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java new file mode 100644 index 0000000000..c6d3b7ff10 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/EnabledOnJava8.java @@ -0,0 +1,18 @@ +package com.baeldung.jupiter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.junit.jupiter.EnabledIf; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@EnabledIf( + expression = "#{systemProperties['java.version'].startsWith('1.8')}", + reason = "Enabled on Java 8" +) +public @interface EnabledOnJava8 { + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java b/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java new file mode 100644 index 0000000000..ae058bc8ba --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/Spring5EnabledAnnotationTest.java @@ -0,0 +1,50 @@ +package com.baeldung.jupiter; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.DisabledIf; +import org.springframework.test.context.junit.jupiter.EnabledIf; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +@SpringJUnitConfig(Spring5EnabledAnnotationTest.Config.class) +@TestPropertySource(properties = { "tests.enabled=true" }) +public class Spring5EnabledAnnotationTest { + + @Configuration + static class Config { + } + + @EnabledIf("true") + @Test + void givenEnabledIfLiteral_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledIf(expression = "${tests.enabled}", loadContext = true) + @Test + void givenEnabledIfExpression_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledIf("#{systemProperties['java.version'].startsWith('1.8')}") + @Test + void givenEnabledIfSpel_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @EnabledOnJava8 + @Test + void givenEnabledOnJava8_WhenTrue_ThenTestExecuted() { + assertTrue(true); + } + + @DisabledIf("#{systemProperties['java.version'].startsWith('1.7')}") + @Test + void givenDisabledIf_WhenTrue_ThenTestNotExecuted() { + assertTrue(true); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/security/SecurityTest.java b/spring-5/src/test/java/com/baeldung/security/SecurityTest.java new file mode 100644 index 0000000000..a1c940a17a --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/security/SecurityTest.java @@ -0,0 +1,48 @@ +package com.baeldung.security; + +import com.baeldung.SpringSecurity5Application; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.reactive.server.WebTestClient; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = SpringSecurity5Application.class) +public class SecurityTest { + + @Autowired + ApplicationContext context; + + private WebTestClient rest; + + @Before + public void setup() { + this.rest = WebTestClient + .bindToApplicationContext(this.context) + .configureClient() + .build(); + } + + @Test + public void whenNoCredentials_thenRedirectToLogin() { + this.rest.get() + .uri("/") + .exchange() + .expectStatus().is3xxRedirection(); + } + + @Test + @WithMockUser + public void whenHasCredentials_thenSeesGreeting() { + this.rest.get() + .uri("/") + .exchange() + .expectStatus().isOk() + .expectBody(String.class).isEqualTo("Hello, user"); + } +} diff --git a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java b/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java index b05f903b4b..43114b5b50 100644 --- a/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java +++ b/spring-5/src/test/java/com/baeldung/web/client/WebTestClientTest.java @@ -53,7 +53,7 @@ public class WebTestClientTest { .uri("/resource") .exchange() .expectStatus() - .is4xxClientError() + .is3xxRedirection() .expectBody(); } diff --git a/spring-activiti/README.md b/spring-activiti/README.md index 5007b03ec7..703dfeec52 100644 --- a/spring-activiti/README.md +++ b/spring-activiti/README.md @@ -3,3 +3,4 @@ - [A Guide to Activiti with Java](http://www.baeldung.com/java-activiti) - [Introduction to Activiti with Spring](http://www.baeldung.com/spring-activiti) - [Activiti with Spring Security](http://www.baeldung.com/activiti-spring-security) +- [ProcessEngine Configuration in Activiti](http://www.baeldung.com/activiti-process-engine) diff --git a/spring-all/README.md b/spring-all/README.md index 36bf7da778..e1504a66db 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -23,3 +23,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) - [A CLI with Spring Shell](http://www.baeldung.com/spring-shell-cli) - [JasperReports with Spring](http://www.baeldung.com/spring-jasper) +- [Model, ModelMap, and ModelView in Spring MVC](http://www.baeldung.com/spring-mvc-model-model-map-model-view) diff --git a/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java similarity index 97% rename from spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java rename to spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java index d70fb1c7cf..0201deabca 100644 --- a/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java +++ b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationIntegrationTest.java @@ -19,7 +19,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = RANDOM_PORT) -public class SpringBootAdminClientApplicationTests { +public class SpringBootAdminClientApplicationIntegrationTest { @Autowired Environment environment; diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java similarity index 95% rename from spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java rename to spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java index 8ca50a6f75..7c1b1881a4 100644 --- a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigIntegrationTest.java @@ -13,7 +13,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(classes = { HazelcastConfig.class }, webEnvironment = NONE) -public class HazelcastConfigTest { +public class HazelcastConfigIntegrationTest { @Autowired private ApplicationContext applicationContext; diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java similarity index 96% rename from spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java rename to spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java index 85f6b374a4..465d079ac3 100644 --- a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationIntegrationTest.java @@ -16,7 +16,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen @RunWith(SpringRunner.class) @SpringBootTest(classes = { NotifierConfiguration.class }, webEnvironment = NONE) -public class NotifierConfigurationTest { +public class NotifierConfigurationIntegrationTest { @Autowired private ApplicationContext applicationContext; diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java similarity index 97% rename from spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java rename to spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java index 40611f00f6..0c0695e6c2 100644 --- a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigIntegrationTest.java @@ -17,7 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class WebSecurityConfigTest { +public class WebSecurityConfigIntegrationTest { @Autowired WebApplicationContext wac; diff --git a/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java b/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java similarity index 97% rename from spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java rename to spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java index 41662e5c17..e0bbef1c7f 100644 --- a/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java +++ b/spring-boot-keycloak/src/test/java/com/baeldung/keycloak/KeycloakConfigurationIntegrationTest.java @@ -20,7 +20,7 @@ import static org.mockito.Mockito.when; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SpringBoot.class) -public class KeycloakConfigurationTest { +public class KeycloakConfigurationIntegrationTest { @Spy private KeycloakSecurityContextClientRequestInterceptor factory; diff --git a/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java index a51e3a6884..ffd5bf55d6 100644 --- a/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/properties/ConfigPropertiesIntegrationTest.java @@ -1,7 +1,5 @@ package org.baeldung.properties; -import org.baeldung.properties.ConfigProperties; -import org.baeldung.properties.ConfigPropertiesDemoApplication; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/spring-jpa/src/main/resources/data.sql b/spring-boot/src/test/resources/data.sql similarity index 100% rename from spring-jpa/src/main/resources/data.sql rename to spring-boot/src/test/resources/data.sql diff --git a/spring-jpa/src/main/resources/schema.sql b/spring-boot/src/test/resources/schema.sql similarity index 100% rename from spring-jpa/src/main/resources/schema.sql rename to spring-boot/src/test/resources/schema.sql diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index 93bf6ea74b..e6d78f292d 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + 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.cloud @@ -15,8 +15,10 @@ spring-cloud-ribbon-client spring-cloud-rest spring-cloud-zookeeper - spring-cloud-gateway - spring-cloud-connectors-heroku + spring-cloud-gateway + spring-cloud-stream + spring-cloud-connectors-heroku + spring-cloud-aws pom @@ -38,6 +40,7 @@ 1.2.3.RELEASE 1.2.3.RELEASE 1.2.3.RELEASE + 1.3.0.RELEASE 1.4.2.RELEASE 3.6.0 1.4.2.RELEASE diff --git a/spring-cloud/spring-cloud-aws/README.md b/spring-cloud/spring-cloud-aws/README.md new file mode 100644 index 0000000000..c5f58159c8 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/README.md @@ -0,0 +1,21 @@ +# Spring Cloud AWS + +#### Running the Integration Tests + +To run the Integration Tests, we need to have an AWS account and have API keys generated for programmatic access. Edit +the `application.properties` file to add the following properties: + +``` +cloud.aws.credentials.accessKey=YourAccessKey +cloud.aws.credentials.secretKey=YourSecretKey +cloud.aws.region.static=us-east-1 +``` + +To test automatic DataSource creation from RDS instance, we also need to create an RDS instance in the AWS account. +Let's say that the RDS instance is called `spring-cloud-test-db` having the master password `se3retpass`, then we need +to write the following in `application.properties`: + +``` +cloud.aws.rds.spring-cloud-test-db +cloud.aws.rds.spring-cloud-test-db.password=se3retpass +``` diff --git a/spring-cloud/spring-cloud-aws/pom.xml b/spring-cloud/spring-cloud-aws/pom.xml new file mode 100644 index 0000000000..632e050d92 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + + com.baeldung.spring.cloud + spring-cloud-aws + 0.0.1-SNAPSHOT + jar + + Spring Cloud AWS + Spring Cloud AWS Examples + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + Dalston.SR4 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-aws + + + org.springframework.cloud + spring-cloud-starter-aws-jdbc + + + org.springframework.cloud + spring-cloud-starter-aws-messaging + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.postgresql + postgresql + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + maven-surefire-plugin + + + **/*IntegrationTest.java + + + + + + + + + diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java new file mode 100644 index 0000000000..2c3909b3eb --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/SpringCloudAwsApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.spring.cloud.aws; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringCloudAwsApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringCloudAwsApplication.class, args); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java new file mode 100644 index 0000000000..85dcd05c86 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/config/SpringCloudAwsConfig.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.aws.config; + +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sqs.AmazonSQSAsync; +import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate; +import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SpringCloudAwsConfig { + + @Bean + public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSQSAsync) { + return new QueueMessagingTemplate(amazonSQSAsync); + } + + @Bean + public NotificationMessagingTemplate notificationMessagingTemplate(AmazonSNS amazonSNS) { + return new NotificationMessagingTemplate(amazonSNS); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java new file mode 100644 index 0000000000..cfad6e904f --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.aws.s3; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.core.io.WritableResource; +import org.springframework.core.io.support.ResourcePatternResolver; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +@Component +public class SpringCloudS3 { + + @Autowired + ResourceLoader resourceLoader; + + @Autowired + ResourcePatternResolver resourcePatternResolver; + + public void downloadS3Object(String s3Url) throws IOException { + Resource resource = resourceLoader.getResource(s3Url); + File downloadedS3Object = new File(resource.getFilename()); + try (InputStream inputStream = resource.getInputStream()) { + Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } + + public void uploadFileToS3(File file, String s3Url) throws IOException { + WritableResource resource = (WritableResource) resourceLoader.getResource(s3Url); + try (OutputStream outputStream = resource.getOutputStream()) { + Files.copy(file.toPath(), outputStream); + } + } + + public void downloadMultipleS3Objects(String s3UrlPattern) throws IOException { + Resource[] allFileMatchingPatten = this.resourcePatternResolver.getResources(s3UrlPattern); + for (Resource resource : allFileMatchingPatten) { + String fileName = resource.getFilename(); + fileName = fileName.substring(0, fileName.lastIndexOf("/") + 1); + File downloadedS3Object = new File(fileName); + try (InputStream inputStream = resource.getInputStream()) { + Files.copy(inputStream, downloadedS3Object.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java new file mode 100644 index 0000000000..7c78fcbe37 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointController.java @@ -0,0 +1,36 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage; +import org.springframework.cloud.aws.messaging.config.annotation.NotificationSubject; +import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationMessageMapping; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationSubscriptionMapping; +import org.springframework.cloud.aws.messaging.endpoint.annotation.NotificationUnsubscribeConfirmationMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/topic-subscriber") +public class SNSEndpointController { + + private static final Logger logger = LoggerFactory.getLogger(SNSEndpointController.class); + + @NotificationMessageMapping + public void receiveNotification(@NotificationMessage String message, @NotificationSubject String subject) { + logger.info("Received message: {}, having subject: {}", message, subject); + } + + @NotificationUnsubscribeConfirmationMapping + public void confirmSubscriptionMessage(NotificationStatus notificationStatus) { + logger.info("Unsubscribed from Topic"); + notificationStatus.confirmSubscription(); + } + + @NotificationSubscriptionMapping + public void confirmUnsubscribeMessage(NotificationStatus notificationStatus) { + logger.info("Subscribed to Topic"); + notificationStatus.confirmSubscription(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java new file mode 100644 index 0000000000..58cb03644b --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sns/SNSMessageSender.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.aws.messaging.core.NotificationMessagingTemplate; +import org.springframework.stereotype.Component; + +@Component +public class SNSMessageSender { + + @Autowired + NotificationMessagingTemplate notificationMessagingTemplate; + + public void send(String topicName, Object message, String subject) { + notificationMessagingTemplate.sendNotification(topicName, message, subject); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java new file mode 100644 index 0000000000..d2a5fcf9ca --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQS.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.aws.sqs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate; +import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener; +import org.springframework.context.annotation.Lazy; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CountDownLatch; + +@Component +@Lazy +public class SpringCloudSQS { + + private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQS.class); + + static final String QUEUE_NAME = "spring-cloud-test-queue"; + + /* + * CountDownLatch is added to wait for messages + * during integration test + */ + CountDownLatch countDownLatch; + + public void setCountDownLatch(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Autowired + QueueMessagingTemplate queueMessagingTemplate; + + @SqsListener(QUEUE_NAME) + public void receiveMessage(String message, @Header("SenderId") String senderId) { + logger.info("Received message: {}, having SenderId: {}", message, senderId); + if (countDownLatch != null) { + countDownLatch.countDown(); + } + } + + public void send(String queueName, Object message) { + queueMessagingTemplate.convertAndSend(queueName, message); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/resources/application.properties b/spring-cloud/spring-cloud-aws/src/main/resources/application.properties new file mode 100644 index 0000000000..a769b70ddd --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/resources/application.properties @@ -0,0 +1,14 @@ +cloud.aws.credentials.accessKey=YourAccessKey +cloud.aws.credentials.secretKey=YourSecretKey +cloud.aws.region.static=us-east-1 + +cloud.aws.rds.spring-cloud-test-db +cloud.aws.rds.spring-cloud-test-db.password=se3retpass + +# These 3 properties are optional +cloud.aws.rds.spring-cloud-test-db.username=testuser +cloud.aws.rds.spring-cloud-test-db.readReplicaSupport=true +cloud.aws.rds.spring-cloud-test-db.databaseName=test + +# Disable auto cloudfromation +cloud.aws.stack.auto=false diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java new file mode 100644 index 0000000000..fe10eb6f15 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/SpringCloudAwsTestUtil.java @@ -0,0 +1,73 @@ +package com.baeldung.spring.cloud.aws; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sns.AmazonSNSClientBuilder; +import com.amazonaws.services.sqs.AmazonSQS; +import com.amazonaws.services.sqs.AmazonSQSClientBuilder; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.junit.BeforeClass; + +/** + * This class is needed only for testing. This is because we need to + * create AWS resources before Spring's Application context is created + * in a {@link BeforeClass} method. Since Autowired dependencies don't + * work in static context, we will use this class for AWS clients. + */ +public class SpringCloudAwsTestUtil { + + private static String awsAccessKey; + private static String awsSecretKey; + private static String defaultRegion; + + static { + try { + InputStream is = SpringCloudAwsTestUtil.class.getResourceAsStream("/application.properties"); + Properties properties = new Properties(); + properties.load(is); + awsAccessKey = properties.getProperty("cloud.aws.credentials.accessKey"); + awsSecretKey = properties.getProperty("cloud.aws.credentials.secretKey"); + defaultRegion = properties.getProperty("cloud.aws.region.static"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static AWSCredentials awsCredentials() { + return new BasicAWSCredentials(awsAccessKey, awsSecretKey); + } + + public static AWSCredentialsProvider awsCredentialsProvider() { + return new AWSStaticCredentialsProvider(awsCredentials()); + } + + public static AmazonS3 amazonS3() { + return AmazonS3ClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } + + public static AmazonSNS amazonSNS() { + return AmazonSNSClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } + + public static AmazonSQS amazonSQS() { + return AmazonSQSClientBuilder.standard() + .withCredentials(awsCredentialsProvider()) + .withRegion(defaultRegion) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java new file mode 100644 index 0000000000..9e163d6dc4 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/rds/SpringCloudRDSIntegrationTest.java @@ -0,0 +1,46 @@ +package com.baeldung.spring.cloud.aws.rds; + +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 javax.sql.DataSource; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +public class SpringCloudRDSIntegrationTest { + + @Autowired + DataSource dataSource; + + @Test + public void whenDataSourceCreated_thenSuccess() { + assertThat(dataSource).isNotNull(); + } + + @Test + public void givenDataSource_whenConnectionCreated_thenSuccess() throws SQLException { + Connection connection = dataSource.getConnection(); + assertThat(connection).isNotNull(); + } + + @Test + public void givenConnection_whenQueryExecuted_thenSuccess() throws SQLException { + Connection connection = dataSource.getConnection(); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("SELECT 1"); + while (resultSet.next()) { + int result = resultSet.getInt(1); + assertThat(result).isEqualTo(1); + } + connection.close(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java new file mode 100644 index 0000000000..a866287dec --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/s3/SpringCloudS3IntegrationTest.java @@ -0,0 +1,101 @@ +package com.baeldung.spring.cloud.aws.s3; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.ListObjectsV2Result; +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import org.junit.AfterClass; +import org.junit.BeforeClass; +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.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudS3IntegrationTest { + + @Autowired + private SpringCloudS3 springCloudS3; + + private static String bucketName; + private static String testFileToDownload; + private static String testFileToUpload; + + private static String[] filesWithSimilarName; + private static List similarNameFiles; + + @BeforeClass + public static void setupResources() throws IOException { + + bucketName = UUID.randomUUID().toString(); + testFileToDownload = "test-file-download.txt"; + testFileToUpload = "test-file-upload.txt"; + + filesWithSimilarName = new String[] { "foo/hello-apple.txt", "foo/hello-orange.txt", "bar/hello-grapes.txt", }; + + similarNameFiles = new ArrayList<>(); + for (String name : filesWithSimilarName) { + similarNameFiles.add(new File(name.substring(0, name.lastIndexOf("/") + 1))); + } + + Files.write(Paths.get(testFileToUpload), "Hello World Uploaded!".getBytes()); + + AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3(); + amazonS3.createBucket(bucketName); + + amazonS3.putObject(bucketName, testFileToDownload, "Hello World"); + + for (String s3Key : filesWithSimilarName) { + amazonS3.putObject(bucketName, s3Key, "Hello World"); + } + } + + @Test + public void whenS3ObjectDownloaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/" + testFileToDownload; + springCloudS3.downloadS3Object(s3Url); + assertThat(new File(testFileToDownload)).exists(); + } + + @Test + public void whenS3ObjectUploaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/" + testFileToUpload; + File file = new File(testFileToUpload); + springCloudS3.uploadFileToS3(file, s3Url); + } + + @Test + public void whenMultipleS3ObjectsDownloaded_thenSuccess() throws IOException { + String s3Url = "s3://" + bucketName + "/**/hello-*.txt"; + springCloudS3.downloadMultipleS3Objects(s3Url); + similarNameFiles.forEach(f -> assertThat(f).exists()); + } + + @AfterClass + public static void cleanUpResources() { + AmazonS3 amazonS3 = SpringCloudAwsTestUtil.amazonS3(); + ListObjectsV2Result listObjectsV2Result = amazonS3.listObjectsV2(bucketName); + for (S3ObjectSummary objectSummary : listObjectsV2Result.getObjectSummaries()) { + amazonS3.deleteObject(bucketName, objectSummary.getKey()); + } + amazonS3.deleteBucket(bucketName); + + new File(testFileToDownload).delete(); + new File(testFileToUpload).delete(); + similarNameFiles.forEach(File::delete); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java new file mode 100644 index 0000000000..14958570e2 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SNSEndpointControllerUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.cloud.aws.sns; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.cloud.aws.messaging.endpoint.NotificationStatus; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; + +public class SNSEndpointControllerUnitTest { + + SNSEndpointController snsEndpointController; + + @Before + public void setUp() { + snsEndpointController = new SNSEndpointController(); + } + + @Test + public void whenReceivedNotificationInvoked_thenSuccess() { + snsEndpointController.receiveNotification("Message", "Subject"); + } + + @Test + public void whenConfirmUnsubscribeReturned_thenSuccess() { + NotificationStatus notificationStatus = mock(NotificationStatus.class); + doNothing().when(notificationStatus).confirmSubscription(); + snsEndpointController.confirmUnsubscribeMessage(notificationStatus); + } + + @Test + public void whenConfirmSubscriptionReturned_thenSuccess() { + NotificationStatus notificationStatus = mock(NotificationStatus.class); + doNothing().when(notificationStatus).confirmSubscription(); + snsEndpointController.confirmSubscriptionMessage(notificationStatus); + } + +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java new file mode 100644 index 0000000000..e1f23d5c76 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sns/SpringCloudSNSIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.spring.cloud.aws.sns; + +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +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.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sns.model.CreateTopicResult; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import com.baeldung.spring.cloud.aws.sqs.Greeting; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudSNSIntegrationTest { + + @Autowired + private SNSMessageSender snsMessageSender; + + private static String topicName; + private static String topicArn; + + @BeforeClass + public static void setupAwsResources() { + + topicName = UUID.randomUUID().toString(); + + AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS(); + + CreateTopicResult result = amazonSNS.createTopic(topicName); + topicArn = result.getTopicArn(); + } + + @Test + public void whenMessagePublished_thenSuccess() { + String subject = "Test Message"; + String message = "Hello World"; + snsMessageSender.send(topicName, message, subject); + } + + @Test + public void whenConvertedMessagePublished_thenSuccess() { + String subject = "Test Message"; + Greeting message = new Greeting("Helo", "World"); + snsMessageSender.send(topicName, message, subject); + } + + @AfterClass + public static void cleanupAwsResources() { + AmazonSNS amazonSNS = SpringCloudAwsTestUtil.amazonSNS(); + amazonSNS.deleteTopic(topicArn); + } + +} diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java new file mode 100644 index 0000000000..3d14d55f14 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/Greeting.java @@ -0,0 +1,63 @@ +package com.baeldung.spring.cloud.aws.sqs; + +public class Greeting { + private String message; + private String name; + + public Greeting() { + + } + + public Greeting(String mesage, String name) { + this.message = mesage; + this.name = name; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Greeting other = (Greeting) obj; + if (message == null) { + if (other.message != null) + return false; + } else if (!message.equals(other.message)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java new file mode 100644 index 0000000000..76d2fd7c0d --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/sqs/SpringCloudSQSIntegrationTest.java @@ -0,0 +1,135 @@ +package com.baeldung.spring.cloud.aws.sqs; + +import com.amazonaws.services.sqs.AmazonSQS; +import com.amazonaws.services.sqs.model.CreateQueueResult; +import com.amazonaws.services.sqs.model.PurgeQueueRequest; +import com.amazonaws.services.sqs.model.ReceiveMessageRequest; +import com.amazonaws.services.sqs.model.ReceiveMessageResult; +import com.baeldung.spring.cloud.aws.SpringCloudAwsTestUtil; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Lazy; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import java.io.IOException; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class SpringCloudSQSIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(SpringCloudSQSIntegrationTest.class); + + @Autowired + @Lazy + private SpringCloudSQS springCloudSQS; + + private static String receiveQueueName; + private static String receiveQueueUrl; + + private static String sendQueueName; + private static String sendQueueURl; + + @BeforeClass + public static void setupAwsResources() { + + sendQueueName = UUID.randomUUID().toString(); + receiveQueueName = SpringCloudSQS.QUEUE_NAME; + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + CreateQueueResult receiveQueue = amazonSQS.createQueue(receiveQueueName); + receiveQueueUrl = receiveQueue.getQueueUrl(); + + CreateQueueResult sendQueue = amazonSQS.createQueue(sendQueueName); + sendQueueURl = sendQueue.getQueueUrl(); + } + + @Test + public void whenMessageSentAndVerified_thenSuccess() throws InterruptedException { + + String message = "Hello World"; + springCloudSQS.send(sendQueueName, message); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl); + request.setMaxNumberOfMessages(1); + + ReceiveMessageResult result = null; + do { + result = amazonSQS.receiveMessage(request); + if (result.getMessages().size() == 0) { + logger.info("Message not received at first time, waiting for 1 second"); + } + } while (result.getMessages().size() == 0); + assertThat(result.getMessages().get(0).getBody()).isEqualTo(message); + + // Delete message so that it doen't interfere with other test + amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle()); + + } + + @Test + public void whenConvertedMessageSentAndVerified_thenSuccess() throws InterruptedException, IOException { + + Greeting message = new Greeting("Hello", "World"); + springCloudSQS.send(sendQueueName, message); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + + ReceiveMessageRequest request = new ReceiveMessageRequest(sendQueueURl); + request.setMaxNumberOfMessages(1); + + ReceiveMessageResult result = null; + do { + result = amazonSQS.receiveMessage(request); + if (result.getMessages().size() == 0) { + logger.info("Message not received at first time, waiting for 1 second"); + } + } while (result.getMessages().size() == 0); + assertThat(new ObjectMapper().readValue(result.getMessages().get(0).getBody(), Greeting.class)).isEqualTo(message); + + // Delete message so that it doen't interfere with other test + amazonSQS.deleteMessage(sendQueueURl, result.getMessages().get(0).getReceiptHandle()); + } + + @Test + public void givenMessageSent_whenMessageReceived_thenSuccess() throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(5); + springCloudSQS.setCountDownLatch(countDownLatch); + + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + for (int i = 0; i < 5; i++) { + amazonSQS.sendMessage(receiveQueueUrl, "Hello World " + i); + logger.info("Sent message {}, waiting for 1 second", i + 1); + Thread.sleep(1000L); + } + countDownLatch.await(); + } + + @AfterClass + public static void cleanupAwsResources() { + AmazonSQS amazonSQS = SpringCloudAwsTestUtil.amazonSQS(); + PurgeQueueRequest receiveQueuePurge = new PurgeQueueRequest(receiveQueueUrl); + amazonSQS.purgeQueue(receiveQueuePurge); + amazonSQS.deleteQueue(receiveQueueUrl); + + PurgeQueueRequest sendQueuePurge = new PurgeQueueRequest(sendQueueURl); + amazonSQS.purgeQueue(sendQueuePurge); + amazonSQS.deleteQueue(sendQueueURl); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties b/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties new file mode 100644 index 0000000000..0d3d90b03a --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/resources/application-test.properties @@ -0,0 +1,4 @@ +# Don't try to create DataSouce when running tests which don't need a DataSource +spring.autoconfigure.exclude=\ + org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration,\ + org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration diff --git a/spring-cloud/spring-cloud-stream/README.md b/spring-cloud/spring-cloud-stream/README.md new file mode 100644 index 0000000000..5ecb852df5 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Introduction to Spring Cloud Stream](http://www.baeldung.com/spring-cloud-stream) diff --git a/spring-cloud/spring-cloud-stream/pom.xml b/spring-cloud/spring-cloud-stream/pom.xml new file mode 100644 index 0000000000..5ec24268d9 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + org.baeldung + spring-cloud-stream + pom + + spring-cloud-stream + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + + + spring-cloud-stream-rabbit + + + + UTF-8 + 3.6.0 + + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + ${spring-cloud-stream.version} + + + + org.springframework.cloud + spring-cloud-stream + ${spring-cloud-stream.version} + + + + org.springframework.cloud + spring-cloud-stream-test-support + ${spring-cloud-stream.version} + test + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + + diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml new file mode 100644 index 0000000000..a954a7035e --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/pom.xml @@ -0,0 +1,32 @@ + + + 4.0.0 + + spring-cloud-stream-rabbit + jar + + spring-cloud-stream-rabbit + Simple Spring Cloud Stream + + + org.baeldung + spring-cloud-stream + 1.0.0-SNAPSHOT + .. + + + + + org.springframework.cloud + spring-cloud-starter-stream-rabbit + + + + org.springframework.cloud + spring-cloud-stream-test-support + test + + + + diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java new file mode 100644 index 0000000000..375494dfac --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplication.java @@ -0,0 +1,38 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@SpringBootApplication +@EnableBinding(MyProcessor.class) +public class MultipleOutputsServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleOutputsServiceApplication.class, args); + } + + @Autowired + private MyProcessor processor; + + @StreamListener(MyProcessor.INPUT) + public void routeValues(Integer val) { + if (val < 10) { + processor.anOutput() + .send(message(val)); + } else { + processor.anotherOutput() + .send(message(val)); + } + } + + private static final Message message(T val) { + return MessageBuilder.withPayload(val) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java new file mode 100644 index 0000000000..4729e418b6 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceApplication.java @@ -0,0 +1,39 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.messaging.Message; +import org.springframework.messaging.support.MessageBuilder; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@SpringBootApplication +@EnableBinding(MyProcessor.class) +public class MultipleOutputsWithConditionsServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleOutputsWithConditionsServiceApplication.class, args); + } + + @Autowired + private MyProcessor processor; + + @StreamListener(target = MyProcessor.INPUT, condition = "payload < 10") + public void routeValuesToAnOutput(Integer val) { + processor.anOutput() + .send(message(val)); + } + + @StreamListener(target = MyProcessor.INPUT, condition = "payload >= 10") + public void routeValuesToAnotherOutput(Integer val) { + processor.anotherOutput() + .send(message(val)); + } + + private static final Message message(T val) { + return MessageBuilder.withPayload(val) + .build(); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java new file mode 100644 index 0000000000..aac551e544 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerServiceApplication.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding; +import org.springframework.cloud.stream.annotation.StreamListener; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.context.annotation.Bean; +import org.springframework.messaging.converter.MessageConverter; +import org.springframework.messaging.handler.annotation.SendTo; + +import com.baeldung.spring.cloud.stream.rabbit.messages.TextPlainMessageConverter; +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +@SpringBootApplication +@EnableBinding(Processor.class) +public class MyLoggerServiceApplication { + public static void main(String[] args) { + SpringApplication.run(MyLoggerServiceApplication.class, args); + } + + @Bean + public MessageConverter providesTextPlainMessageConverter() { + return new TextPlainMessageConverter(); + } + + @StreamListener(Processor.INPUT) + @SendTo(Processor.OUTPUT) + public LogMessage enrichLogMessage(LogMessage log) { + return new LogMessage(String.format("[1]: %s", log.getMessage())); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java new file mode 100644 index 0000000000..d690ee38a9 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/messages/TextPlainMessageConverter.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.cloud.stream.rabbit.messages; + +import org.springframework.messaging.Message; +import org.springframework.messaging.converter.AbstractMessageConverter; +import org.springframework.util.MimeType; + +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +public class TextPlainMessageConverter extends AbstractMessageConverter { + + public TextPlainMessageConverter() { + super(new MimeType("text", "plain")); + } + + @Override + protected boolean supports(Class> clazz) { + return (LogMessage.class == clazz); + } + + @Override + protected Object convertFromInternal(Message> message, Class> targetClass, Object conversionHint) { + Object payload = message.getPayload(); + String text = payload instanceof String ? (String) payload : new String((byte[]) payload); + return new LogMessage(text); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java new file mode 100644 index 0000000000..44a6ca4d4e --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/model/LogMessage.java @@ -0,0 +1,32 @@ +package com.baeldung.spring.cloud.stream.rabbit.model; + +import java.io.Serializable; + +public class LogMessage implements Serializable { + + private static final long serialVersionUID = -5857383701708275796L; + + private String message; + + public LogMessage() { + + } + + public LogMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return message; + } + +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java new file mode 100644 index 0000000000..563ce06b6f --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/java/com/baeldung/spring/cloud/stream/rabbit/processor/MyProcessor.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.cloud.stream.rabbit.processor; + +import org.springframework.cloud.stream.annotation.Input; +import org.springframework.cloud.stream.annotation.Output; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.SubscribableChannel; + +public interface MyProcessor { + String INPUT = "myInput"; + + @Input + SubscribableChannel myInput(); + + @Output("myOutput") + MessageChannel anOutput(); + + @Output + MessageChannel anotherOutput(); +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml new file mode 100644 index 0000000000..3d9d97a736 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + cloud: + stream: + bindings: + input: + destination: queue.log.messages + binder: local_rabbit + group: logMessageConsumers + output: + destination: queue.pretty.log.messages + binder: local_rabbit + binders: + local_rabbit: + type: rabbit + environment: + spring: + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest + virtual-host: / +server: + port: 0 +management: + health: + binders: + enabled: true \ No newline at end of file diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java new file mode 100644 index 0000000000..898d06897f --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsServiceApplicationIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MultipleOutputsServiceApplication.class) +@DirtiesContext +public class MultipleOutputsServiceApplicationIntegrationTest { + + @Autowired + private MyProcessor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseIsInAOutput() { + whenSendMessage(1); + thenPayloadInChannelIs(pipe.anOutput(), 1); + } + + @Test + public void whenSendMessage_thenResponseIsInAnotherOutput() { + whenSendMessage(11); + thenPayloadInChannelIs(pipe.anotherOutput(), 11); + } + + private void whenSendMessage(Integer val) { + pipe.myInput() + .send(MessageBuilder.withPayload(val) + .build()); + } + + private void thenPayloadInChannelIs(MessageChannel channel, Integer expectedValue) { + Object payload = messageCollector.forChannel(channel) + .poll() + .getPayload(); + assertEquals(expectedValue, payload); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java new file mode 100644 index 0000000000..c3bf5a1205 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MultipleOutputsWithConditionsServiceIntegrationTest.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MultipleOutputsWithConditionsServiceApplication.class) +@DirtiesContext +public class MultipleOutputsWithConditionsServiceIntegrationTest { + + @Autowired + private MyProcessor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseIsInAOutput() { + whenSendMessage(1); + thenPayloadInChannelIs(pipe.anOutput(), 1); + } + + @Test + public void whenSendMessage_thenResponseIsInAnotherOutput() { + whenSendMessage(11); + thenPayloadInChannelIs(pipe.anotherOutput(), 11); + } + + private void whenSendMessage(Integer val) { + pipe.myInput() + .send(MessageBuilder.withPayload(val) + .build()); + } + + private void thenPayloadInChannelIs(MessageChannel channel, Integer expectedValue) { + Object payload = messageCollector.forChannel(channel) + .poll() + .getPayload(); + assertEquals(expectedValue, payload); + } +} diff --git a/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java new file mode 100644 index 0000000000..21d84e79e0 --- /dev/null +++ b/spring-cloud/spring-cloud-stream/spring-cloud-stream-rabbit/src/test/java/com/baeldung/spring/cloud/stream/rabbit/MyLoggerApplicationIntegrationTest.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.cloud.stream.rabbit; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.stream.messaging.Processor; +import org.springframework.cloud.stream.test.binder.MessageCollector; +import org.springframework.messaging.support.MessageBuilder; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = MyLoggerServiceApplication.class) +@DirtiesContext +public class MyLoggerApplicationIntegrationTest { + + @Autowired + private Processor pipe; + + @Autowired + private MessageCollector messageCollector; + + @Test + public void whenSendMessage_thenResponseShouldUpdateText() { + pipe.input() + .send(MessageBuilder.withPayload(new LogMessage("This is my message")) + .build()); + + Object payload = messageCollector.forChannel(pipe.output()) + .poll() + .getPayload(); + + assertEquals("[1]: This is my message", payload.toString()); + } +} diff --git a/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationTests.java b/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java similarity index 82% rename from spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationTests.java rename to spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java index b39a5605b1..71eec9cf45 100644 --- a/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationTests.java +++ b/spring-jmeter-jenkins/src/test/java/com/baeldung/SpringJMeterJenkinsApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class SpringJMeterJenkinsApplicationTests { +public class SpringJMeterJenkinsApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/spring-boot/src/main/java/org/baeldung/dsrouting/ClientDao.java b/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/dsrouting/ClientDao.java rename to spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java diff --git a/spring-boot/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java b/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java rename to spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java diff --git a/spring-boot/src/main/java/org/baeldung/dsrouting/ClientDatabase.java b/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/dsrouting/ClientDatabase.java rename to spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java diff --git a/spring-boot/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java b/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java rename to spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java diff --git a/spring-boot/src/main/java/org/baeldung/dsrouting/ClientService.java b/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java similarity index 100% rename from spring-boot/src/main/java/org/baeldung/dsrouting/ClientService.java rename to spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java diff --git a/spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTests.java b/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java similarity index 97% rename from spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTests.java rename to spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java index 88a142fcde..f81247e3cd 100644 --- a/spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTests.java +++ b/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = DataSourceRoutingTestConfiguration.class) -public class DataSourceRoutingTests { +public class DataSourceRoutingIntegrationTest { @Autowired DataSource routingDatasource; diff --git a/spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java b/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java similarity index 89% rename from spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java rename to spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java index 595ad6ce0d..dee9d58722 100644 --- a/spring-boot/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java +++ b/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java @@ -35,19 +35,17 @@ public class DataSourceRoutingTestConfiguration { private DataSource clientADatasource() { EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder(); - EmbeddedDatabase embeddedDb = dbBuilder.setType(EmbeddedDatabaseType.H2) + return dbBuilder.setType(EmbeddedDatabaseType.H2) .setName("CLIENT_A") .addScript("classpath:dsrouting-db.sql") .build(); - return embeddedDb; } private DataSource clientBDatasource() { EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder(); - EmbeddedDatabase embeddedDb = dbBuilder.setType(EmbeddedDatabaseType.H2) + return dbBuilder.setType(EmbeddedDatabaseType.H2) .setName("CLIENT_B") .addScript("classpath:dsrouting-db.sql") .build(); - return embeddedDb; } } diff --git a/spring-boot/src/test/resources/dsrouting-db.sql b/spring-jpa/src/test/resources/dsrouting-db.sql similarity index 100% rename from spring-boot/src/test/resources/dsrouting-db.sql rename to spring-jpa/src/test/resources/dsrouting-db.sql diff --git a/spring-rest-full/src/testFile b/spring-rest-full/src/testFile new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spring-rest-full/src/testFile @@ -0,0 +1 @@ + diff --git a/spring-rest-shell/README.md b/spring-rest-shell/README.md index 06e18450c6..901d9a51ee 100644 --- a/spring-rest-shell/README.md +++ b/spring-rest-shell/README.md @@ -2,4 +2,4 @@ ### Relevant Articles -- [Spring REST Shell](http://www.baeldung.com/) \ No newline at end of file +- [Spring REST Shell](http://www.baeldung.com/spring-rest-shell) \ No newline at end of file diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java similarity index 96% rename from spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclTest.java rename to spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java index fd9069d9bc..38e1a2a9e7 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java @@ -1,119 +1,119 @@ -package org.baeldung.acl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.List; - -import org.baeldung.acl.persistence.dao.NoticeMessageRepository; -import org.baeldung.acl.persistence.entity.NoticeMessage; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; -import org.springframework.test.context.transaction.TransactionalTestExecutionListener; -import org.springframework.test.context.web.ServletTestExecutionListener; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@TestExecutionListeners(listeners={ServletTestExecutionListener.class, - DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, - TransactionalTestExecutionListener.class, - WithSecurityContextTestExecutionListener.class}) -public class SpringAclTest extends AbstractJUnit4SpringContextTests{ - - private static Integer FIRST_MESSAGE_ID = 1; - private static Integer SECOND_MESSAGE_ID = 2; - private static Integer THIRD_MESSAGE_ID = 3; - private static String EDITTED_CONTENT = "EDITED"; - - @Configuration - @ComponentScan("org.baeldung.acl.*") - public static class SpringConfig { - - } - - @Autowired - NoticeMessageRepository repo; - - @Test - @WithMockUser(username="manager") - public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){ - List details = repo.findAll(); - assertNotNull(details); - assertEquals(1,details.size()); - assertEquals(FIRST_MESSAGE_ID,details.get(0).getId()); - } - - @Test - @WithMockUser(username="manager") - public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){ - NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(firstMessage); - assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); - - firstMessage.setContent(EDITTED_CONTENT); - repo.save(firstMessage); - - NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(editedFirstMessage); - assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId()); - assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent()); - } - - @Test - @WithMockUser(username="hr") - public void givenUsernameHr_whenFindMessageById2_thenOK(){ - NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID); - assertNotNull(secondMessage); - assertEquals(SECOND_MESSAGE_ID,secondMessage.getId()); - } - - @Test(expected=AccessDeniedException.class) - @WithMockUser(username="hr") - public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){ - NoticeMessage secondMessage = new NoticeMessage(); - secondMessage.setId(SECOND_MESSAGE_ID); - secondMessage.setContent(EDITTED_CONTENT); - repo.save(secondMessage); - } - - @Test - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){ - List details = repo.findAll(); - assertNotNull(details); - assertEquals(3,details.size()); - } - - @Test - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){ - NoticeMessage thirdMessage = new NoticeMessage(); - thirdMessage.setId(THIRD_MESSAGE_ID); - thirdMessage.setContent(EDITTED_CONTENT); - repo.save(thirdMessage); - } - - @Test(expected=AccessDeniedException.class) - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){ - NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(firstMessage); - assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); - firstMessage.setContent(EDITTED_CONTENT); - repo.save(firstMessage); - } -} +package org.baeldung.acl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.baeldung.acl.persistence.dao.NoticeMessageRepository; +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextTestExecutionListener; +import org.springframework.test.context.transaction.TransactionalTestExecutionListener; +import org.springframework.test.context.web.ServletTestExecutionListener; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestExecutionListeners(listeners={ServletTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, + TransactionalTestExecutionListener.class, + WithSecurityContextTestExecutionListener.class}) +public class SpringAclIntegrationTest extends AbstractJUnit4SpringContextTests{ + + private static Integer FIRST_MESSAGE_ID = 1; + private static Integer SECOND_MESSAGE_ID = 2; + private static Integer THIRD_MESSAGE_ID = 3; + private static String EDITTED_CONTENT = "EDITED"; + + @Configuration + @ComponentScan("org.baeldung.acl.*") + public static class SpringConfig { + + } + + @Autowired + NoticeMessageRepository repo; + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(1,details.size()); + assertEquals(FIRST_MESSAGE_ID,details.get(0).getId()); + } + + @Test + @WithMockUser(username="manager") + public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + + NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(editedFirstMessage); + assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId()); + assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent()); + } + + @Test + @WithMockUser(username="hr") + public void givenUsernameHr_whenFindMessageById2_thenOK(){ + NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID); + assertNotNull(secondMessage); + assertEquals(SECOND_MESSAGE_ID,secondMessage.getId()); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(username="hr") + public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){ + NoticeMessage secondMessage = new NoticeMessage(); + secondMessage.setId(SECOND_MESSAGE_ID); + secondMessage.setContent(EDITTED_CONTENT); + repo.save(secondMessage); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){ + List details = repo.findAll(); + assertNotNull(details); + assertEquals(3,details.size()); + } + + @Test + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){ + NoticeMessage thirdMessage = new NoticeMessage(); + thirdMessage.setId(THIRD_MESSAGE_ID); + thirdMessage.setContent(EDITTED_CONTENT); + repo.save(thirdMessage); + } + + @Test(expected=AccessDeniedException.class) + @WithMockUser(roles={"EDITOR"}) + public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){ + NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); + assertNotNull(firstMessage); + assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); + firstMessage.setContent(EDITTED_CONTENT); + repo.save(firstMessage); + } +} \ No newline at end of file diff --git a/testing-modules/README.md b/testing-modules/README.md new file mode 100644 index 0000000000..3fbeea6188 --- /dev/null +++ b/testing-modules/README.md @@ -0,0 +1,3 @@ + +## Testing Modules + diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 229703ccf5..2be8937d04 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -20,7 +20,7 @@ UTF-8 1.8 - 5.0.1 + 5.0.2 1.0.1 4.12.1 2.8.2 @@ -127,4 +127,4 @@ - \ No newline at end of file + diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java new file mode 100644 index 0000000000..43b39d6859 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/mockito/java8/LazyVerificationTest.java @@ -0,0 +1,34 @@ +package com.baeldung.mockito.java8; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.util.List; + +import org.junit.Test; +import org.mockito.exceptions.base.MockitoAssertionError; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.VerificationCollector; + +public class LazyVerificationTest { + + @Test + public void whenLazilyVerified_thenReportsMultipleFailures() { + VerificationCollector collector = MockitoJUnit.collector() + .assertLazily(); + + List mockList = mock(List.class); + verify(mockList).add("one"); + verify(mockList).clear(); + + try { + collector.collectAndReport(); + } catch (MockitoAssertionError error) { + assertTrue(error.getMessage() + .contains("1. Wanted but not invoked:")); + assertTrue(error.getMessage() + .contains("2. Wanted but not invoked:")); + } + } +} diff --git a/testing-modules/mockito/README.md b/testing-modules/mockito/README.md index 2407a5c3c5..0d6f69a64f 100644 --- a/testing-modules/mockito/README.md +++ b/testing-modules/mockito/README.md @@ -11,3 +11,4 @@ - [Mockito’s Mock Methods](http://www.baeldung.com/mockito-mock-methods) - [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock) - [Mocking Exception Throwing using Mockito](http://www.baeldung.com/mockito-exceptions) +- [Mocking Void Methods with Mockito](http://www.baeldung.com/mockito-void-methods) diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java new file mode 100644 index 0000000000..3824de619c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/FinalList.java @@ -0,0 +1,10 @@ +package org.baeldung.mockito; + +public class FinalList extends MyList { + + @Override + public int size() { + return 1; + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java new file mode 100644 index 0000000000..5f064e1355 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockFinals.java @@ -0,0 +1,35 @@ +package org.baeldung.mockito; + +import org.junit.Test; + +import static org.junit.Assert.assertNotEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MockFinals { + + @Test + public void whenMockFinalClassMockWorks() { + + FinalList finalList = new FinalList(); + + FinalList mock = mock(FinalList.class); + when(mock.size()).thenReturn(2); + + assertNotEquals(mock.size(), finalList.size()); + + } + + @Test + public void whenMockFinalMethodMockWorks() { + + MyList myList = new MyList(); + + MyList mock = mock(MyList.class); + when(mock.finalMethod()).thenReturn(1); + + assertNotEquals(mock.finalMethod(), myList.finalMethod()); + } + + + } diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java index 0b501225ad..4fcddb3164 100644 --- a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyList.java @@ -19,4 +19,7 @@ class MyList extends AbstractList { // no-op } + final public int finalMethod() { + return 0; + } } diff --git a/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker new file mode 100644 index 0000000000..ca6ee9cea8 --- /dev/null +++ b/testing-modules/mockito/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker @@ -0,0 +1 @@ +mock-maker-inline \ No newline at end of file diff --git a/testing-modules/mocks/README.md b/testing-modules/mocks/README.md index 15370b812b..d7b817c518 100644 --- a/testing-modules/mocks/README.md +++ b/testing-modules/mocks/README.md @@ -1,6 +1,5 @@ ## Relevant articles: -- [Introduction to MockServer](http://www.baeldung.com/mockserver) - [JMockit Advanced Usage](http://www.baeldung.com/jmockit-advanced-usage) - [A Guide to JMockit Expectations](http://www.baeldung.com/jmockit-expectations) - [JMockit 101](http://www.baeldung.com/jmockit-101) diff --git a/testing-modules/rest-testing/README.md b/testing-modules/rest-testing/README.md index 37a53dd815..c6185de05f 100644 --- a/testing-modules/rest-testing/README.md +++ b/testing-modules/rest-testing/README.md @@ -10,3 +10,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Introduction to WireMock](http://www.baeldung.com/introduction-to-wiremock) - [REST API Testing with Cucumber](http://www.baeldung.com/cucumber-rest-api-testing) - [Testing a REST API with JBehave](http://www.baeldung.com/jbehave-rest-testing) +- [REST API Testing with Karate](http://www.baeldung.com/karate-rest-api-testing) diff --git a/testing-modules/testing/README.md b/testing-modules/testing/README.md index 889f6706d4..143cb792cf 100644 --- a/testing-modules/testing/README.md +++ b/testing-modules/testing/README.md @@ -15,3 +15,4 @@ - [Cucumber Java 8 Support](http://www.baeldung.com/cucumber-java-8-support) - [Introduction to Lambda Behave](http://www.baeldung.com/lambda-behave) - [Introduction to Jukito](http://www.baeldung.com/jukito) +- [Custom JUnit 4 Test Runners](http://www.baeldung.com/junit-4-custom-runners)