diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..40f5c88746 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Eugen Paraschiv + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d94a786bc2..271aea0767 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,14 @@ The "REST with Spring" Classes ============================== + After 5 months of work, here's the Master Class of REST With Spring:
**[>> THE REST WITH SPRING MASTER CLASS](http://www.baeldung.com/rest-with-spring-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=rws#master-class)** +And here's the Master Class of Learn Spring Security:
+**[>> LEARN SPRING SECURITY MASTER CLASS](http://www.baeldung.com/learn-spring-security-course?utm_source=github&utm_medium=social&utm_content=tutorials&utm_campaign=lss#master-class)** + + Spring Tutorials ================ diff --git a/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java b/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java new file mode 100644 index 0000000000..e2af4f8808 --- /dev/null +++ b/apache-poi/src/main/java/com/baeldung/poi/powerpoint/PowerPointHelper.java @@ -0,0 +1,224 @@ +package com.baeldung.poi.powerpoint; + +import org.apache.poi.sl.usermodel.AutoNumberingScheme; +import org.apache.poi.sl.usermodel.PictureData; +import org.apache.poi.sl.usermodel.TableCell; +import org.apache.poi.sl.usermodel.TextParagraph; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xslf.usermodel.*; + +import java.awt.*; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Helper class for the PowerPoint presentation creation + */ +public class PowerPointHelper { + + /** + * Read an existing presentation + * + * @param fileLocation + * File location of the presentation + * @return instance of {@link XMLSlideShow} + * @throws IOException + */ + public XMLSlideShow readingExistingSlideShow(String fileLocation) throws IOException { + return new XMLSlideShow(new FileInputStream(fileLocation)); + } + + /** + * Create a sample presentation + * + * @param fileLocation + * File location of the presentation + * @throws IOException + */ + public void createPresentation(String fileLocation) throws IOException { + // Create presentation + XMLSlideShow ppt = new XMLSlideShow(); + + XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0); + + // Retriving the slide layout + XSLFSlideLayout layout = defaultMaster.getLayout(SlideLayout.TITLE_ONLY); + + // Creating the 1st slide + XSLFSlide slide1 = ppt.createSlide(layout); + XSLFTextShape title = slide1.getPlaceholder(0); + // Clearing text to remove the predefined one in the template + title.clearText(); + XSLFTextParagraph p = title.addNewTextParagraph(); + + XSLFTextRun r1 = p.addNewTextRun(); + r1.setText("Baeldung"); + r1.setFontColor(new Color(78, 147, 89)); + r1.setFontSize(48.); + + // Add Image + ClassLoader classLoader = getClass().getClassLoader(); + byte[] pictureData = IOUtils.toByteArray(new FileInputStream(classLoader.getResource("logo-leaf.png").getFile())); + + XSLFPictureData pd = ppt.addPicture(pictureData, PictureData.PictureType.PNG); + XSLFPictureShape picture = slide1.createPicture(pd); + picture.setAnchor(new Rectangle(320, 230, 100, 92)); + + // Creating 2nd slide + layout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT); + XSLFSlide slide2 = ppt.createSlide(layout); + + // setting the tile + title = slide2.getPlaceholder(0); + title.clearText(); + XSLFTextRun r = title.addNewTextParagraph().addNewTextRun(); + r.setText("Baeldung"); + + // Adding the link + XSLFHyperlink link = r.createHyperlink(); + link.setAddress("http://www.baeldung.com"); + + // setting the content + XSLFTextShape content = slide2.getPlaceholder(1); + content.clearText(); // unset any existing text + content.addNewTextParagraph().addNewTextRun().setText("First paragraph"); + content.addNewTextParagraph().addNewTextRun().setText("Second paragraph"); + content.addNewTextParagraph().addNewTextRun().setText("Third paragraph"); + + // Creating 3rd slide - List + layout = defaultMaster.getLayout(SlideLayout.TITLE_AND_CONTENT); + XSLFSlide slide3 = ppt.createSlide(layout); + title = slide3.getPlaceholder(0); + title.clearText(); + r = title.addNewTextParagraph().addNewTextRun(); + r.setText("Lists"); + + content = slide3.getPlaceholder(1); + content.clearText(); + XSLFTextParagraph p1 = content.addNewTextParagraph(); + p1.setIndentLevel(0); + p1.setBullet(true); + r1 = p1.addNewTextRun(); + r1.setText("Bullet"); + + // the next three paragraphs form an auto-numbered list + XSLFTextParagraph p2 = content.addNewTextParagraph(); + p2.setBulletAutoNumber(AutoNumberingScheme.alphaLcParenRight, 1); + p2.setIndentLevel(1); + XSLFTextRun r2 = p2.addNewTextRun(); + r2.setText("Numbered List Item - 1"); + + // Creating 4th slide + XSLFSlide slide4 = ppt.createSlide(); + createTable(slide4); + + // Save presentation + FileOutputStream out = new FileOutputStream(fileLocation); + ppt.write(out); + out.close(); + + // Closing presentation + ppt.close(); + } + + /** + * Delete a slide from the presentation + * + * @param ppt + * The presentation + * @param slideNumber + * The number of the slide to be deleted (0-based) + */ + public void deleteSlide(XMLSlideShow ppt, int slideNumber) { + ppt.removeSlide(slideNumber); + } + + /** + * Re-order the slides inside a presentation + * + * @param ppt + * The presentation + * @param slideNumber + * The number of the slide to move + * @param newSlideNumber + * The new position of the slide (0-base) + */ + public void reorderSlide(XMLSlideShow ppt, int slideNumber, int newSlideNumber) { + List slides = ppt.getSlides(); + + XSLFSlide secondSlide = slides.get(slideNumber); + ppt.setSlideOrder(secondSlide, newSlideNumber); + } + + /** + * Retrieve the placeholder inside a slide + * + * @param slide + * The slide + * @return List of placeholder inside a slide + */ + public List retrieveTemplatePlaceholders(XSLFSlide slide) { + List placeholders = new ArrayList<>(); + + for (XSLFShape shape : slide.getShapes()) { + if (shape instanceof XSLFAutoShape) { + placeholders.add(shape); + } + } + return placeholders; + } + + /** + * Create a table + * + * @param slide + * Slide + */ + private void createTable(XSLFSlide slide) { + + XSLFTable tbl = slide.createTable(); + tbl.setAnchor(new Rectangle(50, 50, 450, 300)); + + int numColumns = 3; + int numRows = 5; + + // header + XSLFTableRow headerRow = tbl.addRow(); + headerRow.setHeight(50); + for (int i = 0; i < numColumns; i++) { + XSLFTableCell th = headerRow.addCell(); + XSLFTextParagraph p = th.addNewTextParagraph(); + p.setTextAlign(TextParagraph.TextAlign.CENTER); + XSLFTextRun r = p.addNewTextRun(); + r.setText("Header " + (i + 1)); + r.setBold(true); + r.setFontColor(Color.white); + th.setFillColor(new Color(79, 129, 189)); + th.setBorderWidth(TableCell.BorderEdge.bottom, 2.0); + th.setBorderColor(TableCell.BorderEdge.bottom, Color.white); + // all columns are equally sized + tbl.setColumnWidth(i, 150); + } + + // data + for (int rownum = 0; rownum < numRows; rownum++) { + XSLFTableRow tr = tbl.addRow(); + tr.setHeight(50); + for (int i = 0; i < numColumns; i++) { + XSLFTableCell cell = tr.addCell(); + XSLFTextParagraph p = cell.addNewTextParagraph(); + XSLFTextRun r = p.addNewTextRun(); + + r.setText("Cell " + (i * rownum + 1)); + if (rownum % 2 == 0) { + cell.setFillColor(new Color(208, 216, 232)); + } else { + cell.setFillColor(new Color(233, 247, 244)); + } + } + } + } +} diff --git a/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java new file mode 100644 index 0000000000..5319208e85 --- /dev/null +++ b/apache-poi/src/test/java/com/baeldung/poi/powerpoint/PowerPointIntegrationTest.java @@ -0,0 +1,77 @@ +package com.baeldung.poi.powerpoint; + +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFShape; +import org.apache.poi.xslf.usermodel.XSLFSlide; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.List; + +public class PowerPointIntegrationTest { + + private PowerPointHelper pph; + private String fileLocation; + private static final String FILE_NAME = "presentation.pptx"; + + @Before + public void setUp() throws Exception { + File currDir = new File("."); + String path = currDir.getAbsolutePath(); + fileLocation = path.substring(0, path.length() - 1) + FILE_NAME; + + pph = new PowerPointHelper(); + pph.createPresentation(fileLocation); + } + + @Test + public void whenReadingAPresentation_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + + Assert.assertNotNull(xmlSlideShow); + Assert.assertEquals(4, xmlSlideShow.getSlides().size()); + } + + @Test + public void whenRetrievingThePlaceholdersForEachSlide_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + + List onlyTitleSlidePlaceholders = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(0)); + List titleAndBodySlidePlaceholders = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(1)); + List emptySlidePlaceholdes = pph.retrieveTemplatePlaceholders(xmlSlideShow.getSlides().get(3)); + + Assert.assertEquals(1, onlyTitleSlidePlaceholders.size()); + Assert.assertEquals(2, titleAndBodySlidePlaceholders.size()); + Assert.assertEquals(0, emptySlidePlaceholdes.size()); + + } + + @Test + public void whenSortingSlides_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + XSLFSlide slide4 = xmlSlideShow.getSlides().get(3); + pph.reorderSlide(xmlSlideShow, 3, 1); + + Assert.assertEquals(slide4, xmlSlideShow.getSlides().get(1)); + } + + @Test + public void givenPresentation_whenDeletingASlide_thenOK() throws Exception { + XMLSlideShow xmlSlideShow = pph.readingExistingSlideShow(fileLocation); + pph.deleteSlide(xmlSlideShow, 3); + + Assert.assertEquals(3, xmlSlideShow.getSlides().size()); + } + + @After + public void tearDown() throws Exception { + File testFile = new File(fileLocation); + if (testFile.exists()) { + testFile.delete(); + } + pph = null; + } +} diff --git a/bootique/dependency-reduced-pom.xml b/bootique/dependency-reduced-pom.xml index ed18f4e42a..ab09cfb7b1 100644 --- a/bootique/dependency-reduced-pom.xml +++ b/bootique/dependency-reduced-pom.xml @@ -28,8 +28,14 @@ junit junit - 3.8.1 + 4.12 test + + + hamcrest-core + org.hamcrest + + diff --git a/cas/cas-secured-app/pom.xml b/cas/cas-secured-app/pom.xml index 543354e8b3..d52597412e 100644 --- a/cas/cas-secured-app/pom.xml +++ b/cas/cas-secured-app/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.M7 @@ -87,14 +87,6 @@ - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - spring-milestones Spring Milestones @@ -106,14 +98,6 @@ - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - spring-milestones Spring Milestones diff --git a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java index 703e6abf7a..7faccbb125 100644 --- a/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java +++ b/cas/cas-secured-app/src/main/java/com/baeldung/cassecuredapp/controllers/AuthController.java @@ -1,6 +1,7 @@ package com.baeldung.cassecuredapp.controllers; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler; @@ -15,7 +16,7 @@ import javax.servlet.http.HttpServletResponse; @Controller public class AuthController { - private Logger logger = Logger.getLogger(AuthController.class); + private Logger logger = LogManager.getLogger(AuthController.class); @GetMapping("/logout") public String logout( diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml index f5506f095e..17d330b3b8 100644 --- a/core-java-8/pom.xml +++ b/core-java-8/pom.xml @@ -1,258 +1,276 @@ - - 4.0.0 - com.baeldung - core-java-8 - 0.1.0-SNAPSHOT - jar - - core-java-8 - - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - - log4j - log4j - 1.2.17 - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - - org.assertj - assertj-core - ${assertj.version} - test - - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - - - - core-java-8 - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - - - - - - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - - - - - - - - 21.0 - 3.5 - 3.6.1 - 2.5 - 4.1 - 4.01 - 1.10 - 1.16.12 - - - 3.6.1 - 1.7.0 - - + + 4.0.0 + com.baeldung + core-java-8 + 0.1.0-SNAPSHOT + jar + + core-java-8 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + + log4j + log4j + 1.2.17 + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + org.openjdk.jmh + jmh-core + 1.19 + + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + + org.openjdk.jmh + jmh-generator-bytecode + 1.19 + + + + + + core-java-8 + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + + 21.0 + 3.5 + 3.6.1 + 2.5 + 4.1 + 4.01 + 1.10 + 1.16.12 + + + 3.6.1 + 1.7.0 + + \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java new file mode 100644 index 0000000000..2a42a166fa --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java @@ -0,0 +1,45 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; + +import com.baeldung.counter.CounterUtil.MutableInteger; + +@Fork(value = 1, warmups = 3) +@BenchmarkMode(Mode.All) +public class CounterStatistics { + + private static final Map counterMap = new HashMap<>(); + private static final Map counterWithMutableIntMap = new HashMap<>(); + private static final Map counterWithIntArrayMap = new HashMap<>(); + private static final Map counterWithLongWrapperMap = new HashMap<>(); + + @Benchmark + public void wrapperAsCounter() { + CounterUtil.counterWithWrapperObject(counterMap); + } + + @Benchmark + public void lambdaExpressionWithWrapper() { + CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap); + } + + @Benchmark + public void mutableIntegerAsCounter() { + CounterUtil.counterWithMutableInteger(counterWithMutableIntMap); + } + + @Benchmark + public void primitiveArrayAsCounter() { + CounterUtil.counterWithPrimitiveArray(counterWithIntArrayMap); + } + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java new file mode 100644 index 0000000000..657b510452 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java @@ -0,0 +1,53 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.baeldung.counter.CounterUtil.MutableInteger; + +public class CounterTest { + + @Test + public void whenMapWithWrapperAsCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithWrapperObject(counterMap); + + assertEquals(3, counterMap.get("China") + .intValue()); + assertEquals(2, counterMap.get("India") + .intValue()); + } + + @Test + public void whenMapWithLambdaAndWrapperCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithLambdaAndWrapper(counterMap); + + assertEquals(3l, counterMap.get("China") + .longValue()); + assertEquals(2l, counterMap.get("India") + .longValue()); + } + + @Test + public void whenMapWithMutableIntegerCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithMutableInteger(counterMap); + assertEquals(3, counterMap.get("China") + .getCount()); + assertEquals(2, counterMap.get("India") + .getCount()); + } + + @Test + public void whenMapWithPrimitiveArray_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithPrimitiveArray(counterMap); + assertEquals(3, counterMap.get("China")[0]); + assertEquals(2, counterMap.get("India")[0]); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java new file mode 100644 index 0000000000..647fbfb0cc --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java @@ -0,0 +1,61 @@ +package com.baeldung.counter; + +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CounterUtil { + + private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" }; + + public static void counterWithWrapperObject(Map counterMap) { + for (String country : COUNTRY_NAMES) { + counterMap.compute(country, (k, v) -> v == null ? 1 : v + 1); + } + } + + public static void counterWithLambdaAndWrapper(Map counterMap) { + counterMap.putAll(Stream.of(COUNTRY_NAMES) + .parallel() + .collect(Collectors.groupingBy(k -> k, Collectors.counting()))); + } + + public static class MutableInteger { + int count; + + public MutableInteger(int count) { + this.count = count; + } + + public void increment() { + this.count++; + } + + public int getCount() { + return this.count; + } + } + + public static void counterWithMutableInteger(Map counterMap) { + for (String country : COUNTRY_NAMES) { + MutableInteger oldValue = counterMap.get(country); + if (oldValue != null) { + oldValue.increment(); + } else { + counterMap.put(country, new MutableInteger(1)); + } + } + } + + public static void counterWithPrimitiveArray(Map counterMap) { + for (String country : COUNTRY_NAMES) { + int[] oldCounter = counterMap.get(country); + if (oldCounter != null) { + oldCounter[0] += 1; + } else { + counterMap.put(country, new int[] { 1 }); + } + } + } + +} diff --git a/core-java-9/compile-httpclient.bat b/core-java-9/compile-httpclient.bat new file mode 100644 index 0000000000..9d845784cf --- /dev/null +++ b/core-java-9/compile-httpclient.bat @@ -0,0 +1,3 @@ +javac --module-path mods -d mods/com.baeldung.httpclient^ + src/modules/com.baeldung.httpclient/module-info.java^ + src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java \ No newline at end of file diff --git a/core-java-9/run-httpclient.bat b/core-java-9/run-httpclient.bat new file mode 100644 index 0000000000..60b1eb7f68 --- /dev/null +++ b/core-java-9/run-httpclient.bat @@ -0,0 +1 @@ +java --module-path mods -m com.baeldung.httpclient/com.baeldung.httpclient.HttpClientExample \ No newline at end of file diff --git a/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java b/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java new file mode 100644 index 0000000000..de08c2164e --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.httpclient/com/baeldung/httpclient/HttpClientExample.java @@ -0,0 +1,84 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.baeldung.httpclient; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import jdk.incubator.http.HttpClient; +import jdk.incubator.http.HttpRequest; +import jdk.incubator.http.HttpRequest.BodyProcessor; +import jdk.incubator.http.HttpResponse; +import jdk.incubator.http.HttpResponse.BodyHandler; + +/** + * + * @author pkaria + */ +public class HttpClientExample { + + public static void main(String[] args) throws Exception { + httpGetRequest(); + httpPostRequest(); + asynchronousRequest(); + asynchronousMultipleRequests(); + } + + public static void httpGetRequest() throws URISyntaxException, IOException, InterruptedException { + HttpClient client = HttpClient.newHttpClient(); + URI httpURI = new URI("http://jsonplaceholder.typicode.com/posts/1"); + HttpRequest request = HttpRequest.newBuilder(httpURI).GET() + .headers("Accept-Enconding", "gzip, deflate").build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandler.asString()); + String responseBody = response.body(); + int responseStatusCode = response.statusCode(); + System.out.println(responseBody); + } + + public static void httpPostRequest() throws URISyntaxException, IOException, InterruptedException { + HttpClient client = HttpClient + .newBuilder() + .build(); + HttpRequest request = HttpRequest + .newBuilder(new URI("http://jsonplaceholder.typicode.com/posts")) + .POST(BodyProcessor.fromString("Sample Post Request")) + .build(); + HttpResponse response + = client.send(request, HttpResponse.BodyHandler.asString()); + String responseBody = response.body(); + System.out.println(responseBody); + } + + public static void asynchronousRequest() throws URISyntaxException { + HttpClient client = HttpClient.newHttpClient(); + URI httpURI = new URI("http://jsonplaceholder.typicode.com/posts/1"); + HttpRequest request = HttpRequest.newBuilder(httpURI).GET().build(); + CompletableFuture> futureResponse = client.sendAsync(request, + HttpResponse.BodyHandler.asString()); + } + + public static void asynchronousMultipleRequests() throws URISyntaxException { + List targets = Arrays.asList(new URI("http://jsonplaceholder.typicode.com/posts/1"), new URI("http://jsonplaceholder.typicode.com/posts/2")); + HttpClient client = HttpClient.newHttpClient(); + List> futures = targets + .stream() + .map(target -> client + .sendAsync( + HttpRequest.newBuilder(target) + .GET() + .build(), + BodyHandler.asFile(Paths.get("base", target.getPath()))) + .thenApply(response -> response.body()) + .thenApply(path -> path.toFile())) + .collect(Collectors.toList()); + } +} diff --git a/core-java-9/src/modules/com.baeldung.httpclient/module-info.java b/core-java-9/src/modules/com.baeldung.httpclient/module-info.java new file mode 100644 index 0000000000..205c9ea725 --- /dev/null +++ b/core-java-9/src/modules/com.baeldung.httpclient/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.httpclient { + requires jdk.incubator.httpclient; +} diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java index d742d3a55f..4d87978070 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java @@ -3,7 +3,6 @@ package com.baeldung.concurrent.daemon; public class NewThread extends Thread { public void run() { - long startTime = System.currentTimeMillis(); while (true) { for (int i = 0; i < 10; i++) { diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java new file mode 100644 index 0000000000..9b850c4153 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Data.java @@ -0,0 +1,33 @@ +package com.baeldung.concurrent.waitandnotify; + +public class Data { + private String packet; + + // True if receiver should wait + // False if sender should wait + private boolean transfer = true; + + public synchronized String receive() { + while (transfer) { + try { + wait(); + } catch (InterruptedException e) {} + } + transfer = true; + + notifyAll(); + return packet; + } + + public synchronized void send(String packet) { + while (!transfer) { + try { + wait(); + } catch (InterruptedException e) {} + } + transfer = false; + + this.packet = packet; + notifyAll(); + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java new file mode 100644 index 0000000000..d4fd1574c6 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/NetworkDriver.java @@ -0,0 +1,12 @@ +package com.baeldung.concurrent.waitandnotify; + +public class NetworkDriver { + public static void main(String[] args) { + Data data = new Data(); + Thread sender = new Thread(new Sender(data)); + Thread receiver = new Thread(new Receiver(data)); + + sender.start(); + receiver.start(); + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java new file mode 100644 index 0000000000..63f48b8031 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Receiver.java @@ -0,0 +1,25 @@ +package com.baeldung.concurrent.waitandnotify; + +import java.util.concurrent.ThreadLocalRandom; + +public class Receiver implements Runnable { + private Data load; + + public Receiver(Data load) { + this.load = load; + } + + public void run() { + for(String receivedMessage = load.receive(); + !"End".equals(receivedMessage) ; + receivedMessage = load.receive()) { + + System.out.println(receivedMessage); + + //Thread.sleep() to mimic heavy server-side processing + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) {} + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java new file mode 100644 index 0000000000..b7d782c3f5 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/waitandnotify/Sender.java @@ -0,0 +1,30 @@ +package com.baeldung.concurrent.waitandnotify; + +import java.util.concurrent.ThreadLocalRandom; + +public class Sender implements Runnable { + private Data data; + + public Sender(Data data) { + this.data = data; + } + + public void run() { + String packets[] = { + "First packet", + "Second packet", + "Third packet", + "Fourth packet", + "End" + }; + + for (String packet : packets) { + data.send(packet); + + //Thread.sleep() to mimic heavy server-side processing + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) {} + } + } +} \ No newline at end of file diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java index 17b71aa35b..7e2bf590fd 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.concurrent.*; import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.fail; public class WaitingForThreadsToFinishTest { @@ -40,16 +39,13 @@ public class WaitingForThreadsToFinishTest { CountDownLatch latch = new CountDownLatch(2); for (int i = 0; i < 2; i++) { - WORKER_THREAD_POOL.submit(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(1000); - latch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - Thread.currentThread().interrupt(); - } + WORKER_THREAD_POOL.submit(() -> { + try { + Thread.sleep(1000); + latch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + Thread.currentThread().interrupt(); } }); } @@ -83,13 +79,9 @@ public class WaitingForThreadsToFinishTest { awaitTerminationAfterShutdown(WORKER_THREAD_POOL); try { - WORKER_THREAD_POOL.submit(new Callable() { - @Override - public String call() throws Exception { - fail("This thread should have been rejected !"); - Thread.sleep(1000000); - return null; - } + WORKER_THREAD_POOL.submit((Callable) () -> { + Thread.sleep(1000000); + return null; }); } catch (RejectedExecutionException ex) { // 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 index 8c1bdbf787..70854f013f 100644 --- 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 @@ -1,7 +1,11 @@ package com.baeldung.concurrent.stopping; +import com.jayway.awaitility.Awaitility; import org.junit.Test; +import java.util.concurrent.TimeUnit; + +import static com.jayway.awaitility.Awaitility.await; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -22,11 +26,10 @@ public class StopThreadTest { // Stop it and make sure the flags have been reversed controlSubThread.stop(); - Thread.sleep(interval); - assertTrue(controlSubThread.isStopped()); + await() + .until(() -> assertTrue(controlSubThread.isStopped())); } - @Test public void whenInterruptedThreadIsStopped() throws InterruptedException { @@ -44,7 +47,8 @@ public class StopThreadTest { controlSubThread.interrupt(); // Wait less than the time we would normally sleep, and make sure we exited. - Thread.sleep(interval/10); - assertTrue(controlSubThread.isStopped()); + Awaitility.await() + .atMost(interval/ 10, TimeUnit.MILLISECONDS) + .until(controlSubThread::isStopped); } } diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java new file mode 100644 index 0000000000..49f4313e9d --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/waitandnotify/NetworkIntegrationTest.java @@ -0,0 +1,65 @@ +package com.baeldung.concurrent.waitandnotify; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NetworkIntegrationTest { + + private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); + private String expected; + + @Before + public void setUpStreams() { + System.setOut(new PrintStream(outContent)); + System.setErr(new PrintStream(errContent)); + } + + @Before + public void setUpExpectedOutput() { + StringWriter expectedStringWriter = new StringWriter(); + + PrintWriter printWriter = new PrintWriter(expectedStringWriter); + printWriter.println("First packet"); + printWriter.println("Second packet"); + printWriter.println("Third packet"); + printWriter.println("Fourth packet"); + printWriter.close(); + + expected = expectedStringWriter.toString(); + } + + @After + public void cleanUpStreams() { + System.setOut(null); + System.setErr(null); + } + + @Test + public void givenSenderAndReceiver_whenSendingPackets_thenNetworkSynchronized() { + Data data = new Data(); + Thread sender = new Thread(new Sender(data)); + Thread receiver = new Thread(new Receiver(data)); + + sender.start(); + receiver.start(); + + //wait for sender and receiver to finish before we test against expected + try { + sender.join(); + receiver.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + assertEquals(expected, outContent.toString()); + } +} diff --git a/core-java-sun/.gitignore b/core-java-sun/.gitignore new file mode 100644 index 0000000000..3de4cc647e --- /dev/null +++ b/core-java-sun/.gitignore @@ -0,0 +1,26 @@ +*.class + +0.* + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* +.resourceCache + +# Packaged files # +*.jar +*.war +*.ear + +# Files generated by integration tests +*.txt +backup-pom.xml +/bin/ +/temp + +#IntelliJ specific +.idea/ +*.iml \ No newline at end of file diff --git a/core-java-sun/README.md b/core-java-sun/README.md new file mode 100644 index 0000000000..9cf8b26f1b --- /dev/null +++ b/core-java-sun/README.md @@ -0,0 +1,6 @@ +========= + +## Core Java Cookbooks and Examples + +### Relevant Articles: +- [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) diff --git a/core-java-sun/pom.xml b/core-java-sun/pom.xml new file mode 100644 index 0000000000..3997f47d19 --- /dev/null +++ b/core-java-sun/pom.xml @@ -0,0 +1,489 @@ + + 4.0.0 + com.baeldung + core-java-sun + 0.1.0-SNAPSHOT + jar + + core-java-sun + + + + + + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + + org.decimal4j + decimal4j + ${decimal4j.version} + + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + + + + org.unix4j + unix4j-command + ${unix4j.version} + + + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + junit + junit + ${junit.version} + test + + + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.javamoney + moneta + 1.1 + + + + org.owasp.esapi + esapi + 2.1.0.1 + + + + com.sun.messaging.mq + fscontext + ${fscontext.version} + + + com.codepoetics + protonpack + ${protonpack.version} + + + one.util + streamex + ${streamex.version} + + + io.vavr + vavr + ${vavr.version} + + + org.openjdk.jmh + jmh-core + 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + org.springframework + spring-web + 4.3.4.RELEASE + + + com.sun + tools + 1.8.0 + system + ${java.home}/../lib/tools.jar + + + + + core-java + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + org.codehaus.mojo + exec-maven-plugin + + + + run-benchmarks + + none + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + .* + + + + + + + + + + + + + 2.8.5 + + + 1.7.21 + 1.1.7 + + + 23.0 + 3.5 + 1.55 + 1.10 + 3.6.1 + 1.0.3 + 2.5 + 4.1 + 4.01 + 0.4 + 1.8.7 + 1.16.12 + 4.6-b01 + 1.13 + 0.6.5 + 0.9.0 + + + 1.3 + 4.12 + 2.8.9 + 3.6.1 + 1.7.0 + + + 3.6.0 + 2.19.1 + + \ No newline at end of file diff --git a/spring-jpa/.gitignore b/core-java-sun/src/main/java/com/baeldung/.gitignore similarity index 100% rename from spring-jpa/.gitignore rename to core-java-sun/src/main/java/com/baeldung/.gitignore diff --git a/core-java-sun/src/main/java/com/baeldung/README.md b/core-java-sun/src/main/java/com/baeldung/README.md new file mode 100644 index 0000000000..51809b2882 --- /dev/null +++ b/core-java-sun/src/main/java/com/baeldung/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [SHA-256 Hashing in Java](http://www.baeldung.com/sha-256-hashing-java) diff --git a/core-java/src/main/java/com/baeldung/javac/Positive.java b/core-java-sun/src/main/java/com/baeldung/javac/Positive.java similarity index 100% rename from core-java/src/main/java/com/baeldung/javac/Positive.java rename to core-java-sun/src/main/java/com/baeldung/javac/Positive.java diff --git a/core-java/src/main/java/com/baeldung/javac/SampleJavacPlugin.java b/core-java-sun/src/main/java/com/baeldung/javac/SampleJavacPlugin.java similarity index 100% rename from core-java/src/main/java/com/baeldung/javac/SampleJavacPlugin.java rename to core-java-sun/src/main/java/com/baeldung/javac/SampleJavacPlugin.java diff --git a/core-java-sun/src/main/resources/log4j.properties b/core-java-sun/src/main/resources/log4j.properties new file mode 100644 index 0000000000..621cf01735 --- /dev/null +++ b/core-java-sun/src/main/resources/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=DEBUG, A1 + +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/spring-jpa/src/main/resources/logback.xml b/core-java-sun/src/main/resources/logback.xml similarity index 100% rename from spring-jpa/src/main/resources/logback.xml rename to core-java-sun/src/main/resources/logback.xml diff --git a/core-java/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java b/core-java-sun/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java rename to core-java-sun/src/test/java/com/baeldung/javac/SampleJavacPluginIntegrationTest.java diff --git a/core-java/src/test/java/com/baeldung/javac/SimpleClassFile.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleClassFile.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/SimpleClassFile.java rename to core-java-sun/src/test/java/com/baeldung/javac/SimpleClassFile.java diff --git a/core-java/src/test/java/com/baeldung/javac/SimpleFileManager.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleFileManager.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/SimpleFileManager.java rename to core-java-sun/src/test/java/com/baeldung/javac/SimpleFileManager.java diff --git a/core-java/src/test/java/com/baeldung/javac/SimpleSourceFile.java b/core-java-sun/src/test/java/com/baeldung/javac/SimpleSourceFile.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/SimpleSourceFile.java rename to core-java-sun/src/test/java/com/baeldung/javac/SimpleSourceFile.java diff --git a/core-java/src/test/java/com/baeldung/javac/TestCompiler.java b/core-java-sun/src/test/java/com/baeldung/javac/TestCompiler.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/TestCompiler.java rename to core-java-sun/src/test/java/com/baeldung/javac/TestCompiler.java diff --git a/core-java/src/test/java/com/baeldung/javac/TestRunner.java b/core-java-sun/src/test/java/com/baeldung/javac/TestRunner.java similarity index 100% rename from core-java/src/test/java/com/baeldung/javac/TestRunner.java rename to core-java-sun/src/test/java/com/baeldung/javac/TestRunner.java diff --git a/spring-jpa/src/test/resources/.gitignore b/core-java-sun/src/test/resources/.gitignore similarity index 100% rename from spring-jpa/src/test/resources/.gitignore rename to core-java-sun/src/test/resources/.gitignore diff --git a/core-java/README.md b/core-java/README.md index 4573d5f7e2..8287a21d1e 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -119,4 +119,6 @@ - [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) - [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) - [Copy a File with Java](http://www.baeldung.com/java-copy-file) +- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) +- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) diff --git a/core-java/customers.xml b/core-java/customers.xml new file mode 100644 index 0000000000..b52dc27633 --- /dev/null +++ b/core-java/customers.xml @@ -0,0 +1,95 @@ + + + + SELECT * FROM customers + 1008 + + true + 1000 + 0 + 2 + + + + + 0 + 0 + 0 + true + ResultSet.TYPE_SCROLL_INSENSITIVE + false + customers + jdbc:h2:mem:testdb + + com.sun.rowset.providers.RIOptimisticProvider + Oracle Corporation + 1.0 + 2 + 1 + + + + 2 + + 1 + false + true + false + 0 + true + true + 11 + ID + ID + PUBLIC + 10 + 0 + CUSTOMERS + TESTDB + 4 + INTEGER + + + 2 + false + true + false + 0 + true + true + 50 + NAME + NAME + PUBLIC + 50 + 0 + CUSTOMERS + TESTDB + 12 + VARCHAR + + + + + 1 + Customer1 + + + 2 + Customer2 + + + 3 + Customer3 + + + 4 + Customer4 + + + 5 + Customer5 + + + diff --git a/core-java/pom.xml b/core-java/pom.xml index 77000b8741..068a772c43 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -1,491 +1,496 @@ - 4.0.0 - com.baeldung - core-java - 0.1.0-SNAPSHOT - jar + 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 + core-java + 0.1.0-SNAPSHOT + jar - core-java + core-java - + - - - net.sourceforge.collections - collections-generic - ${collections-generic.version} - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - - org.decimal4j - decimal4j - ${decimal4j.version} - - - - org.bouncycastle - bcprov-jdk15on - ${bouncycastle.version} - - - - org.unix4j - unix4j-command - ${unix4j.version} - - - - com.googlecode.grep4j - grep4j - ${grep4j.version} - - - - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - - log4j - log4j - 1.2.17 - - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - - org.hamcrest - hamcrest-all - 1.3 - test - - - - junit - junit - ${junit.version} - test - - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - - org.assertj - assertj-core - ${assertj.version} - test - - - - org.mockito - mockito-core - ${mockito.version} - test - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.javamoney - moneta - 1.1 - - - - org.owasp.esapi - esapi - 2.1.0.1 - - - - com.sun.messaging.mq - fscontext - ${fscontext.version} - - - com.codepoetics - protonpack - ${protonpack.version} - - - one.util - streamex - ${streamex.version} - - - io.vavr - vavr - ${vavr.version} - - - org.openjdk.jmh - jmh-core - 1.19 - - - org.openjdk.jmh - jmh-generator-annprocess - 1.19 - + - org.springframework - spring-web - 4.3.4.RELEASE + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + com.google.guava + guava + ${guava.version} - - com.sun - tools - 1.8.0 - system - ${java.home}/../lib/tools.jar - - - - core-java - - - src/main/resources - true - - + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + - + + commons-io + commons-io + ${commons-io.version} + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - + + org.apache.commons + commons-math3 + ${commons-math3.version} + - - + + org.decimal4j + decimal4j + ${decimal4j.version} + - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - + + org.unix4j + unix4j-command + ${unix4j.version} + - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - + - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - java - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - -Xmx300m - -XX:+UseParallelGC - -classpath - - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - - + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + junit + junit + ${junit.version} + test + + + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.javamoney + moneta + 1.1 + + + + org.owasp.esapi + esapi + 2.1.0.1 + + + com.h2database + h2 + 1.4.196 + runtime + + + com.sun.messaging.mq + fscontext + ${fscontext.version} + + + com.codepoetics + protonpack + ${protonpack.version} + + + one.util + streamex + ${streamex.version} + + + io.vavr + vavr + ${vavr.version} + + + org.openjdk.jmh + jmh-core + 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + org.springframework + spring-web + 4.3.4.RELEASE + + + + org.springframework.boot + spring-boot-starter + 1.5.8.RELEASE + + + + + + core-java + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + - + - + - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - org.codehaus.mojo - exec-maven-plugin + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + org.codehaus.mojo + exec-maven-plugin - - - run-benchmarks - - none - - exec - - - test - java - - -classpath - - org.openjdk.jmh.Main - .* - - - - - - - - - + + + run-benchmarks + + none + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + .* + + + + + + + + + - - - 2.8.5 + + + 2.8.5 - - 1.7.21 - 1.1.7 + + 1.7.21 + 1.1.7 - - 23.0 - 3.5 - 1.55 - 1.10 - 3.6.1 - 1.0.3 - 2.5 - 4.1 - 4.01 - 0.4 - 1.8.7 - 1.16.12 - 4.6-b01 - 1.13 - 0.6.5 - 0.9.0 - - - 1.3 - 4.12 - 2.8.9 - 3.6.1 - 1.7.0 + + 22.0 + 3.5 + 1.55 + 1.10 + 3.6.1 + 1.0.3 + 2.5 + 4.1 + 4.01 + 0.4 + 1.8.7 + 1.16.12 + 4.6-b01 + 1.13 + 0.6.5 + 0.9.0 - - 3.6.0 - 2.19.1 - - \ No newline at end of file + + 1.3 + 4.12 + 2.8.9 + 3.6.1 + 1.7.0 + + + 3.6.0 + 2.19.1 + + diff --git a/core-java/src/main/java/com/baeldung/array/ArrayBenchmarkRunner.java b/core-java/src/main/java/com/baeldung/array/ArrayBenchmarkRunner.java new file mode 100644 index 0000000000..977587a06a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/ArrayBenchmarkRunner.java @@ -0,0 +1,21 @@ +package com.baeldung.array; + +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +public class ArrayBenchmarkRunner { + + public static void main(String[] args) throws Exception { + + Options options = new OptionsBuilder() + .include(SearchArrayTest.class.getSimpleName()).threads(1) + .forks(1).shouldFailOnError(true).shouldDoGC(true) + .jvmArgs("-server").build(); + + new Runner(options).run(); + + + } + +} diff --git a/core-java/src/main/java/com/baeldung/array/ArrayInverter.java b/core-java/src/main/java/com/baeldung/array/ArrayInverter.java new file mode 100644 index 0000000000..7f7fcbb5a8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/ArrayInverter.java @@ -0,0 +1,41 @@ +package com.baeldung.array; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.IntStream; + +import org.apache.commons.lang3.ArrayUtils; + +import com.google.common.collect.Lists; + +public class ArrayInverter { + + public void invertUsingFor(Object[] array) { + for (int i = 0; i < array.length / 2; i++) { + Object temp = array[i]; + array[i] = array[array.length - 1 - i]; + array[array.length - 1 - i] = temp; + } + } + + public void invertUsingCollectionsReverse(Object[] array) { + List list = Arrays.asList(array); + Collections.reverse(list); + } + + public Object[] invertUsingStreams(final Object[] array) { + return IntStream.range(1, array.length + 1).mapToObj(i -> array[array.length - i]).toArray(); + } + + public void invertUsingCommonsLang(Object[] array) { + ArrayUtils.reverse(array); + } + + public Object[] invertUsingGuava(Object[] array) { + List list = Arrays.asList(array); + List reverted = Lists.reverse(list); + return reverted.toArray(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/array/SearchArrayTest.java b/core-java/src/main/java/com/baeldung/array/SearchArrayTest.java new file mode 100644 index 0000000000..fd11e49373 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/array/SearchArrayTest.java @@ -0,0 +1,130 @@ +package com.baeldung.array; + +import org.openjdk.jmh.annotations.*; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class SearchArrayTest { + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayLoop() { + + int count = 1000; + String[] strings = seedArray(count); + for (int i = 0; i < count; i++) { + searchLoop(strings, "T"); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayAllocNewList() { + + int count = 1000; + String[] strings = seedArray(count); + for (int i = 0; i < count; i++) { + searchList(strings, "W"); + } + + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayAllocNewSet() { + + int count = 1000; + String[] strings = seedArray(count); + for (int i = 0; i < count; i++) { + searchSet(strings, "S"); + } + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayReuseList() { + + int count = 1000; + String[] strings = seedArray(count); + + List asList = Arrays.asList(strings); + + for (int i = 0; i < count; i++) { + asList.contains("W"); + } + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayReuseSet() { + + int count = 1000; + String[] strings = seedArray(count); + Set asSet = new HashSet<>(Arrays.asList(strings)); + for (int i = 0; i < count; i++) { + asSet.contains("S"); + } + } + + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @Warmup(iterations = 5) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchArrayBinarySearch() { + + int count = 1000; + String[] strings = seedArray(count); + Arrays.sort(strings); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + Arrays.binarySearch(strings, "A"); + } + long duration = System.nanoTime() - startTime; + //System.out.println("Binary search: " + duration / 10000); + + } + + private boolean searchList(String[] strings, String searchString) { + return Arrays.asList(strings).contains(searchString); + } + + private boolean searchSet(String[] strings, String searchString) { + Set set = new HashSet<>(Arrays.asList(strings)); + return set.contains(searchString); + } + + private boolean searchLoop(String[] strings, String searchString) { + for (String s : strings) { + if (s.equals(searchString)) + return true; + } + return false; + } + + private String[] seedArray(int length) { + + String[] strings = new String[length]; + Random random = new Random(); + for (int i = 0; i < length; i++) + { + strings[i] = String.valueOf(random.nextInt()); + } + return strings; + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparable/Player.java b/core-java/src/main/java/com/baeldung/comparable/Player.java new file mode 100644 index 0000000000..68a78980f3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparable/Player.java @@ -0,0 +1,51 @@ +package com.baeldung.comparable; + +public class Player implements Comparable { + + private int ranking; + + private String name; + + private int age; + + public Player(int ranking, String name, int age) { + this.ranking = ranking; + this.name = name; + this.age = age; + } + + public int getRanking() { + return ranking; + } + + public void setRanking(int ranking) { + this.ranking = ranking; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return this.name; + } + + @Override + public int compareTo(Player otherPlayer) { + return (this.getRanking() - otherPlayer.getRanking()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java b/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java new file mode 100644 index 0000000000..a9b883f579 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparable/PlayerSorter.java @@ -0,0 +1,25 @@ +package com.baeldung.comparable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam); + System.out.println("After Sorting : " + footballTeam); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/Player.java b/core-java/src/main/java/com/baeldung/comparator/Player.java new file mode 100644 index 0000000000..e6e9ee0db6 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/Player.java @@ -0,0 +1,46 @@ +package com.baeldung.comparator; + +public class Player { + + private int ranking; + + private String name; + + private int age; + + public Player(int ranking, String name, int age) { + this.ranking = ranking; + this.name = name; + this.age = age; + } + + public int getRanking() { + return ranking; + } + + public void setRanking(int ranking) { + this.ranking = ranking; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return this.name; + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java new file mode 100644 index 0000000000..d2e7ca1f42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeComparator.java @@ -0,0 +1,12 @@ +package com.baeldung.comparator; + +import java.util.Comparator; + +public class PlayerAgeComparator implements Comparator { + + @Override + public int compare(Player firstPlayer, Player secondPlayer) { + return (firstPlayer.getAge() - secondPlayer.getAge()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java new file mode 100644 index 0000000000..3bbbcddb80 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerAgeSorter.java @@ -0,0 +1,27 @@ +package com.baeldung.comparator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerAgeSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + //Instance of PlayerAgeComparator + PlayerAgeComparator playerComparator = new PlayerAgeComparator(); + Collections.sort(footballTeam, playerComparator); + System.out.println("After Sorting by age : " + footballTeam); + + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java new file mode 100644 index 0000000000..2d42698843 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingComparator.java @@ -0,0 +1,12 @@ +package com.baeldung.comparator; + +import java.util.Comparator; + +public class PlayerRankingComparator implements Comparator { + + @Override + public int compare(Player firstPlayer, Player secondPlayer) { + return (firstPlayer.getRanking() - secondPlayer.getRanking()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java new file mode 100644 index 0000000000..581585fb7e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/comparator/PlayerRankingSorter.java @@ -0,0 +1,27 @@ +package com.baeldung.comparator; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class PlayerRankingSorter { + + public static void main(String[] args) { + + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 40); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + + System.out.println("Before Sorting : " + footballTeam); + //Instance of PlayerRankingComparator + PlayerRankingComparator playerComparator = new PlayerRankingComparator(); + Collections.sort(footballTeam, playerComparator); + System.out.println("After Sorting by ranking : " + footballTeam); + + } + +} 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 index 406f0f5274..9f34fe77b9 100644 --- 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 @@ -11,7 +11,7 @@ public class PolygonFactory { if(numberOfSides == 5) { return new Pentagon(); } - if(numberOfSides == 4) { + if(numberOfSides == 7) { return new Heptagon(); } else if(numberOfSides == 8) { @@ -19,4 +19,4 @@ public class PolygonFactory { } return null; } -} \ No newline at end of file +} diff --git a/core-java/src/main/java/com/baeldung/interfaces/CommaSeparatedCustomers.java b/core-java/src/main/java/com/baeldung/interfaces/CommaSeparatedCustomers.java new file mode 100644 index 0000000000..29ed2d3d26 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/interfaces/CommaSeparatedCustomers.java @@ -0,0 +1,21 @@ +package com.baeldung.interfaces; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class CommaSeparatedCustomers implements Customer.List { + + private List customers = new ArrayList(); + + @Override + public void Add(Customer customer) { + customers.add(customer); + } + + @Override + public String getCustomerNames() { + return customers.stream().map(customer -> customer.getName()).collect(Collectors.joining(",")); + } + +} diff --git a/core-java/src/main/java/com/baeldung/interfaces/Customer.java b/core-java/src/main/java/com/baeldung/interfaces/Customer.java new file mode 100644 index 0000000000..d2f2b48074 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/interfaces/Customer.java @@ -0,0 +1,19 @@ +package com.baeldung.interfaces; + +public class Customer { + public interface List { + void Add(Customer customer); + + String getCustomerNames(); + } + + private String name; + + public Customer(String name) { + this.name = name; + } + + String getName() { + return name; + } +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java new file mode 100644 index 0000000000..9cfcff468e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java @@ -0,0 +1,51 @@ +package com.baeldung.jdbcrowset; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +public class DatabaseConfiguration { + + + public static Connection geth2Connection() throws Exception { + Class.forName("org.h2.Driver"); + System.out.println("Driver Loaded."); + String url = "jdbc:h2:mem:testdb"; + return DriverManager.getConnection(url, "sa", ""); + } + + public static void initDatabase(Statement stmt) throws SQLException{ + int iter = 1; + while(iter<=5){ + String customer = "Customer"+iter; + String sql ="INSERT INTO customers(id, name) VALUES ("+iter+ ",'"+customer+"');"; + System.out.println("here is sql statmeent for execution: " + sql); + stmt.executeUpdate(sql); + iter++; + } + + int iterb = 1; + while(iterb<=5){ + String associate = "Associate"+iter; + String sql = "INSERT INTO associates(id, name) VALUES("+iterb+",'"+associate+"');"; + System.out.println("here is sql statement for associate:"+ sql); + stmt.executeUpdate(sql); + iterb++; + } + + + } + + + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java new file mode 100644 index 0000000000..7d5bb759f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java @@ -0,0 +1,24 @@ +package com.baeldung.jdbcrowset; + +import javax.sql.RowSetEvent; +import javax.sql.RowSetListener; + +public class ExampleListener implements RowSetListener { + + + public void cursorMoved(RowSetEvent event) { + System.out.println("ExampleListener alerted of cursorMoved event"); + System.out.println(event.toString()); + } + + public void rowChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowChanged event"); + System.out.println(event.toString()); + } + + public void rowSetChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowSetChanged event"); + System.out.println(event.toString()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java new file mode 100644 index 0000000000..14e738f72d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java @@ -0,0 +1,46 @@ +package com.baeldung.jdbcrowset; + +import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.sql.RowSet; +import javax.sql.rowset.Predicate; + +public class FilterExample implements Predicate { + + private Pattern pattern; + + public FilterExample(String regexQuery) { + if (regexQuery != null && !regexQuery.isEmpty()) { + pattern = Pattern.compile(regexQuery); + } + } + + public boolean evaluate(RowSet rs) { + try { + if (!rs.isAfterLast()) { + String name = rs.getString("name"); + System.out.println(String.format( + "Searching for pattern '%s' in %s", pattern.toString(), + name)); + Matcher matcher = pattern.matcher(name); + return matcher.matches(); + } else + return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean evaluate(Object value, int column) throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + + public boolean evaluate(Object value, String columnName) + throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java new file mode 100644 index 0000000000..72c462ac42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java @@ -0,0 +1,139 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import com.sun.rowset.*; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JdbcRowsetApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(JdbcRowsetApplication.class, args); + Statement stmt = null; + try { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + // insert data + DatabaseConfiguration.initDatabase(stmt); + // JdbcRowSet Example + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + // CachedRowSet Example + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + + // WebRowSet example + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + + // JoinRowSet example + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + + // FilteredRowSet example + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java b/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java new file mode 100644 index 0000000000..1b2e621b52 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/loops/LoopsInJava.java @@ -0,0 +1,43 @@ +package com.baeldung.loops; + +public class LoopsInJava { + + public int[] simple_for_loop() { + int[] arr = new int[5]; + for (int i = 0; i < 5; i++) { + arr[i] = i; + System.out.println("Simple for loop: i - " + i); + } + return arr; + } + + public int[] enhanced_for_each_loop() { + int[] intArr = { 0, 1, 2, 3, 4 }; + int[] arr = new int[5]; + for (int num : intArr) { + arr[num] = num; + System.out.println("Enhanced for-each loop: i - " + num); + } + return arr; + } + + public int[] while_loop() { + int i = 0; + int[] arr = new int[5]; + while (i < 5) { + arr[i] = i; + System.out.println("While loop: i - " + i++); + } + return arr; + } + + public int[] do_while_loop() { + int i = 0; + int[] arr = new int[5]; + do { + arr[i] = i; + System.out.println("Do-While loop: i - " + i++); + } while (i < 5); + return arr; + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java b/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java new file mode 100644 index 0000000000..7f2665ff2d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/FileManager.java @@ -0,0 +1,38 @@ +package com.baeldung.polymorphism; + +import java.awt.image.BufferedImage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FileManager { + + final static Logger logger = LoggerFactory.getLogger(FileManager.class); + + public static void main(String[] args) { + GenericFile file1 = new TextFile("SampleTextFile", "This is a sample text content", "v1.0.0"); + logger.info("File Info: \n" + file1.getFileInfo() + "\n"); + ImageFile imageFile = new ImageFile("SampleImageFile", 200, 100, new BufferedImage(100, 200, BufferedImage.TYPE_INT_RGB).toString() + .getBytes(), "v1.0.0"); + logger.info("File Info: \n" + imageFile.getFileInfo()); + } + + public static ImageFile createImageFile(String name, int height, int width, byte[] content, String version) { + ImageFile imageFile = new ImageFile(name, height, width, content, version); + logger.info("File 2 Info: \n" + imageFile.getFileInfo()); + return imageFile; + } + + public static GenericFile createTextFile(String name, String content, String version) { + GenericFile file1 = new TextFile(name, content, version); + logger.info("File 1 Info: \n" + file1.getFileInfo() + "\n"); + return file1; + } + + public static TextFile createTextFile2(String name, String content, String version) { + TextFile file1 = new TextFile(name, content, version); + logger.info("File 1 Info: \n" + file1.getFileInfo() + "\n"); + return file1; + } + +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java b/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java new file mode 100644 index 0000000000..03e704f36f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/GenericFile.java @@ -0,0 +1,63 @@ +package com.baeldung.polymorphism; + +import java.util.Date; + +public class GenericFile { + private String name; + private String extension; + private Date dateCreated; + private String version; + private byte[] content; + + public GenericFile() { + this.setDateCreated(new Date()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getExtension() { + return extension; + } + + public void setExtension(String extension) { + this.extension = extension; + } + + public Date getDateCreated() { + return dateCreated; + } + + public void setDateCreated(Date dateCreated) { + this.dateCreated = dateCreated; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public byte[] getContent() { + return content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + public String getFileInfo() { + return String.format("File Name: %s\n" + " Extension: %s\n" + " Date Created: %s\n" + " Version: %s\n", this.getName(), this.getExtension(), this.getDateCreated(), this.getVersion()); + } + + public Object read() { + return content; + } +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java b/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java new file mode 100644 index 0000000000..e237f3f826 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/ImageFile.java @@ -0,0 +1,41 @@ +package com.baeldung.polymorphism; + +public class ImageFile extends GenericFile { + private int height; + private int width; + + public ImageFile(String name, int height, int width, byte[] content, String version) { + this.setHeight(height); + this.setWidth(width); + this.setContent(content); + this.setName(name); + this.setVersion(version); + this.setExtension(".jpg"); + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public String getFileInfo() { + return String.format(" %s Height: %d\n Width: %d", super.getFileInfo(), this.getHeight(), this.getWidth()); + } + + public String read() { + return this.getContent() + .toString(); + } + +} diff --git a/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java b/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java new file mode 100644 index 0000000000..2c28c968b8 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/polymorphism/TextFile.java @@ -0,0 +1,44 @@ +package com.baeldung.polymorphism; + +public class TextFile extends GenericFile { + private int wordCount; + + public TextFile(String name, String content, String version) { + String[] words = content.split(" "); + this.setWordCount(words.length > 0 ? words.length : 1); + this.setContent(content.getBytes()); + this.setName(name); + this.setVersion(version); + this.setExtension(".txt"); + } + + public int getWordCount() { + return wordCount; + } + + public void setWordCount(int wordCount) { + this.wordCount = wordCount; + } + + public String getFileInfo() { + return String.format(" %s Word Count: %d", super.getFileInfo(), wordCount); + } + + public String read() { + return this.getContent() + .toString(); + } + + public String read(int limit) { + return this.getContent() + .toString() + .substring(0, limit); + } + + public String read(int start, int stop) { + return this.getContent() + .toString() + .substring(start, stop); + } + +} diff --git a/core-java/src/main/java/com/baeldung/tree/BinaryTree.java b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java new file mode 100644 index 0000000000..3cc496e348 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/tree/BinaryTree.java @@ -0,0 +1,216 @@ +package com.baeldung.tree; + +import java.util.LinkedList; +import java.util.Queue; + +public class BinaryTree { + + Node root; + + public void add(int value) { + + Node newNode = new Node(value); + + if (root == null) { + root = newNode; + return; + } + + Node parent = root; + Node current = root; + + while (true) { + + if (newNode.value < parent.value) { + current = parent.left; + + if (current == null) { + parent.left = newNode; + break; + } + } else { + current = parent.right; + + if (current == null) { + parent.right = newNode; + break; + } + } + + parent = current; + } + } + + public boolean isEmpty() { + return root == null; + } + + public boolean containsNode(int value) { + + Node current = root; + + while (current != null) { + + if (value == current.value) { + return true; + } + + if (value < current.value) { + current = current.left; + } else { + current = current.right; + } + + } + + return false; + } + + public void delete(int value) { + + Node current = root; + Node parent = root; + Node nodeToDelete = null; + boolean isLeftChild = false; + + while (nodeToDelete == null && current != null) { + + if (value == current.value) { + nodeToDelete = current; + } else if (value < current.value) { + parent = current; + current = current.left; + isLeftChild = true; + } else { + parent = current; + current = current.right; + isLeftChild = false; + } + + } + + if (nodeToDelete == null) { + return; + } + + // Case 1: no children + if (nodeToDelete.left == null && nodeToDelete.right == null) { + if (nodeToDelete == root) { + root = null; + } else if (isLeftChild) { + parent.left = null; + } else { + parent.right = null; + } + } + // Case 2: only 1 child + else if (nodeToDelete.right == null) { + if (nodeToDelete == root) { + root = nodeToDelete.left; + } else if (isLeftChild) { + parent.left = nodeToDelete.left; + } else { + parent.right = nodeToDelete.left; + } + } else if (nodeToDelete.left == null) { + if (nodeToDelete == root) { + root = nodeToDelete.right; + } else if (isLeftChild) { + parent.left = nodeToDelete.right; + } else { + parent.right = nodeToDelete.right; + } + } + // Case 3: 2 children + else if (nodeToDelete.left != null && nodeToDelete.right != null) { + Node replacement = findReplacement(nodeToDelete); + if (nodeToDelete == root) { + root = replacement; + } else if (isLeftChild) { + parent.left = replacement; + } else { + parent.right = replacement; + } + } + + } + + private Node findReplacement(Node nodeToDelete) { + + Node replacement = nodeToDelete; + Node parentReplacement = nodeToDelete; + Node current = nodeToDelete.right; + + while (current != null) { + parentReplacement = replacement; + replacement = current; + current = current.left; + } + + if (replacement != nodeToDelete.right) { + parentReplacement.left = replacement.right; + replacement.right = nodeToDelete.right; + } + + replacement.left = nodeToDelete.left; + + return replacement; + } + + public void traverseInOrder(Node node) { + if (node != null) { + traverseInOrder(node.left); + System.out.print(" " + node.value); + traverseInOrder(node.right); + } + } + + public void traversePreOrder(Node node) { + if (node != null) { + System.out.print(" " + node.value); + traversePreOrder(node.left); + traversePreOrder(node.right); + } + } + + public void traversePostOrder(Node node) { + if (node != null) { + traversePostOrder(node.left); + traversePostOrder(node.right); + + System.out.print(" " + node.value); + } + } + + public void traverseLevelOrder() { + Queue nodes = new LinkedList<>(); + nodes.add(root); + + while (!nodes.isEmpty()) { + + Node node = nodes.remove(); + + System.out.print(" " + node.value); + + if (node.left != null) { + nodes.add(node.left); + } + + if (node.left != null) { + nodes.add(node.right); + } + } + } + + class Node { + int value; + Node left; + Node right; + + Node(int value) { + this.value = value; + right = null; + left = null; + } + } +} diff --git a/core-java/src/main/java/com/baeldung/util/StreamUtils.java b/core-java/src/main/java/com/baeldung/util/StreamUtils.java new file mode 100644 index 0000000000..42f438732f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/util/StreamUtils.java @@ -0,0 +1,16 @@ +package com.baeldung.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.apache.commons.io.IOUtils; + +public class StreamUtils { + + public static String getStringFromInputStream(InputStream input) throws IOException { + StringWriter writer = new StringWriter(); + IOUtils.copy(input, writer, "UTF-8"); + return writer.toString(); + } +} diff --git a/core-java/src/main/resources/countries.properties b/core-java/src/main/resources/countries.properties new file mode 100644 index 0000000000..50b5e85653 --- /dev/null +++ b/core-java/src/main/resources/countries.properties @@ -0,0 +1,3 @@ +UK +US +Germany \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/array/ArrayInverterUnitTest.java b/core-java/src/test/java/com/baeldung/array/ArrayInverterUnitTest.java new file mode 100644 index 0000000000..ca59ee51fb --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/ArrayInverterUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.array; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class ArrayInverterUnitTest { + + private String[] fruits = { "apples", "tomatoes", "bananas", "guavas", "pineapples", "oranges" }; + + @Test + public void invertArrayWithForLoop() { + ArrayInverter inverter = new ArrayInverter(); + inverter.invertUsingFor(fruits); + + assertThat(new String[] { "oranges", "pineapples", "guavas", "bananas", "tomatoes", "apples" }).isEqualTo(fruits); + } + + @Test + public void invertArrayWithCollectionsReverse() { + ArrayInverter inverter = new ArrayInverter(); + inverter.invertUsingCollectionsReverse(fruits); + + assertThat(new String[] { "oranges", "pineapples", "guavas", "bananas", "tomatoes", "apples" }).isEqualTo(fruits); + } + + @Test + public void invertArrayWithStreams() { + ArrayInverter inverter = new ArrayInverter(); + + assertThat(new String[] { "oranges", "pineapples", "guavas", "bananas", "tomatoes", "apples" }).isEqualTo(inverter.invertUsingStreams(fruits)); + } + + @Test + public void invertArrayWithCommonsLang() { + ArrayInverter inverter = new ArrayInverter(); + inverter.invertUsingCommonsLang(fruits); + + assertThat(new String[] { "oranges", "pineapples", "guavas", "bananas", "tomatoes", "apples" }).isEqualTo(fruits); + } + + @Test + public void invertArrayWithGuava() { + ArrayInverter inverter = new ArrayInverter(); + + assertThat(new String[] { "oranges", "pineapples", "guavas", "bananas", "tomatoes", "apples" }).isEqualTo(inverter.invertUsingGuava(fruits)); + } + +} diff --git a/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java b/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java new file mode 100644 index 0000000000..50813a8601 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/arraydeque/ArrayDequeTest.java @@ -0,0 +1,50 @@ +package com.baeldung.arraydeque; + +import java.util.ArrayDeque; +import java.util.Deque; + +import static org.junit.Assert.*; +import org.junit.Test; + +public class ArrayDequeTest { + + @Test + public void whenOffer_addsAtLast() { + final Deque deque = new ArrayDeque<>(); + + deque.offer("first"); + deque.offer("second"); + + assertEquals("second", deque.getLast()); + } + + @Test + public void whenPoll_removesFirst() { + final Deque deque = new ArrayDeque<>(); + + deque.offer("first"); + deque.offer("second"); + + assertEquals("first", deque.poll()); + } + + @Test + public void whenPush_addsAtFirst() { + final Deque deque = new ArrayDeque<>(); + + deque.push("first"); + deque.push("second"); + + assertEquals("second", deque.getFirst()); + } + + @Test + public void whenPop_removesLast() { + final Deque deque = new ArrayDeque<>(); + + deque.push("first"); + deque.push("second"); + + assertEquals("second", deque.pop()); + } +} diff --git a/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java new file mode 100644 index 0000000000..7dc47ee8c2 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java @@ -0,0 +1,93 @@ +package com.baeldung.collection; + +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +public class WhenUsingHashSet { + + @Test + public void whenAddingElement_shouldAddElement() { + Set hashset = new HashSet<>(); + Assert.assertTrue(hashset.add("String Added")); + } + + @Test + public void whenCheckingForElement_shouldSearchForElement() { + Set hashsetContains = new HashSet<>(); + hashsetContains.add("String Added"); + Assert.assertTrue(hashsetContains.contains("String Added")); + } + + @Test + public void whenCheckingTheSizeOfHashSet_shouldReturnThesize() { + Set hashSetSize = new HashSet<>(); + hashSetSize.add("String Added"); + Assert.assertEquals(1, hashSetSize.size()); + } + + @Test + public void whenCheckingForEmptyHashSet_shouldCheckForEmpty() { + Set emptyHashSet = new HashSet<>(); + Assert.assertTrue(emptyHashSet.isEmpty()); + } + + @Test + public void whenRemovingElement_shouldRemoveElement() { + Set removeFromHashSet = new HashSet<>(); + removeFromHashSet.add("String Added"); + Assert.assertTrue(removeFromHashSet.remove("String Added")); + } + + @Test + public void whenClearingHashSet_shouldClearHashSet() { + Set clearHashSet = new HashSet<>(); + clearHashSet.add("String Added"); + clearHashSet.clear(); + Assert.assertTrue(clearHashSet.isEmpty()); + } + + @Test + public void whenIteratingHashSet_shouldIterateHashSet() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + System.out.println(itr.next()); + } + } + + @Test(expected = ConcurrentModificationException.class) + public void whenModifyingHashSetWhileIterating_shouldThrowException() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + itr.next(); + hashset.remove("Second"); + } + } + + @Test + public void whenRemovingElementUsingIterator_shouldRemoveElement() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + String element = itr.next(); + if (element.equals("Second")) + itr.remove(); + } + Assert.assertEquals(2, hashset.size()); + } +} diff --git a/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java b/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java new file mode 100644 index 0000000000..e8745884b8 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparable/ComparableUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.comparable; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class ComparableUnitTest { + + @Test + public void whenUsingComparable_thenSortedList() { + List footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + Collections.sort(footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + +} diff --git a/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java b/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java new file mode 100644 index 0000000000..5b7ec3bfe4 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparator/ComparatorUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.comparator; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class ComparatorUnitTest { + + List footballTeam; + + @Before + public void setUp() { + footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 20); + Player player2 = new Player(67, "Roger", 22); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + } + + @Test + public void whenUsingRankingComparator_thenSortedList() { + PlayerRankingComparator playerComparator = new PlayerRankingComparator(); + Collections.sort(footballTeam, playerComparator); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + + @Test + public void whenUsingAgeComparator_thenSortedList() { + PlayerAgeComparator playerComparator = new PlayerAgeComparator(); + Collections.sort(footballTeam, playerComparator); + assertEquals(footballTeam.get(0) + .getName(), "John"); + assertEquals(footballTeam.get(2) + .getRanking(), 45); + } + +} diff --git a/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java b/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java new file mode 100644 index 0000000000..49c8749309 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/comparator/Java8ComparatorUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.comparator; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class Java8ComparatorUnitTest { + + List footballTeam; + + @Before + public void setUp() { + footballTeam = new ArrayList(); + Player player1 = new Player(59, "John", 22); + Player player2 = new Player(67, "Roger", 20); + Player player3 = new Player(45, "Steven", 24); + footballTeam.add(player1); + footballTeam.add(player2); + footballTeam.add(player3); + } + + @Test + public void whenComparing_UsingLambda_thenSorted() { + System.out.println("************** Java 8 Comaparator **************"); + Comparator byRanking = (Player player1, Player player2) -> player1.getRanking() - player2.getRanking(); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byRanking); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + } + + @Test + public void whenComparing_UsingComparatorComparing_thenSorted() { + System.out.println("********* Comaparator.comparing method *********"); + System.out.println("********* byRanking *********"); + Comparator byRanking = Comparator.comparing(Player::getRanking); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byRanking); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Steven"); + assertEquals(footballTeam.get(2) + .getRanking(), 67); + + System.out.println("********* byAge *********"); + Comparator byAge = Comparator.comparing(Player::getAge); + + System.out.println("Before Sorting : " + footballTeam); + Collections.sort(footballTeam, byAge); + System.out.println("After Sorting : " + footballTeam); + assertEquals(footballTeam.get(0) + .getName(), "Roger"); + assertEquals(footballTeam.get(2) + .getRanking(), 45); + } + +} diff --git a/core-java/src/test/java/com/baeldung/file/FilesTest.java b/core-java/src/test/java/com/baeldung/file/FilesTest.java new file mode 100644 index 0000000000..c5a5b8a3a1 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/file/FilesTest.java @@ -0,0 +1,94 @@ +package com.baeldung.file; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; + +import com.google.common.base.Charsets; +import com.google.common.io.CharSink; +import com.google.common.io.FileWriteMode; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.util.StreamUtils; + +public class FilesTest { + + public static final String fileName = "src/main/resources/countries.properties"; + + @Before + @After + public void setup() throws Exception { + PrintWriter writer = new PrintWriter(fileName); + writer.print("UK\r\n" + "US\r\n" + "Germany\r\n"); + writer.close(); + } + + @Test + public void whenAppendToFileUsingGuava_thenCorrect() throws IOException { + File file = new File(fileName); + CharSink chs = com.google.common.io.Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND); + chs.write("Spain\r\n"); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + + @Test + public void whenAppendToFileUsingFiles_thenCorrect() throws IOException { + Files.write(Paths.get(fileName), "Spain\r\n".getBytes(), StandardOpenOption.APPEND); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileUtils_thenCorrect() throws IOException { + File file = new File(fileName); + FileUtils.writeStringToFile(file, "Spain\r\n", StandardCharsets.UTF_8, true); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileOutputStream_thenCorrect() throws Exception { + FileOutputStream fos = new FileOutputStream(fileName, true); + fos.write("Spain\r\n".getBytes()); + fos.close(); + + assertThat(StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\r\n"); + } + + @Test + public void whenAppendToFileUsingFileWriter_thenCorrect() throws IOException { + FileWriter fw = new FileWriter(fileName, true); + BufferedWriter bw = new BufferedWriter(fw); + bw.write("Spain"); + bw.newLine(); + bw.close(); + + assertThat( + StreamUtils.getStringFromInputStream( + new FileInputStream(fileName))) + .isEqualTo("UK\r\n" + "US\r\n" + "Germany\r\n" + "Spain\n"); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/interfaces/InnerInterfaceTests.java b/core-java/src/test/java/com/baeldung/interfaces/InnerInterfaceTests.java new file mode 100644 index 0000000000..b19ed76189 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/interfaces/InnerInterfaceTests.java @@ -0,0 +1,18 @@ +package com.baeldung.interfaces; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class InnerInterfaceTests { + @Test + public void whenCustomerListJoined_thenReturnsJoinedNames() { + Customer.List customerList = new CommaSeparatedCustomers(); + customerList.Add(new Customer("customer1")); + customerList.Add(new Customer("customer2")); + assertEquals("customer1,customer2", customerList.getCustomerNames()); + } +} diff --git a/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java new file mode 100644 index 0000000000..cb455c213a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java @@ -0,0 +1,157 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.junit.Before; +import org.junit.Test; + +import com.sun.rowset.CachedRowSetImpl; +import com.sun.rowset.JdbcRowSetImpl; +import com.sun.rowset.JoinRowSetImpl; +import com.sun.rowset.WebRowSetImpl; + +public class JdbcRowSetTest { + Statement stmt = null; + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + String sql = "SELECT * FROM customers"; + + @Before + public void setup() throws Exception { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + DatabaseConfiguration.initDatabase(stmt); + + } + + // JdbcRowSet Example + @Test + public void createJdbcRowSet_SelectCustomers_ThenCorrect() throws Exception { + + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + Connection conn = DatabaseConfiguration.geth2Connection(); + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + } + + // CachedRowSet Example + @Test + public void createCachedRowSet_DeleteRecord_ThenCorrect() throws Exception { + + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + } + + // WebRowSet example + @Test + public void createWebRowSet_SelectCustomers_WritetoXML_ThenCorrect() throws SQLException, IOException { + + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + } + + // JoinRowSet example + @Test + public void createCachedRowSets_DoJoinRowSet_ThenCorrect() throws Exception { + + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + } + + // FilteredRowSet example + @Test + public void createFilteredRowSet_filterByRegexExpression_thenCorrect() throws Exception { + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + Connection conn = DatabaseConfiguration.geth2Connection(); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + } +} diff --git a/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java new file mode 100644 index 0000000000..f82f9ddaa7 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java @@ -0,0 +1,107 @@ +package com.baeldung.loops; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class WhenUsingLoops { + + private LoopsInJava loops = new LoopsInJava(); + private static List list = new ArrayList<>(); + private static Set set = new HashSet<>(); + private static Map map = new HashMap<>(); + + @BeforeClass + public static void setUp() { + list.add("One"); + list.add("Two"); + list.add("Three"); + + set.add("Four"); + set.add("Five"); + set.add("Six"); + + map.put("One", 1); + map.put("Two", 2); + map.put("Three", 3); + } + + @Test + public void shouldRunForLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.simple_for_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunEnhancedForeachLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.enhanced_for_each_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunWhileLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.while_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void shouldRunDoWhileLoop() { + int[] expected = { 0, 1, 2, 3, 4 }; + int[] actual = loops.do_while_loop(); + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void whenUsingSimpleFor_shouldIterateList() { + for (int i = 0; i < list.size(); i++) { + System.out.println(list.get(i)); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateList() { + for (String item : list) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateSet() { + for (String item : set) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateMap() { + for (Entry entry : map.entrySet()) { + System.out.println("Key: " + entry.getKey() + " - " + "Value: " + entry.getValue()); + } + } + + @Test + public void whenUsingSimpleFor_shouldRunLabelledLoop() { + aa: for (int i = 1; i <= 3; i++) { + if (i == 1) + continue; + bb: for (int j = 1; j <= 3; j++) { + if (i == 2 && j == 2) { + break aa; + } + System.out.println(i + " " + j); + } + } + } + +} diff --git a/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java b/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java new file mode 100644 index 0000000000..9fa8ee9cd5 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/AnonymousInner.java @@ -0,0 +1,20 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +abstract class SimpleAbstractClass { + abstract void run(); +} + +public class AnonymousInner { + + @Test + public void run() { + SimpleAbstractClass simpleAbstractClass = new SimpleAbstractClass() { + void run() { + System.out.println("Running Anonymous Class..."); + } + }; + simpleAbstractClass.run(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java b/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java new file mode 100644 index 0000000000..3db33cde9b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/Enclosing.java @@ -0,0 +1,21 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class Enclosing { + + private static int x = 1; + + public static class StaticNested { + + private void run() { + System.out.println("x = " + x); + } + } + + @Test + public void test() { + Enclosing.StaticNested nested = new Enclosing.StaticNested(); + nested.run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java b/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java new file mode 100644 index 0000000000..deeb72de0c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/NewEnclosing.java @@ -0,0 +1,22 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class NewEnclosing { + + private void run() { + class Local { + void run() { + System.out.println("Welcome to Baeldung!"); + } + } + Local local = new Local(); + local.run(); + } + + @Test + public void test() { + NewEnclosing newEnclosing = new NewEnclosing(); + newEnclosing.run(); + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java b/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java new file mode 100644 index 0000000000..260f69fd1b --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/NewOuter.java @@ -0,0 +1,30 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class NewOuter { + + int a = 1; + static int b = 2; + + public class InnerClass { + int a = 3; + static final int b = 4; + + public void run() { + System.out.println("a = " + a); + System.out.println("b = " + b); + System.out.println("NewOuter.this.a = " + NewOuter.this.a); + System.out.println("NewOuter.b = " + NewOuter.b); + System.out.println("NewOuter.this.b = " + NewOuter.this.b); + } + } + + @Test + public void test() { + NewOuter outer = new NewOuter(); + NewOuter.InnerClass inner = outer.new InnerClass(); + inner.run(); + + } +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/nestedclass/Outer.java b/core-java/src/test/java/com/baeldung/nestedclass/Outer.java new file mode 100644 index 0000000000..d5e46670c9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/nestedclass/Outer.java @@ -0,0 +1,20 @@ +package com.baeldung.nestedclass; + +import org.junit.Test; + +public class Outer { + + public class Inner { + + public void run() { + System.out.println("Calling test..."); + } + } + + @Test + public void test() { + Outer outer = new Outer(); + Outer.Inner inner = outer.new Inner(); + inner.run(); + } +} diff --git a/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java b/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java new file mode 100644 index 0000000000..58826766e0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/polymorphism/PolymorphismUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.polymorphism; + +import static org.junit.Assert.*; + +import java.awt.image.BufferedImage; +import org.junit.Test; + +public class PolymorphismUnitTest { + + @Test + public void givenImageFile_whenFileCreated_shouldSucceed() { + ImageFile imageFile = FileManager.createImageFile("SampleImageFile", 200, 100, new BufferedImage(100, 200, BufferedImage.TYPE_INT_RGB).toString() + .getBytes(), "v1.0.0"); + assertEquals(200, imageFile.getHeight()); + } + + // Downcasting then Upcasting + @Test + public void givenTextFile_whenTextFileCreatedAndAssignedToGenericFileAndCastBackToTextFileOnGetWordCount_shouldSucceed() { + GenericFile textFile = FileManager.createTextFile("SampleTextFile", "This is a sample text content", "v1.0.0"); + TextFile textFile2 = (TextFile) textFile; + assertEquals(6, textFile2.getWordCount()); + } + + // Downcasting + @Test(expected = ClassCastException.class) + public void givenGenericFile_whenCastToTextFileAndInvokeGetWordCount_shouldFail() { + GenericFile genericFile = new GenericFile(); + TextFile textFile = (TextFile) genericFile; + System.out.println(textFile.getWordCount()); + } +} diff --git a/core-java/src/test/java/com/baeldung/string/StringTest.java b/core-java/src/test/java/com/baeldung/string/StringTest.java index fe1a69aa23..e88b2d7c2c 100644 --- a/core-java/src/test/java/com/baeldung/string/StringTest.java +++ b/core-java/src/test/java/com/baeldung/string/StringTest.java @@ -223,4 +223,4 @@ public class StringTest { assertEquals("200", String.valueOf(l)); } -} +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java b/core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java new file mode 100644 index 0000000000..2c20c730df --- /dev/null +++ b/core-java/src/test/java/com/baeldung/tree/BinaryTreeTest.java @@ -0,0 +1,85 @@ +package com.baeldung.tree; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class BinaryTreeTest { + + @Test + public void givenABinaryTree_WhenAddingElements_ThenTreeNotEmpty() { + + BinaryTree bt = createBinaryTree(); + + assertTrue(!bt.isEmpty()); + } + + @Test + public void givenABinaryTree_WhenAddingElements_ThenTreeContainsThoseElements() { + + BinaryTree bt = createBinaryTree(); + + assertTrue(bt.containsNode(6)); + assertTrue(bt.containsNode(4)); + + assertFalse(bt.containsNode(1)); + } + + @Test + public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() { + + BinaryTree bt = createBinaryTree(); + + assertTrue(bt.containsNode(9)); + bt.delete(9); + assertFalse(bt.containsNode(9)); + } + + @Test + public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() { + + BinaryTree bt = createBinaryTree(); + + bt.traverseInOrder(bt.root); + } + + @Test + public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() { + + BinaryTree bt = createBinaryTree(); + + bt.traversePreOrder(bt.root); + } + + @Test + public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() { + + BinaryTree bt = createBinaryTree(); + + bt.traversePostOrder(bt.root); + } + + @Test + public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() { + + BinaryTree bt = createBinaryTree(); + + bt.traverseLevelOrder(); + } + + private BinaryTree createBinaryTree() { + BinaryTree bt = new BinaryTree(); + + bt.add(6); + bt.add(4); + bt.add(8); + bt.add(3); + bt.add(5); + bt.add(7); + bt.add(9); + + return bt; + } + +} diff --git a/core-java/src/test/java/com/baeldung/varargs/FormatterTest.java b/core-java/src/test/java/com/baeldung/varargs/FormatterTest.java new file mode 100644 index 0000000000..509c8764d2 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/varargs/FormatterTest.java @@ -0,0 +1,60 @@ +package com.baeldung.varargs; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class FormatterTest { + + private final static String FORMAT = "%s %s %s"; + + @Test + public void givenNoArgument_thenEmptyAndTwoSpacesAreReturned() { + String actualResult = format(); + + assertThat(actualResult, is("empty ")); + } + + @Test + public void givenOneArgument_thenResultHasTwoTrailingSpace() { + String actualResult = format("baeldung"); + + assertThat(actualResult, is("baeldung ")); + } + + @Test + public void givenTwoArguments_thenOneTrailingSpaceExists() { + String actualResult = format("baeldung", "rocks"); + + assertThat(actualResult, is("baeldung rocks ")); + } + + @Test + public void givenMoreThanThreeArguments_thenTheFirstThreeAreUsed() { + String actualResult = formatWithVarArgs("baeldung", "rocks", "java", "and", "spring"); + + assertThat(actualResult, is("baeldung rocks java")); + } + + public String format() { + return format("empty", ""); + } + + public String format(String value) { + return format(value, ""); + } + + public String format(String val1, String val2) { + return String.format(FORMAT, val1, val2, ""); + } + + public String formatWithVarArgs(String... values) { + if (values.length == 0) { + return "no arguments given"; + } + + return String.format(FORMAT, values); + } + +} \ No newline at end of file diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt new file mode 100644 index 0000000000..09ce898860 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt @@ -0,0 +1,51 @@ +package com.baeldung.kotlin + +import org.junit.Assert +import org.junit.Test + +class ExtensionMethods { + @Test + fun simpleExtensionMethod() { + fun String.escapeForXml() : String { + return this + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + } + + Assert.assertEquals("Nothing", "Nothing".escapeForXml()) + Assert.assertEquals("<Tag>", "".escapeForXml()) + Assert.assertEquals("a&b", "a&b".escapeForXml()) + } + + @Test + fun genericExtensionMethod() { + fun T.concatAsString(b: T) : String { + return this.toString() + b.toString() + } + + Assert.assertEquals("12", "1".concatAsString("2")) + Assert.assertEquals("12", 1.concatAsString(2)) + // This doesn't compile + // Assert.assertEquals("12", 1.concatAsString(2.0)) + } + + @Test + fun infixExtensionMethod() { + infix fun Number.toPowerOf(exponent: Number): Double { + return Math.pow(this.toDouble(), exponent.toDouble()) + } + + Assert.assertEquals(9.0, 3 toPowerOf 2, 0.1) + Assert.assertEquals(3.0, 9 toPowerOf 0.5, 0.1) + } + + @Test + fun operatorExtensionMethod() { + operator fun List.times(by: Int): List { + return this.map { it * by } + } + + Assert.assertEquals(listOf(2, 4, 6), listOf(1, 2, 3) * 2) + } +} diff --git a/dubbo/README.md b/dubbo/README.md new file mode 100644 index 0000000000..dec02f5cfc --- /dev/null +++ b/dubbo/README.md @@ -0,0 +1,4 @@ +## Relevant articles: + +- [Intro to Dubbo](http://www.baeldung.com/dubbo-intro) + diff --git a/dubbo/pom.xml b/dubbo/pom.xml new file mode 100644 index 0000000000..3faef99e8d --- /dev/null +++ b/dubbo/pom.xml @@ -0,0 +1,72 @@ + + 4.0.0 + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + dubbo + + + UTF-8 + UTF-8 + 1.8 + 2.5.7 + 3.4.11 + 0.10 + 2.19.1 + + + + + com.alibaba + dubbo + ${dubbo.version} + + + junit + junit + 4.12 + test + + + + org.apache.zookeeper + zookeeper + ${zookeeper.version} + + + + com.101tec + zkclient + ${zkclient.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + maven-surefire-plugin + ${surefire.version} + + + **/*LiveTest.java + + + + + + + diff --git a/dubbo/src/main/java/com/alibaba/dubbo/registry/simple/SimpleRegistryService.java b/dubbo/src/main/java/com/alibaba/dubbo/registry/simple/SimpleRegistryService.java new file mode 100644 index 0000000000..bf4a5e201c --- /dev/null +++ b/dubbo/src/main/java/com/alibaba/dubbo/registry/simple/SimpleRegistryService.java @@ -0,0 +1,210 @@ +/* + * Copyright 1999-2011 Alibaba Group. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.registry.simple; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.URL; +import com.alibaba.dubbo.common.logger.Logger; +import com.alibaba.dubbo.common.logger.LoggerFactory; +import com.alibaba.dubbo.common.utils.ConcurrentHashSet; +import com.alibaba.dubbo.common.utils.NetUtils; +import com.alibaba.dubbo.common.utils.UrlUtils; +import com.alibaba.dubbo.registry.NotifyListener; +import com.alibaba.dubbo.registry.RegistryService; +import com.alibaba.dubbo.registry.support.AbstractRegistry; +import com.alibaba.dubbo.rpc.RpcContext; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * SimpleRegistryService + * + * @author william.liangf + */ +public class SimpleRegistryService extends AbstractRegistry { + + private final static Logger logger = LoggerFactory.getLogger(SimpleRegistryService.class); + private final ConcurrentMap> remoteRegistered = new ConcurrentHashMap>(); + private final ConcurrentMap>> remoteSubscribed = new ConcurrentHashMap>>(); + + public SimpleRegistryService() { + super(new URL("dubbo", NetUtils.getLocalHost(), 0, RegistryService.class.getName(), "file", "N/A")); + } + + public boolean isAvailable() { + return true; + } + + public List lookup(URL url) { + List urls = new ArrayList(); + for (URL u : getRegistered()) { + if (UrlUtils.isMatch(url, u)) { + urls.add(u); + } + } + return urls; + } + + public void register(URL url) { + String client = RpcContext.getContext().getRemoteAddressString(); + Set urls = remoteRegistered.get(client); + if (urls == null) { + remoteRegistered.putIfAbsent(client, new ConcurrentHashSet()); + urls = remoteRegistered.get(client); + } + urls.add(url); + super.register(url); + registered(url); + } + + public void unregister(URL url) { + String client = RpcContext.getContext().getRemoteAddressString(); + Set urls = remoteRegistered.get(client); + if (urls != null && urls.size() > 0) { + urls.remove(url); + } + super.unregister(url); + unregistered(url); + } + + public void subscribe(URL url, NotifyListener listener) { + if (getUrl().getPort() == 0) { + URL registryUrl = RpcContext.getContext().getUrl(); + if (registryUrl != null && registryUrl.getPort() > 0 + && RegistryService.class.getName().equals(registryUrl.getPath())) { + super.setUrl(registryUrl); + super.register(registryUrl); + } + } + String client = RpcContext.getContext().getRemoteAddressString(); + ConcurrentMap> clientListeners = remoteSubscribed.get(client); + if (clientListeners == null) { + remoteSubscribed.putIfAbsent(client, new ConcurrentHashMap>()); + clientListeners = remoteSubscribed.get(client); + } + Set listeners = clientListeners.get(url); + if (listeners == null) { + clientListeners.putIfAbsent(url, new ConcurrentHashSet()); + listeners = clientListeners.get(url); + } + listeners.add(listener); + super.subscribe(url, listener); + subscribed(url, listener); + } + + public void unsubscribe(URL url, NotifyListener listener) { + if (!Constants.ANY_VALUE.equals(url.getServiceInterface()) + && url.getParameter(Constants.REGISTER_KEY, true)) { + unregister(url); + } + String client = RpcContext.getContext().getRemoteAddressString(); + Map> clientListeners = remoteSubscribed.get(client); + if (clientListeners != null && clientListeners.size() > 0) { + Set listeners = clientListeners.get(url); + if (listeners != null && listeners.size() > 0) { + listeners.remove(listener); + } + } + } + + protected void registered(URL url) { + for (Map.Entry> entry : getSubscribed().entrySet()) { + URL key = entry.getKey(); + if (UrlUtils.isMatch(key, url)) { + List list = lookup(key); + for (NotifyListener listener : entry.getValue()) { + listener.notify(list); + } + } + } + } + + protected void unregistered(URL url) { + for (Map.Entry> entry : getSubscribed().entrySet()) { + URL key = entry.getKey(); + if (UrlUtils.isMatch(key, url)) { + List list = lookup(key); + for (NotifyListener listener : entry.getValue()) { + listener.notify(list); + } + } + } + } + + protected void subscribed(final URL url, final NotifyListener listener) { + if (Constants.ANY_VALUE.equals(url.getServiceInterface())) { + new Thread(new Runnable() { + public void run() { + Map> map = new HashMap>(); + for (URL u : getRegistered()) { + if (UrlUtils.isMatch(url, u)) { + String service = u.getServiceInterface(); + List list = map.get(service); + if (list == null) { + list = new ArrayList(); + map.put(service, list); + } + list.add(u); + } + } + for (List list : map.values()) { + try { + listener.notify(list); + } catch (Throwable e) { + logger.warn("Discard to notify " + url.getServiceKey() + " to listener " + listener); + } + } + } + }, "DubboMonitorNotifier").start(); + } else { + List list = lookup(url); + try { + listener.notify(list); + } catch (Throwable e) { + logger.warn("Discard to notify " + url.getServiceKey() + " to listener " + listener); + } + } + } + + public void disconnect() { + String client = RpcContext.getContext().getRemoteAddressString(); + if (logger.isInfoEnabled()) { + logger.info("Disconnected " + client); + } + Set urls = remoteRegistered.get(client); + if (urls != null && urls.size() > 0) { + for (URL url : urls) { + unregister(url); + } + } + Map> listeners = remoteSubscribed.get(client); + if (listeners != null && listeners.size() > 0) { + for (Map.Entry> entry : listeners.entrySet()) { + URL url = entry.getKey(); + for (NotifyListener listener : entry.getValue()) { + unsubscribe(url, listener); + } + } + } + } + +} \ No newline at end of file diff --git a/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsFailoverServiceImpl.java b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsFailoverServiceImpl.java new file mode 100644 index 0000000000..2ad26beac3 --- /dev/null +++ b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsFailoverServiceImpl.java @@ -0,0 +1,14 @@ +package com.baeldung.dubbo.remote; + +/** + * @author aiet + */ +public class GreetingsFailoverServiceImpl implements GreetingsService { + + @Override + public String sayHi(String name) { + System.out.println("failover implementation"); + return "hi, failover " + name; + } + +} diff --git a/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsService.java b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsService.java new file mode 100644 index 0000000000..337c4c83e7 --- /dev/null +++ b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsService.java @@ -0,0 +1,10 @@ +package com.baeldung.dubbo.remote; + +/** + * @author aiet + */ +public interface GreetingsService { + + String sayHi(String name); + +} diff --git a/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceImpl.java b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceImpl.java new file mode 100644 index 0000000000..a11d9588d8 --- /dev/null +++ b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceImpl.java @@ -0,0 +1,14 @@ +package com.baeldung.dubbo.remote; + +/** + * @author aiet + */ +public class GreetingsServiceImpl implements GreetingsService { + + @Override + public String sayHi(String name) { + System.out.println("default implementation"); + return "hi, " + name; + } + +} diff --git a/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceSpecialImpl.java b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceSpecialImpl.java new file mode 100644 index 0000000000..37449da8d8 --- /dev/null +++ b/dubbo/src/main/java/com/baeldung/dubbo/remote/GreetingsServiceSpecialImpl.java @@ -0,0 +1,20 @@ +package com.baeldung.dubbo.remote; + +import static java.util.concurrent.TimeUnit.SECONDS; + +/** + * @author aiet + */ +public class GreetingsServiceSpecialImpl implements GreetingsService { + + @Override + public String sayHi(String name) { + try { + System.out.println("specially called"); + SECONDS.sleep(5); + } catch (Exception ignored) { + } + return "hi, " + name; + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/APIConfigurationLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/APIConfigurationLiveTest.java new file mode 100644 index 0000000000..27c77bf9df --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/APIConfigurationLiveTest.java @@ -0,0 +1,57 @@ +package com.baeldung.dubbo; + +import com.alibaba.dubbo.config.ApplicationConfig; +import com.alibaba.dubbo.config.ReferenceConfig; +import com.alibaba.dubbo.config.RegistryConfig; +import com.alibaba.dubbo.config.ServiceConfig; +import com.baeldung.dubbo.remote.GreetingsService; +import com.baeldung.dubbo.remote.GreetingsServiceImpl; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author aiet + */ +public class APIConfigurationLiveTest { + + @Before + public void initProvider() { + ApplicationConfig application = new ApplicationConfig(); + application.setName("demo-provider"); + application.setVersion("1.0"); + + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("multicast://224.1.1.1:9090"); + + ServiceConfig service = new ServiceConfig<>(); + service.setApplication(application); + service.setRegistry(registryConfig); + service.setInterface(GreetingsService.class); + service.setRef(new GreetingsServiceImpl()); + + service.export(); + } + + @Test + public void givenProviderConsumer_whenSayHi_thenGotResponse() { + ApplicationConfig application = new ApplicationConfig(); + application.setName("demo-consumer"); + application.setVersion("1.0"); + + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("multicast://224.1.1.1:9090"); + + ReferenceConfig reference = new ReferenceConfig<>(); + reference.setApplication(application); + reference.setRegistry(registryConfig); + reference.setInterface(GreetingsService.class); + + GreetingsService greetingsService = reference.get(); + String hiMessage = greetingsService.sayHi("baeldung"); + + assertEquals("hi, baeldung", hiMessage); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/ClusterDynamicLoadBalanceLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/ClusterDynamicLoadBalanceLiveTest.java new file mode 100644 index 0000000000..408d5af368 --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/ClusterDynamicLoadBalanceLiveTest.java @@ -0,0 +1,70 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.ArrayList; +import java.util.List; +import java.util.OptionalDouble; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author aiet + */ +public class ClusterDynamicLoadBalanceLiveTest { + + private ExecutorService executorService; + + @Before + public void initRemote() { + executorService = Executors.newFixedThreadPool(2); + executorService.submit(() -> { + ClassPathXmlApplicationContext remoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-default.xml"); + remoteContext.start(); + }); + executorService.submit(() -> { + SECONDS.sleep(2); + ClassPathXmlApplicationContext backupRemoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-special.xml"); + backupRemoteContext.start(); + return null; + }); + } + + @Test + public void givenProviderCluster_whenConsumerSaysHi_thenResponseBalanced() throws InterruptedException { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("cluster/consumer-app-lb.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + List elapseList = new ArrayList<>(6); + for (int i = 0; i < 6; i++) { + long current = System.currentTimeMillis(); + String hiMessage = greetingsService.sayHi("baeldung"); + assertNotNull(hiMessage); + elapseList.add(System.currentTimeMillis() - current); + SECONDS.sleep(1); + } + + OptionalDouble avgElapse = elapseList + .stream() + .mapToLong(e -> e) + .average(); + assertTrue(avgElapse.isPresent()); + assertTrue(avgElapse.getAsDouble() > 1666.0); + + } + + @After + public void destroy() { + executorService.shutdown(); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailoverLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailoverLiveTest.java new file mode 100644 index 0000000000..721363d3d1 --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailoverLiveTest.java @@ -0,0 +1,52 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author aiet + */ +public class ClusterFailoverLiveTest { + + private ExecutorService executorService; + + @Before + public void initRemote() { + executorService = Executors.newFixedThreadPool(2); + executorService.submit(() -> { + ClassPathXmlApplicationContext backupRemoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-special.xml"); + backupRemoteContext.start(); + }); + executorService.submit(() -> { + ClassPathXmlApplicationContext remoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-failover.xml"); + remoteContext.start(); + }); + + } + + @Test + public void givenProviderCluster_whenConsumerSaysHi_thenGotFailoverResponse() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("cluster/consumer-app-failtest.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + String hiMessage = greetingsService.sayHi("baeldung"); + + assertNotNull(hiMessage); + assertEquals("hi, failover baeldung", hiMessage); + } + + @After + public void destroy() { + executorService.shutdown(); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailsafeLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailsafeLiveTest.java new file mode 100644 index 0000000000..29a10fa20a --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/ClusterFailsafeLiveTest.java @@ -0,0 +1,47 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author aiet + */ +public class ClusterFailsafeLiveTest { + + private ExecutorService executorService; + + @Before + public void initRemote() { + executorService = Executors.newFixedThreadPool(1); + executorService.submit(() -> { + ClassPathXmlApplicationContext remoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-special-failsafe.xml"); + remoteContext.start(); + }); + } + + @Test + public void givenProviderCluster_whenConsumerSaysHi_thenGotFailsafeResponse() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("cluster/consumer-app-failtest.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + String hiMessage = greetingsService.sayHi("baeldung"); + + assertNull(hiMessage); + } + + @After + public void destroy() { + executorService.shutdown(); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/ClusterLoadBalanceLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/ClusterLoadBalanceLiveTest.java new file mode 100644 index 0000000000..b880dfe843 --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/ClusterLoadBalanceLiveTest.java @@ -0,0 +1,66 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.ArrayList; +import java.util.List; +import java.util.OptionalDouble; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * @author aiet + */ +public class ClusterLoadBalanceLiveTest { + + private ExecutorService executorService; + + @Before + public void initRemote() { + executorService = Executors.newFixedThreadPool(2); + executorService.submit(() -> { + ClassPathXmlApplicationContext remoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-default.xml"); + remoteContext.start(); + }); + executorService.submit(() -> { + ClassPathXmlApplicationContext backupRemoteContext = new ClassPathXmlApplicationContext("cluster/provider-app-special.xml"); + backupRemoteContext.start(); + }); + } + + @Test + public void givenProviderCluster_whenConsumerSaysHi_thenResponseBalanced() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("cluster/consumer-app-lb.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + List elapseList = new ArrayList<>(6); + for (int i = 0; i < 6; i++) { + long current = System.currentTimeMillis(); + String hiMessage = greetingsService.sayHi("baeldung"); + assertNotNull(hiMessage); + elapseList.add(System.currentTimeMillis() - current); + } + + OptionalDouble avgElapse = elapseList + .stream() + .mapToLong(e -> e) + .average(); + assertTrue(avgElapse.isPresent()); + System.out.println(avgElapse.getAsDouble()); + assertTrue(avgElapse.getAsDouble() > 2500.0); + + } + + @After + public void destroy() { + executorService.shutdown(); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/MulticastRegistryLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/MulticastRegistryLiveTest.java new file mode 100644 index 0000000000..13dc5d3f1e --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/MulticastRegistryLiveTest.java @@ -0,0 +1,36 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author aiet + */ +public class MulticastRegistryLiveTest { + + private ClassPathXmlApplicationContext remoteContext; + + @Before + public void initRemote() { + remoteContext = new ClassPathXmlApplicationContext("multicast/provider-app.xml"); + remoteContext.start(); + } + + @Test + public void givenProvider_whenConsumerSaysHi_thenGotResponse() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("multicast/consumer-app.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + String hiMessage = greetingsService.sayHi("baeldung"); + + assertNotNull(hiMessage); + assertEquals("hi, baeldung", hiMessage); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/ResultCacheLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/ResultCacheLiveTest.java new file mode 100644 index 0000000000..401ebc9b94 --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/ResultCacheLiveTest.java @@ -0,0 +1,47 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.junit.Assert.*; + +/** + * @author aiet + */ +public class ResultCacheLiveTest { + + private ClassPathXmlApplicationContext remoteContext; + + @Before + public void initRemote() { + remoteContext = new ClassPathXmlApplicationContext("multicast/provider-app-special.xml"); + remoteContext.start(); + } + + @Test + public void givenProvider_whenConsumerSaysHi_thenGotResponse() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("multicast/consumer-app.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + + long before = System.currentTimeMillis(); + String hiMessage = greetingsService.sayHi("baeldung"); + + long timeElapsed = System.currentTimeMillis() - before; + assertTrue(timeElapsed > 5000); + assertNotNull(hiMessage); + assertEquals("hi, baeldung", hiMessage); + + + before = System.currentTimeMillis(); + hiMessage = greetingsService.sayHi("baeldung"); + timeElapsed = System.currentTimeMillis() - before; + assertTrue(timeElapsed < 1000); + assertNotNull(hiMessage); + assertEquals("hi, baeldung", hiMessage); + } + +} diff --git a/dubbo/src/test/java/com/baeldung/dubbo/SimpleRegistryLiveTest.java b/dubbo/src/test/java/com/baeldung/dubbo/SimpleRegistryLiveTest.java new file mode 100644 index 0000000000..72f15cf7ec --- /dev/null +++ b/dubbo/src/test/java/com/baeldung/dubbo/SimpleRegistryLiveTest.java @@ -0,0 +1,39 @@ +package com.baeldung.dubbo; + +import com.baeldung.dubbo.remote.GreetingsService; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author aiet + */ +public class SimpleRegistryLiveTest { + + private ClassPathXmlApplicationContext remoteContext; + private ClassPathXmlApplicationContext registryContext; + + @Before + public void initRemote() { + registryContext = new ClassPathXmlApplicationContext("simple/registry.xml"); + registryContext.start(); + + remoteContext = new ClassPathXmlApplicationContext("simple/provider-app.xml"); + remoteContext.start(); + } + + @Test + public void givenProvider_whenConsumerSaysHi_thenGotResponse() { + ClassPathXmlApplicationContext localContext = new ClassPathXmlApplicationContext("simple/consumer-app.xml"); + localContext.start(); + GreetingsService greetingsService = (GreetingsService) localContext.getBean("greetingsService"); + String hiMessage = greetingsService.sayHi("baeldung"); + + assertNotNull(hiMessage); + assertEquals("hi, baeldung", hiMessage); + } + +} diff --git a/dubbo/src/test/resources/cluster/consumer-app-failtest.xml b/dubbo/src/test/resources/cluster/consumer-app-failtest.xml new file mode 100644 index 0000000000..beb982db22 --- /dev/null +++ b/dubbo/src/test/resources/cluster/consumer-app-failtest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/cluster/consumer-app-lb.xml b/dubbo/src/test/resources/cluster/consumer-app-lb.xml new file mode 100644 index 0000000000..268e21b902 --- /dev/null +++ b/dubbo/src/test/resources/cluster/consumer-app-lb.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/cluster/provider-app-default.xml b/dubbo/src/test/resources/cluster/provider-app-default.xml new file mode 100644 index 0000000000..cb51bc1771 --- /dev/null +++ b/dubbo/src/test/resources/cluster/provider-app-default.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/cluster/provider-app-failover.xml b/dubbo/src/test/resources/cluster/provider-app-failover.xml new file mode 100644 index 0000000000..95cbee1f90 --- /dev/null +++ b/dubbo/src/test/resources/cluster/provider-app-failover.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/cluster/provider-app-special-failsafe.xml b/dubbo/src/test/resources/cluster/provider-app-special-failsafe.xml new file mode 100644 index 0000000000..7a7a139bb3 --- /dev/null +++ b/dubbo/src/test/resources/cluster/provider-app-special-failsafe.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/cluster/provider-app-special.xml b/dubbo/src/test/resources/cluster/provider-app-special.xml new file mode 100644 index 0000000000..8e5dc07d61 --- /dev/null +++ b/dubbo/src/test/resources/cluster/provider-app-special.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/log4j.properties b/dubbo/src/test/resources/log4j.properties new file mode 100644 index 0000000000..4c15f1b4e0 --- /dev/null +++ b/dubbo/src/test/resources/log4j.properties @@ -0,0 +1,6 @@ +log4j.rootLogger=INFO, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/dubbo/src/test/resources/multicast/consumer-app.xml b/dubbo/src/test/resources/multicast/consumer-app.xml new file mode 100644 index 0000000000..da9a41fd61 --- /dev/null +++ b/dubbo/src/test/resources/multicast/consumer-app.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/multicast/provider-app-special.xml b/dubbo/src/test/resources/multicast/provider-app-special.xml new file mode 100644 index 0000000000..4b22b5aace --- /dev/null +++ b/dubbo/src/test/resources/multicast/provider-app-special.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/multicast/provider-app.xml b/dubbo/src/test/resources/multicast/provider-app.xml new file mode 100644 index 0000000000..065d5ddad8 --- /dev/null +++ b/dubbo/src/test/resources/multicast/provider-app.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/simple/consumer-app.xml b/dubbo/src/test/resources/simple/consumer-app.xml new file mode 100644 index 0000000000..91f7a666e4 --- /dev/null +++ b/dubbo/src/test/resources/simple/consumer-app.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/simple/provider-app.xml b/dubbo/src/test/resources/simple/provider-app.xml new file mode 100644 index 0000000000..9880172249 --- /dev/null +++ b/dubbo/src/test/resources/simple/provider-app.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dubbo/src/test/resources/simple/registry.xml b/dubbo/src/test/resources/simple/registry.xml new file mode 100644 index 0000000000..9d1372da10 --- /dev/null +++ b/dubbo/src/test/resources/simple/registry.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/flyway/pom.xml b/flyway/pom.xml index 2774602654..5cb8fabe67 100644 --- a/flyway/pom.xml +++ b/flyway/pom.xml @@ -1,10 +1,10 @@ 4.0.0 - com.baeldung flyway 1.0 flyway + pom A sample project to demonstrate Flyway migrations @@ -13,6 +13,10 @@ 1.0.0-SNAPSHOT + + spring-flyway + + mysql @@ -20,6 +24,17 @@ ${mysql.version} + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + @@ -32,5 +47,6 @@ 6.0.5 4.0.3 + 1.5.8.RELEASE \ No newline at end of file diff --git a/flyway/spring-flyway/.gitignore b/flyway/spring-flyway/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/flyway/spring-flyway/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/flyway/spring-flyway/pom.xml b/flyway/spring-flyway/pom.xml new file mode 100644 index 0000000000..cf5703cfab --- /dev/null +++ b/flyway/spring-flyway/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + spring-flyway + 0.0.1-SNAPSHOT + jar + + spring-flyway + Spring Boot Test Flyway Migrations + + + flyway + com.baeldung + 1.0 + ../../flyway + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.flywaydb + flyway-core + + + org.projectlombok + lombok + + + com.h2database + h2 + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/SpringFlywayApplication.java b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/SpringFlywayApplication.java new file mode 100644 index 0000000000..9218fbc88d --- /dev/null +++ b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/SpringFlywayApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.springflyway; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringFlywayApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringFlywayApplication.class, args); + } +} diff --git a/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/entities/Customer.java b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/entities/Customer.java new file mode 100644 index 0000000000..194b961d2d --- /dev/null +++ b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/entities/Customer.java @@ -0,0 +1,28 @@ +package com.baeldung.springflyway.entities; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Customer { + + @Id + @GeneratedValue + private Long id; + + private String firstName; + private String lastName; + + private String email; + +} diff --git a/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/migration/V2__uk_lastname_customer.java b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/migration/V2__uk_lastname_customer.java new file mode 100644 index 0000000000..52b851546b --- /dev/null +++ b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/migration/V2__uk_lastname_customer.java @@ -0,0 +1,14 @@ +package com.baeldung.springflyway.migration; + +import org.flywaydb.core.api.migration.spring.SpringJdbcMigration; +import org.springframework.jdbc.core.JdbcTemplate; + +public class V2__uk_lastname_customer implements SpringJdbcMigration { + + final String CUSTOMER_LASTNAME_UK = "ALTER TABLE customer ADD CONSTRAINT uk_customer_lastname UNIQUE(last_name);"; + + @Override + public void migrate(final JdbcTemplate jdbcTemplate) throws Exception { + jdbcTemplate.execute(CUSTOMER_LASTNAME_UK); + } +} diff --git a/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/repositories/CustomerRepository.java b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/repositories/CustomerRepository.java new file mode 100644 index 0000000000..0a1fb5a146 --- /dev/null +++ b/flyway/spring-flyway/src/main/java/com/baeldung/springflyway/repositories/CustomerRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.springflyway.repositories; + +import com.baeldung.springflyway.entities.Customer; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface CustomerRepository extends JpaRepository { + + Optional findByEmail(String email); +} diff --git a/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInitialMigrationTest.java b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInitialMigrationTest.java new file mode 100644 index 0000000000..b3f2cb29e1 --- /dev/null +++ b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInitialMigrationTest.java @@ -0,0 +1,28 @@ +package com.baeldung.springflyway; + +import com.baeldung.springflyway.entities.Customer; +import com.baeldung.springflyway.repositories.CustomerRepository; +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 static org.junit.Assert.assertNotNull; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CustomerRepositoryInitialMigrationTest { + + @Autowired CustomerRepository customerRepository; + + @Test + public void givenSchemaCreationMigration_whenTryingToCreateACustomer_thenSuccess() { + Customer customer = customerRepository.save(Customer + .builder() + .email("customer@email.com") + .build()); + assertNotNull(customer.getId()); + } + +} diff --git a/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInsertDataMigrationTest.java b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInsertDataMigrationTest.java new file mode 100644 index 0000000000..369e61d98f --- /dev/null +++ b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryInsertDataMigrationTest.java @@ -0,0 +1,35 @@ +package com.baeldung.springflyway; + +import com.baeldung.springflyway.entities.Customer; +import com.baeldung.springflyway.repositories.CustomerRepository; +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 java.util.List; +import java.util.Optional; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CustomerRepositoryInsertDataMigrationTest { + + @Autowired CustomerRepository customerRepository; + + @Test + public void givenASetInsertData_whenRunningMigrationsWithSuccess_thenASpecificCustomerIsFound() { + Optional customerOptional = customerRepository.findByEmail("email@email.com"); + assertTrue(customerOptional.isPresent()); + } + + @Test + public void givenASetInsertData_whenRunningMigrationsWithSuccess_thenASetOfCustomersIsFound() { + List customers = customerRepository.findAll(); + assertNotNull(customers); + assertEquals(customers.size(), 6); + } + +} diff --git a/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryNotNullConstraintMigrationTest.java b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryNotNullConstraintMigrationTest.java new file mode 100644 index 0000000000..90517c9225 --- /dev/null +++ b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryNotNullConstraintMigrationTest.java @@ -0,0 +1,25 @@ +package com.baeldung.springflyway; + +import com.baeldung.springflyway.entities.Customer; +import com.baeldung.springflyway.repositories.CustomerRepository; +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.dao.DataIntegrityViolationException; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CustomerRepositoryNotNullConstraintMigrationTest { + + @Autowired CustomerRepository customerRepository; + + @Test(expected = DataIntegrityViolationException.class) + public void givenTheNotNullConstraintMigrations_whenInsertingACustomerWithNullEmail_thenThrowException() { + customerRepository.save(Customer + .builder() + .build()); + } + +} diff --git a/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintJavaMigrationTest.java b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintJavaMigrationTest.java new file mode 100644 index 0000000000..e5ba782fda --- /dev/null +++ b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintJavaMigrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.springflyway; + +import com.baeldung.springflyway.entities.Customer; +import com.baeldung.springflyway.repositories.CustomerRepository; +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.dao.DataIntegrityViolationException; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { + "flyway.locations[0]=db/migration", "flyway.locations[1]=com/baeldung/springflyway/migration" +}) +public class CustomerRepositoryUniqueConstraintJavaMigrationTest { + + @Autowired CustomerRepository customerRepository; + + @Test(expected = DataIntegrityViolationException.class) + public void givenTheUniqueConstraintMigrations_whenInsertingAnExistingLastNameCustomer_thenThrowException() { + customerRepository.save(Customer + .builder() + .lastName("LastName") + .build()); + + } + +} diff --git a/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintMigrationTest.java b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintMigrationTest.java new file mode 100644 index 0000000000..9fa2dee42d --- /dev/null +++ b/flyway/spring-flyway/src/test/java/com/baeldung/springflyway/CustomerRepositoryUniqueConstraintMigrationTest.java @@ -0,0 +1,27 @@ +package com.baeldung.springflyway; + +import com.baeldung.springflyway.entities.Customer; +import com.baeldung.springflyway.repositories.CustomerRepository; +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.dao.DataIntegrityViolationException; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class CustomerRepositoryUniqueConstraintMigrationTest { + + @Autowired CustomerRepository customerRepository; + + @Test(expected = DataIntegrityViolationException.class) + public void givenTheUniqueConstraintMigrations_whenInsertingAnExistingEmailCustomer_thenThrowException() { + customerRepository.save(Customer + .builder() + .email("email@email.com") + .build()); + + } + +} diff --git a/flyway/spring-flyway/src/test/resources/application.properties b/flyway/spring-flyway/src/test/resources/application.properties new file mode 100644 index 0000000000..5656ca79ce --- /dev/null +++ b/flyway/spring-flyway/src/test/resources/application.properties @@ -0,0 +1 @@ +spring.jpa.hibernate.ddl-auto=validate \ No newline at end of file diff --git a/flyway/spring-flyway/src/test/resources/db/migration/V1_0__create_table_customer.sql b/flyway/spring-flyway/src/test/resources/db/migration/V1_0__create_table_customer.sql new file mode 100644 index 0000000000..8c65253ed8 --- /dev/null +++ b/flyway/spring-flyway/src/test/resources/db/migration/V1_0__create_table_customer.sql @@ -0,0 +1,6 @@ +create table if not exists customer ( + id bigint AUTO_INCREMENT not null primary key, + first_name varchar(255) , + last_name varchar(255) , + email varchar(255) +); \ No newline at end of file diff --git a/flyway/spring-flyway/src/test/resources/db/migration/V1_1__insert_customer.sql b/flyway/spring-flyway/src/test/resources/db/migration/V1_1__insert_customer.sql new file mode 100644 index 0000000000..6bba6e00a1 --- /dev/null +++ b/flyway/spring-flyway/src/test/resources/db/migration/V1_1__insert_customer.sql @@ -0,0 +1,6 @@ +insert into customer (first_name, last_name, email) values ('FirstName', 'LastName', 'email@email.com'); +insert into customer (first_name, last_name, email) values ('FirstName1', 'LastName1', 'email1@email.com'); +insert into customer (first_name, last_name, email) values ('FirstName2', 'LastName2', 'email2@email.com'); +insert into customer (first_name, last_name, email) values ('FirstName3', 'LastName3', 'email3@email.com'); +insert into customer (first_name, last_name, email) values ('FirstName4', 'LastName4', 'email4@email.com'); +insert into customer (first_name, last_name, email) values ('FirstName5', 'LastName5', 'email5@email.com'); \ No newline at end of file diff --git a/flyway/spring-flyway/src/test/resources/db/migration/V1_2__make_email_not_null.sql b/flyway/spring-flyway/src/test/resources/db/migration/V1_2__make_email_not_null.sql new file mode 100644 index 0000000000..b1cc396741 --- /dev/null +++ b/flyway/spring-flyway/src/test/resources/db/migration/V1_2__make_email_not_null.sql @@ -0,0 +1 @@ +ALTER TABLE customer ALTER email SET NOT NULL; \ No newline at end of file diff --git a/flyway/spring-flyway/src/test/resources/db/migration/V1_3__make_email_unique.sql b/flyway/spring-flyway/src/test/resources/db/migration/V1_3__make_email_unique.sql new file mode 100644 index 0000000000..19d738fe46 --- /dev/null +++ b/flyway/spring-flyway/src/test/resources/db/migration/V1_3__make_email_unique.sql @@ -0,0 +1 @@ +ALTER TABLE customer ADD CONSTRAINT uk_customer_email UNIQUE(email); \ No newline at end of file diff --git a/gradle/gradle-fat-jar/build.gradle b/gradle/gradle-fat-jar/build.gradle new file mode 100644 index 0000000000..6afad80652 --- /dev/null +++ b/gradle/gradle-fat-jar/build.gradle @@ -0,0 +1,41 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.1' + } +} + +apply plugin: 'java' +apply plugin: 'com.github.johnrengelman.shadow' + +repositories { + mavenCentral() +} + +jar { + manifest { + attributes "Main-Class": "com.baeldung.fatjar.Application" + } + + from { + configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } + } +} + + +task customFatJar(type: Jar) { + manifest { + attributes 'Main-Class': 'com.baeldung.fatjar.Application' + } + baseName = 'all-in-one-jar' + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + with jar +} + + +dependencies{ + compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' + compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25' +} \ No newline at end of file diff --git a/gradle/gradle-fat-jar/src/main/java/com/baeldung/fatjar/Application.java b/gradle/gradle-fat-jar/src/main/java/com/baeldung/fatjar/Application.java new file mode 100644 index 0000000000..470d89c332 --- /dev/null +++ b/gradle/gradle-fat-jar/src/main/java/com/baeldung/fatjar/Application.java @@ -0,0 +1,16 @@ +package com.baeldung.fatjar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class Application { + + static final Logger logger = LoggerFactory.getLogger(Application.class); + + public static void main(String[] args) { + + logger.info("Hello at Baeldung!"); + } + +} \ No newline at end of file diff --git a/gradle/plugin/build.gradle b/gradle/plugin/build.gradle new file mode 100644 index 0000000000..8d7329c1b0 --- /dev/null +++ b/gradle/plugin/build.gradle @@ -0,0 +1,14 @@ + repositories{ + mavenCentral() + } + apply plugin: 'java' + apply plugin: 'maven' + apply plugin: com.baeldung.GreetingPlugin + dependencies { + compile gradleApi() + } + + greeting { + greeter = "Stranger" + message = "Message from the build script!" + } \ No newline at end of file diff --git a/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPlugin.java b/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPlugin.java new file mode 100644 index 0000000000..ad32ecfe91 --- /dev/null +++ b/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPlugin.java @@ -0,0 +1,17 @@ +package com.baeldung; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; + +public class GreetingPlugin implements Plugin { + @Override + public void apply(Project project) { + + GreetingPluginExtension extension = project.getExtensions().create("greeting", GreetingPluginExtension.class); + + project.task("hello").doLast(task -> { + System.out.println("Hello, " + extension.getGreeter()); + System.out.println("I have a message for You: " + extension.getMessage()); } + ); + } +} \ No newline at end of file diff --git a/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPluginExtension.java b/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPluginExtension.java new file mode 100644 index 0000000000..2ff64a43f5 --- /dev/null +++ b/gradle/plugin/buildSrc/src/main/java/com/baeldung/GreetingPluginExtension.java @@ -0,0 +1,22 @@ +package com.baeldung; + +public class GreetingPluginExtension { + private String greeter = "Baeldung"; + private String message = "Message from Plugin!"; + + public String getGreeter() { + return greeter; + } + + public void setGreeter(String greeter) { + this.greeter = greeter; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/guava-modules/guava-18/pom.xml b/guava-modules/guava-18/pom.xml index a9aba47f12..f8dbf5657e 100644 --- a/guava-modules/guava-18/pom.xml +++ b/guava-modules/guava-18/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/guava-modules/guava-19/pom.xml b/guava-modules/guava-19/pom.xml index 2345212eba..4a23bf7aec 100644 --- a/guava-modules/guava-19/pom.xml +++ b/guava-modules/guava-19/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/guava-modules/guava-21/pom.xml b/guava-modules/guava-21/pom.xml index 94bb66e76a..f5432fb7df 100644 --- a/guava-modules/guava-21/pom.xml +++ b/guava-modules/guava-21/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/guest/remote-debugging/README.md b/guest/remote-debugging/README.md new file mode 100644 index 0000000000..cc63e7fd59 --- /dev/null +++ b/guest/remote-debugging/README.md @@ -0,0 +1,16 @@ +## Building + +To build the module, use Maven's `package` goal: + +``` +mvn clean package +``` + +The `war` file will be available at `target/remote-debugging.war` + +## Running + +The `war` application is deployed to Apache Tomcat 8 or any other Java Web or Application server. +To deploy it to the Apache Tomcat 8 server, drop it in the `tomcat/webapps` directory. + +The service then will be accessible at http://localhost:8080/remote-debugging/hello?name=John \ No newline at end of file diff --git a/guest/remote-debugging/pom.xml b/guest/remote-debugging/pom.xml new file mode 100644 index 0000000000..d958d4c681 --- /dev/null +++ b/guest/remote-debugging/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + com.stackify + java-remote-debugging + 0.0.1-SNAPSHOT + war + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + + + + remote-debugging + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/guest/remote-debugging/src/main/java/com/stackify/debug/JavaRemoteDebuggingApplication.java b/guest/remote-debugging/src/main/java/com/stackify/debug/JavaRemoteDebuggingApplication.java new file mode 100644 index 0000000000..9d1a632638 --- /dev/null +++ b/guest/remote-debugging/src/main/java/com/stackify/debug/JavaRemoteDebuggingApplication.java @@ -0,0 +1,12 @@ +package com.stackify.debug; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JavaRemoteDebuggingApplication { + + public static void main(String[] args) { + SpringApplication.run(JavaRemoteDebuggingApplication.class, args); + } +} diff --git a/guest/remote-debugging/src/main/java/com/stackify/debug/config/WebInitializer.java b/guest/remote-debugging/src/main/java/com/stackify/debug/config/WebInitializer.java new file mode 100644 index 0000000000..b69e2b6c77 --- /dev/null +++ b/guest/remote-debugging/src/main/java/com/stackify/debug/config/WebInitializer.java @@ -0,0 +1,12 @@ +package com.stackify.debug.config; + +import com.stackify.debug.JavaRemoteDebuggingApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.support.SpringBootServletInitializer; + +public class WebInitializer extends SpringBootServletInitializer { + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(JavaRemoteDebuggingApplication.class); + } +} diff --git a/guest/remote-debugging/src/main/java/com/stackify/debug/rest/HelloController.java b/guest/remote-debugging/src/main/java/com/stackify/debug/rest/HelloController.java new file mode 100644 index 0000000000..8c614a36ec --- /dev/null +++ b/guest/remote-debugging/src/main/java/com/stackify/debug/rest/HelloController.java @@ -0,0 +1,16 @@ +package com.stackify.debug.rest; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController("/hello") +public class HelloController { + + @GetMapping + public String hello(@RequestParam("name") String name) { + String message = "Hello, " + name; + return message; + } + +} diff --git a/hibernate5/pom.xml b/hibernate5/pom.xml index 8543d1dae3..3b0b2fcd88 100644 --- a/hibernate5/pom.xml +++ b/hibernate5/pom.xml @@ -17,12 +17,15 @@ UTF-8 3.6.0 - + 5.2.12.Final + 6.0.6 + 2.2.3 + org.hibernate hibernate-core - 5.2.12.Final + ${hibernate.version} junit @@ -40,6 +43,21 @@ h2 1.4.194 + + org.hibernate + hibernate-spatial + ${hibernate.version} + + + mysql + mysql-connector-java + ${mysql.version} + + + ch.vorburger.mariaDB4j + mariaDB4j + ${mariaDB4j.version} + hibernate5 diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index c3bf8c2aa9..25fc0d7b02 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -5,6 +5,8 @@ import com.baeldung.hibernate.pojo.EntityDescription; import com.baeldung.hibernate.pojo.OrderEntry; import com.baeldung.hibernate.pojo.OrderEntryIdClass; import com.baeldung.hibernate.pojo.OrderEntryPK; +import com.baeldung.hibernate.pojo.PointEntity; +import com.baeldung.hibernate.pojo.PolygonEntity; import com.baeldung.hibernate.pojo.Product; import com.baeldung.hibernate.pojo.Phone; import com.baeldung.hibernate.pojo.TemporalValues; @@ -23,6 +25,7 @@ import com.baeldung.hibernate.pojo.inheritance.Person; import com.baeldung.hibernate.pojo.inheritance.Pet; import com.baeldung.hibernate.pojo.inheritance.Vehicle; +import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; @@ -36,8 +39,14 @@ import java.util.Properties; public class HibernateUtil { private static SessionFactory sessionFactory; + private static String PROPERTY_FILE_NAME; public static SessionFactory getSessionFactory() throws IOException { + return getSessionFactory(null); + } + + public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { + PROPERTY_FILE_NAME = propertyFileName; if (sessionFactory == null) { ServiceRegistry serviceRegistry = configureServiceRegistry(); sessionFactory = makeSessionFactory(serviceRegistry); @@ -70,6 +79,8 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(Vehicle.class); metadataSources.addAnnotatedClass(Car.class); metadataSources.addAnnotatedClass(Bag.class); + metadataSources.addAnnotatedClass(PointEntity.class); + metadataSources.addAnnotatedClass(PolygonEntity.class); Metadata metadata = metadataSources.buildMetadata(); return metadata.getSessionFactoryBuilder() @@ -86,12 +97,11 @@ public class HibernateUtil { private static Properties getProperties() throws IOException { Properties properties = new Properties(); URL propertiesURL = Thread.currentThread() - .getContextClassLoader() - .getResource("hibernate.properties"); + .getContextClassLoader() + .getResource(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties")); try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { properties.load(inputStream); } return properties; } - } \ No newline at end of file diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java new file mode 100644 index 0000000000..223f5dcbde --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java @@ -0,0 +1,41 @@ +package com.baeldung.hibernate.pojo; + +import com.vividsolutions.jts.geom.Point; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class PointEntity { + + @Id + @GeneratedValue + private Long id; + + private Point point; + + public PointEntity() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + @Override + public String toString() { + return "PointEntity{" + "id=" + id + ", point=" + point + '}'; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java new file mode 100644 index 0000000000..69208c8cd4 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PolygonEntity.java @@ -0,0 +1,38 @@ +package com.baeldung.hibernate.pojo; + +import com.vividsolutions.jts.geom.Polygon; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class PolygonEntity { + + @Id + @GeneratedValue + private Long id; + + private Polygon polygon; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Polygon getPolygon() { + return polygon; + } + + public void setPolygon(Polygon polygon) { + this.polygon = polygon; + } + + @Override + public String toString() { + return "PolygonEntity{" + "id=" + id + ", polygon=" + polygon + '}'; + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java new file mode 100644 index 0000000000..10b5cbef4e --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java @@ -0,0 +1,144 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.pojo.PointEntity; +import com.baeldung.hibernate.pojo.PolygonEntity; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; +import com.vividsolutions.jts.util.GeometricShapeFactory; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.persistence.Query; +import java.io.IOException; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import static org.junit.Assert.assertTrue; + +public class HibernateSpatialTest { + + private Session session; + private Transaction transaction; + + @Before + public void setUp() throws IOException { + session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") + .openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void shouldConvertWktToGeometry() throws ParseException { + Geometry geometry = wktToGeometry("POINT (2 5)"); + assertEquals("Point", geometry.getGeometryType()); + assertTrue(geometry instanceof Point); + } + + @Test + public void shouldInsertAndSelectPoints() throws ParseException { + PointEntity entity = new PointEntity(); + entity.setPoint((Point) wktToGeometry("POINT (1 1)")); + + session.persist(entity); + PointEntity fromDb = session.find(PointEntity.class, entity.getId()); + assertEquals("POINT (1 1)", fromDb.getPoint().toString()); + } + + @Test + public void shouldSelectDisjointPoints() throws ParseException { + insertPoint("POINT (1 2)"); + insertPoint("POINT (3 4)"); + insertPoint("POINT (5 6)"); + + Point point = (Point) wktToGeometry("POINT (3 4)"); + Query query = session.createQuery("select p from PointEntity p " + + "where disjoint(p.point, :point) = true", PointEntity.class); + query.setParameter("point", point); + assertEquals("POINT (1 2)", ((PointEntity) query.getResultList().get(0)).getPoint().toString()); + assertEquals("POINT (5 6)", ((PointEntity) query.getResultList().get(1)).getPoint().toString()); + } + + @Test + public void shouldSelectAllPointsWithinPolygon() throws ParseException { + insertPoint("POINT (1 1)"); + insertPoint("POINT (1 2)"); + insertPoint("POINT (3 4)"); + insertPoint("POINT (5 6)"); + + Query query = session.createQuery("select p from PointEntity p where within(p.point, :area) = true", + PointEntity.class); + query.setParameter("area", wktToGeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))")); + assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString())) + .containsOnly("POINT (1 1)", "POINT (1 2)", "POINT (3 4)"); + } + + @Test + public void shouldSelectAllPointsWithinRadius() throws ParseException { + insertPoint("POINT (1 1)"); + insertPoint("POINT (1 2)"); + insertPoint("POINT (3 4)"); + insertPoint("POINT (5 6)"); + + Query query = session.createQuery("select p from PointEntity p where within(p.point, :circle) = true", + PointEntity.class); + query.setParameter("circle", createCircle(0.0, 0.0, 5)); + + assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString())) + .containsOnly("POINT (1 1)", "POINT (1 2)"); + } + + @Test + public void shouldSelectAdjacentPolygons() throws ParseException { + insertPolygon("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))"); + insertPolygon("POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))"); + insertPolygon("POLYGON ((2 2, 3 1, 2 5, 4 3, 3 3, 2 2))"); + + Query query = session.createQuery("select p from PolygonEntity p where touches(p.polygon, :polygon) = true", + PolygonEntity.class); + query.setParameter("polygon", wktToGeometry("POLYGON ((5 5, 5 10, 10 10, 10 5, 5 5))")); + assertThat(query.getResultList().stream().map(p -> ((PolygonEntity) p).getPolygon().toString())) + .containsOnly("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))", "POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))"); + } + + private void insertPoint(String point) throws ParseException { + PointEntity entity = new PointEntity(); + entity.setPoint((Point) wktToGeometry(point)); + session.persist(entity); + } + + private void insertPolygon(String polygon) throws ParseException { + PolygonEntity entity = new PolygonEntity(); + entity.setPolygon((Polygon) wktToGeometry(polygon)); + session.persist(entity); + } + + private Geometry wktToGeometry(String wellKnownText) throws ParseException { + WKTReader fromText = new WKTReader(); + Geometry geom = null; + geom = fromText.read(wellKnownText); + return geom; + } + + private static Geometry createCircle(double x, double y, double radius) { + GeometricShapeFactory shapeFactory = new GeometricShapeFactory(); + shapeFactory.setNumPoints(32); + shapeFactory.setCentre(new Coordinate(x, y)); + shapeFactory.setSize(radius * 2); + return shapeFactory.createCircle(); + } +} diff --git a/hibernate5/src/test/resources/hibernate-spatial.properties b/hibernate5/src/test/resources/hibernate-spatial.properties new file mode 100644 index 0000000000..e85cd49cc3 --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-spatial.properties @@ -0,0 +1,10 @@ +hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect +hibernate.connection.driver_class=com.mysql.jdbc.Driver +hibernate.connection.url=jdbc:mysql://localhost:3306/hibernate-spatial +hibernate.connection.username=root +hibernate.connection.password=pass +hibernate.connection.pool_size=5 +hibernate.show_sql=true +hibernate.format_sql=true +hibernate.max_fetch_depth=5 +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/libraries/helloWorld.docx b/libraries/helloWorld.docx new file mode 100644 index 0000000000..09e71a4d4e Binary files /dev/null and b/libraries/helloWorld.docx differ diff --git a/libraries/pom.xml b/libraries/pom.xml index 546fe8a6d8..27d867b68b 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -711,4 +711,4 @@ 3.8.4 2.5.5 - + \ No newline at end of file diff --git a/logging-modules/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml index 918e052a15..5551585372 100644 --- a/logging-modules/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/logging-modules/log4j/README.md b/logging-modules/log4j/README.md index 3c0258142c..8aae1b5826 100644 --- a/logging-modules/log4j/README.md +++ b/logging-modules/log4j/README.md @@ -2,6 +2,5 @@ - [Introduction to Java Logging](http://www.baeldung.com/java-logging-intro) - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [Generate equals() and hashCode() with Eclipse](http://www.baeldung.com/java-eclipse-equals-and-hashcode) -- [A Guide To Java Regular Expressions API](http://www.baeldung.com/regular-expressions-java) - [Introduction to SLF4J](http://www.baeldung.com/slf4j-with-log4j2-logback) - [A Guide to Rolling File Appenders](http://www.baeldung.com/java-logging-rolling-file-appenders) diff --git a/logging-modules/log4j/pom.xml b/logging-modules/log4j/pom.xml index a3bfb0a33a..6a3fbde393 100644 --- a/logging-modules/log4j/pom.xml +++ b/logging-modules/log4j/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 58bc4b74e7..48608fbc80 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -9,7 +9,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/logging-modules/logback/README.md b/logging-modules/logback/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml new file mode 100644 index 0000000000..8169134442 --- /dev/null +++ b/logging-modules/logback/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + logback + logback + 0.1-SNAPSHOT + + + UTF-8 + 1.2.3 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java new file mode 100644 index 0000000000..e3d09dc321 --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java @@ -0,0 +1,14 @@ +package com.baeldung.logback; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + + public static void main(String[] args) { + logger.info("Example log from {}", Example.class.getSimpleName()); + } + +} diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java new file mode 100644 index 0000000000..a25c54b96e --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java @@ -0,0 +1,39 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class MapAppender extends AppenderBase { + + private final ConcurrentMap eventMap + = new ConcurrentHashMap<>(); + + private String prefix; + + @Override + protected void append(final ILoggingEvent event) { + if (prefix == null || "".equals(prefix)) { + addError("Prefix is not set for MapAppender."); + return; + } + + eventMap.put(prefix + System.currentTimeMillis(), event); + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(final String prefix) { + this.prefix = prefix; + } + + public Map getEventMap() { + return eventMap; + } + +} diff --git a/logging-modules/logback/src/main/resources/logback.xml b/logging-modules/logback/src/main/resources/logback.xml new file mode 100644 index 0000000000..37ae2adbb0 --- /dev/null +++ b/logging-modules/logback/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + test + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + \ No newline at end of file diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java new file mode 100644 index 0000000000..20366a229d --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Logger; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +public class MapAppenderIntegrationTest { + + private Logger rootLogger; + + @Before + public void setUp() throws Exception { + rootLogger = (Logger) LoggerFactory.getLogger("ROOT"); + } + + @Test + public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("map"); + assertEquals(appender.getEventMap().size(), 1); + } + + @Test + public void givenNoPrefixSet_whenLoggerEmitsEvent_thenAppenderReceivesNoEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("badMap"); + assertEquals(appender.getEventMap().size(), 0); + } + +} diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java new file mode 100644 index 0000000000..a5a938a923 --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java @@ -0,0 +1,60 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.BasicStatusManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MapAppenderTest { + + private LoggerContext ctx; + + private MapAppender mapAppender = new MapAppender(); + + private LoggingEvent event; + + @Before + public void setUp() throws Exception { + ctx = new LoggerContext(); + ctx.setName("test context"); + ctx.setStatusManager(new BasicStatusManager()); + mapAppender.setContext(ctx); + mapAppender.setPrefix("prefix"); + event = new LoggingEvent("fqcn", ctx.getLogger("logger"), Level.INFO, "Test message for logback appender", null, new Object[0]); + ctx.start(); + } + + @After + public void tearDown() throws Exception { + ctx.stop(); + mapAppender.stop(); + } + + @Test + public void whenPrefixIsNull_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(null); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenPrefixIsEmpty_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(""); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenLogMessageIsEmitted_thenMapAppenderReceivesMessage() throws Exception { + mapAppender.append(event); + assertEquals(mapAppender.getEventMap().size(), 1); + mapAppender.getEventMap().forEach((k, v) -> assertTrue(k.startsWith("prefix"))); + } + +} diff --git a/logging-modules/logback/src/test/resources/logback-test.xml b/logging-modules/logback/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8254e6ac80 --- /dev/null +++ b/logging-modules/logback/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + test + + + + + + + + + + \ No newline at end of file diff --git a/lucene/pom.xml b/lucene/pom.xml index 42b81a7d4a..6659d9ac32 100644 --- a/lucene/pom.xml +++ b/lucene/pom.xml @@ -31,7 +31,5 @@ 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 index 40a35fad86..97b1ec7b5d 100644 --- a/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java +++ b/lucene/src/main/java/com/baeldung/lucene/InMemoryLuceneIndex.java @@ -7,18 +7,22 @@ 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.SortedDocValuesField; 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.index.Term; 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.Sort; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; +import org.apache.lucene.util.BytesRef; public class InMemoryLuceneIndex { @@ -45,6 +49,7 @@ public class InMemoryLuceneIndex { document.add(new TextField("title", title, Field.Store.YES)); document.add(new TextField("body", body, Field.Store.YES)); + document.add(new SortedDocValuesField("title", new BytesRef(title))); writter.addDocument(document); writter.close(); @@ -73,6 +78,51 @@ public class InMemoryLuceneIndex { } + public void deleteDocument(Term term) { + try { + IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); + IndexWriter writter = new IndexWriter(memoryIndex, indexWriterConfig); + writter.deleteDocuments(term); + writter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public List searchIndex(Query query) { + try { + 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 e) { + e.printStackTrace(); + } + return null; + + } + + public List searchIndex(Query query, Sort sort) { + try { + IndexReader indexReader = DirectoryReader.open(memoryIndex); + IndexSearcher searcher = new IndexSearcher(indexReader); + TopDocs topDocs = searcher.search(query, 10, sort); + List documents = new ArrayList<>(); + for (ScoreDoc scoreDoc : topDocs.scoreDocs) { + documents.add(searcher.doc(scoreDoc.doc)); + } + + return documents; + } catch (IOException 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 index c3a498a4b8..acf688cb99 100644 --- a/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java +++ b/lucene/src/test/java/com/baeldung/lucene/LuceneInMemorySearchTest.java @@ -4,7 +4,19 @@ import java.util.List; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.FuzzyQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.PrefixQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.BytesRef; import org.junit.Assert; import org.junit.Test; @@ -20,4 +32,121 @@ public class LuceneInMemorySearchTest { Assert.assertEquals("Hello world", documents.get(0).get("title")); } -} + @Test + public void givenTermQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("activity", "running in track"); + inMemoryLuceneIndex.indexDocument("activity", "Cars are running on road"); + + Term term = new Term("body", "running"); + Query query = new TermQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenPrefixQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Lucene introduction"); + inMemoryLuceneIndex.indexDocument("article", "Introduction to Lucene"); + + Term term = new Term("body", "intro"); + Query query = new PrefixQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenBooleanQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Destination", "Las Vegas singapore car"); + inMemoryLuceneIndex.indexDocument("Commutes in singapore", "Bus Car Bikes"); + + Term term1 = new Term("body", "singapore"); + Term term2 = new Term("body", "car"); + + TermQuery query1 = new TermQuery(term1); + TermQuery query2 = new TermQuery(term2); + + BooleanQuery booleanQuery = new BooleanQuery.Builder().add(query1, BooleanClause.Occur.MUST) + .add(query2, BooleanClause.Occur.MUST).build(); + + List documents = inMemoryLuceneIndex.searchIndex(booleanQuery); + Assert.assertEquals(1, documents.size()); + } + + @Test + public void givenPhraseQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("quotes", "A rose by any other name would smell as sweet."); + + Query query = new PhraseQuery(1, "body", new BytesRef("smell"), new BytesRef("sweet")); + List documents = inMemoryLuceneIndex.searchIndex(query); + + Assert.assertEquals(1, documents.size()); + } + + @Test + public void givenFuzzyQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Halloween Festival"); + inMemoryLuceneIndex.indexDocument("decoration", "Decorations for Halloween"); + + Term term = new Term("body", "hallowen"); + Query query = new FuzzyQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenWildCardQueryWhenFetchedDocumentThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("article", "Lucene introduction"); + inMemoryLuceneIndex.indexDocument("article", "Introducing Lucene with Spring"); + + Term term = new Term("body", "intro*"); + Query query = new WildcardQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(2, documents.size()); + } + + @Test + public void givenSortFieldWhenSortedThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Ganges", "River in India"); + inMemoryLuceneIndex.indexDocument("Mekong", "This river flows in south Asia"); + inMemoryLuceneIndex.indexDocument("Amazon", "Rain forest river"); + inMemoryLuceneIndex.indexDocument("Rhine", "Belongs to Europe"); + inMemoryLuceneIndex.indexDocument("Nile", "Longest River"); + + Term term = new Term("body", "river"); + Query query = new WildcardQuery(term); + + SortField sortField = new SortField("title", SortField.Type.STRING_VAL, false); + Sort sortByTitle = new Sort(sortField); + + List documents = inMemoryLuceneIndex.searchIndex(query, sortByTitle); + Assert.assertEquals(4, documents.size()); + Assert.assertEquals("Amazon", documents.get(0).getField("title").stringValue()); + } + + @Test + public void whenDocumentDeletedThenCorrect() { + InMemoryLuceneIndex inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory(), new StandardAnalyzer()); + inMemoryLuceneIndex.indexDocument("Ganges", "River in India"); + inMemoryLuceneIndex.indexDocument("Mekong", "This river flows in south Asia"); + + Term term = new Term("title", "ganges"); + inMemoryLuceneIndex.deleteDocument(term); + + Query query = new TermQuery(term); + + List documents = inMemoryLuceneIndex.searchIndex(query); + Assert.assertEquals(0, documents.size()); + } + +} \ No newline at end of file diff --git a/muleesb/.gitignore b/muleesb/.gitignore new file mode 100644 index 0000000000..541f92c42e --- /dev/null +++ b/muleesb/.gitignore @@ -0,0 +1 @@ +# Add any directories, files, or patterns you don't want to be tracked by version control \ No newline at end of file diff --git a/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor b/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor new file mode 100644 index 0000000000..0b8060f303 --- /dev/null +++ b/muleesb/.mule/objectstore/b2fe1a90-c473-11e7-8eb5-98e7f44e8ac8/partition-descriptor @@ -0,0 +1 @@ +DEFAULT_PARTITION \ No newline at end of file diff --git a/muleesb/.mule/queue-tx-log/tx1.log b/muleesb/.mule/queue-tx-log/tx1.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/.mule/queue-tx-log/tx2.log b/muleesb/.mule/queue-tx-log/tx2.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/.mule/queue-xa-tx-log/tx1.log b/muleesb/.mule/queue-xa-tx-log/tx1.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/.mule/queue-xa-tx-log/tx2.log b/muleesb/.mule/queue-xa-tx-log/tx2.log new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/mule-project.xml b/muleesb/mule-project.xml new file mode 100644 index 0000000000..0d522b0141 --- /dev/null +++ b/muleesb/mule-project.xml @@ -0,0 +1,5 @@ + + + muleesb + + diff --git a/muleesb/pom.xml b/muleesb/pom.xml new file mode 100644 index 0000000000..2c88bf83da --- /dev/null +++ b/muleesb/pom.xml @@ -0,0 +1,214 @@ + + + + 4.0.0 + com.mycompany + muleesb + 1.0.0-SNAPSHOT + mule + Mule muleesb Application + + + UTF-8 + UTF-8 + + 3.8.1 + 1.2 + 1.3.6 + 3.9.0 + + + + + + org.mule.tools.maven + mule-app-maven-plugin + ${mule.tools.version} + true + + true + + + + org.mule.tools + muleesb-maven-plugin + 1.0 + + 3.7.0 + /home/abir/AnypointStudio/workspace/variablescopetest + + + + deploy + + start + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + add-resource + generate-resources + + add-resource + + + + + src/main/app/ + + + mappings/ + + + src/main/api/ + + + + + + + + com.mulesoft.munit.tools + munit-maven-plugin + ${munit.version} + + + test + test + + test + + + + + + true + + html + + + + + + + + src/test/munit + + + src/test/resources + + + + + + + + + org.mule.modules + mule-module-spring-config + ${mule.version} + provided + + + + org.mule.transports + mule-transport-file + ${mule.version} + provided + + + org.mule.transports + mule-transport-http + ${mule.version} + provided + + + org.mule.transports + mule-transport-jdbc + ${mule.version} + provided + + + org.mule.transports + mule-transport-jms + ${mule.version} + provided + + + org.mule.transports + mule-transport-vm + ${mule.version} + provided + + + + org.mule.modules + mule-module-scripting + ${mule.version} + provided + + + org.mule.modules + mule-module-xml + ${mule.version} + provided + + + + org.mule.tests + mule-tests-functional + ${mule.version} + test + + + org.mule.modules + mule-module-apikit + ${mule.version} + provided + + + com.mulesoft.munit + mule-munit-support + ${mule.munit.support.version} + test + + + com.mulesoft.munit + munit-runner + ${munit.version} + test + + + + + + Central + Central + http://repo1.maven.org/maven2/ + default + + + mulesoft-releases + MuleSoft Releases Repository + http://repository.mulesoft.org/releases/ + default + + + + + mulesoft-release + mulesoft release repository + default + http://repository.mulesoft.org/releases/ + + false + + + + diff --git a/muleesb/src/main/app/mule-app.properties b/muleesb/src/main/app/mule-app.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/muleesb/src/main/app/mule-deploy.properties b/muleesb/src/main/app/mule-deploy.properties new file mode 100644 index 0000000000..07eabe9cc6 --- /dev/null +++ b/muleesb/src/main/app/mule-deploy.properties @@ -0,0 +1,6 @@ +#** GENERATED CONTENT ** Mule Application Deployment Descriptor +#Mon Nov 06 15:54:37 BDT 2017 +redeployment.enabled=true +encoding=UTF-8 +domain=default +config.resources=variablescopetest.xml diff --git a/muleesb/src/main/app/variablescopetest.xml b/muleesb/src/main/app/variablescopetest.xml new file mode 100644 index 0000000000..518b901084 --- /dev/null +++ b/muleesb/src/main/app/variablescopetest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java b/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java new file mode 100644 index 0000000000..0e180062a7 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/FromFlow2Component.java @@ -0,0 +1,18 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleEventContext; +import org.mule.api.MuleMessage; +import org.mule.api.lifecycle.Callable; + +public class FromFlow2Component implements Callable { + + @Override + public Object onCall(MuleEventContext eventContext) throws Exception { + + MuleMessage message = eventContext.getMessage(); + message.setPayload("Converted in flow 2"); + + return message; + } + +} diff --git a/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java b/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java new file mode 100644 index 0000000000..1e1ad15be8 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/InitializationTransformer.java @@ -0,0 +1,29 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleMessage; +import org.mule.api.transformer.TransformerException; +import org.mule.api.transport.PropertyScope; +import org.mule.transformer.AbstractMessageTransformer; + +public class InitializationTransformer extends AbstractMessageTransformer { + + @Override + public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException { + // TODO Auto-generated method stub + + String payload = null; + + try { + payload = message.getPayloadAsString(); + }catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Logged Payload: "+payload); + message.setPayload("Payload from Initialization"); + message.setProperty("outboundKey", "outboundpropertyvalue",PropertyScope.OUTBOUND); + + + return message; + } +} \ No newline at end of file diff --git a/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java b/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java new file mode 100644 index 0000000000..105522e5b4 --- /dev/null +++ b/muleesb/src/main/java/com/baeldung/transformer/InvokingMessageComponent.java @@ -0,0 +1,16 @@ +package com.baeldung.transformer; + +import org.mule.api.MuleMessage; +import org.mule.api.transformer.TransformerException; +import org.mule.transformer.AbstractMessageTransformer; + +public class InvokingMessageComponent extends AbstractMessageTransformer { + + @Override + public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException { + // TODO Auto-generated method stub + String InboundProp = (String) message.getInboundProperty("outboundKey"); + System.out.println("InboundProp:" + InboundProp); + return InboundProp; + } +} \ No newline at end of file diff --git a/muleesb/src/main/resources/log4j2.xml b/muleesb/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..98c4b02433 --- /dev/null +++ b/muleesb/src/main/resources/log4j2.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/muleesb/src/test/munit/variablescopetest-test-suite.xml b/muleesb/src/test/munit/variablescopetest-test-suite.xml new file mode 100644 index 0000000000..43e410a327 --- /dev/null +++ b/muleesb/src/test/munit/variablescopetest-test-suite.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/muleesb/src/test/resources/log4j2-test.xml b/muleesb/src/test/resources/log4j2-test.xml new file mode 100644 index 0000000000..6351ae041c --- /dev/null +++ b/muleesb/src/test/resources/log4j2-test.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/noexception/README.md b/noexception/README.md index d840191369..9dd4c11190 100644 --- a/noexception/README.md +++ b/noexception/README.md @@ -1,2 +1,2 @@ ### Relevant Articles: -- [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception) +- [Introduction to NoException](http://www.baeldung.com/introduction-to-noexception) diff --git a/osgi/pom.xml b/osgi/pom.xml index 4298a0d3eb..e6ef9c3192 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -65,7 +65,7 @@ org.osgi org.osgi.core - 5.0.0 + 6.0.0 provided @@ -77,7 +77,7 @@ org.apache.felix maven-bundle-plugin - 1.4.0 + 3.3.0 true diff --git a/patterns/template-method/pom.xml b/patterns/behavioral-patterns/pom.xml similarity index 92% rename from patterns/template-method/pom.xml rename to patterns/behavioral-patterns/pom.xml index 4b863fe0a4..3c40520ce1 100644 --- a/patterns/template-method/pom.xml +++ b/patterns/behavioral-patterns/pom.xml @@ -1,8 +1,8 @@ 4.0.0 - com.baeldung.templatemethod - template-method + com.baeldung.pattern.templatemethod + pattern.templatemethod 1.0 jar diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java similarity index 59% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java index bd383b4568..9ab34c3cd8 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java @@ -1,11 +1,11 @@ -package com.baeldung.templatemethodpattern.application; +package com.baeldung.pattern.templatemethod.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.pattern.templatemethod.model.Computer; +import com.baeldung.pattern.templatemethod.model.StandardComputer; +import com.baeldung.pattern.templatemethod.model.HighEndComputer; +import com.baeldung.pattern.templatemethod.model.ComputerBuilder; +import com.baeldung.pattern.templatemethod.model.HighEndComputerBuilder; +import com.baeldung.pattern.templatemethod.model.StandardComputerBuilder; public class Application { diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java similarity index 77% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java index 128eec59ad..1419398f62 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java @@ -1,9 +1,7 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; import java.util.HashMap; import java.util.Map; -import java.util.ArrayList; -import java.util.List; public class Computer { diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java similarity index 88% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java index 39052f4776..515a6940f5 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/ComputerBuilder.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java @@ -1,5 +1,6 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; +import com.baeldung.pattern.templatemethod.model.Computer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java similarity index 59% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java index 16d89f1ad6..0684b1b233 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java @@ -1,10 +1,11 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; +import com.baeldung.pattern.templatemethod.model.Computer; import java.util.Map; public class HighEndComputer extends Computer { public HighEndComputer(Map computerParts) { super(computerParts); - } + } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java similarity index 92% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java index baa800ca8f..c992aa2bff 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputerBuilder.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java @@ -1,4 +1,4 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; public class HighEndComputerBuilder extends ComputerBuilder { diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java similarity index 60% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java index 14d32d7b64..4e1d857016 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java @@ -1,10 +1,11 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; +import com.baeldung.pattern.templatemethod.model.Computer; import java.util.Map; public class StandardComputer extends Computer { public StandardComputer(Map computerParts) { super(computerParts); - } + } } diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java similarity index 92% rename from patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java rename to patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java index 78547dc38b..cc81dddc1b 100644 --- a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputerBuilder.java +++ b/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java @@ -1,4 +1,4 @@ -package com.baeldung.templatemethodpattern.model; +package com.baeldung.pattern.templatemethod.model; public class StandardComputerBuilder extends ComputerBuilder { diff --git a/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java b/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java similarity index 89% rename from patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java rename to patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java index 1d608ff2c2..679559af9f 100644 --- a/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java +++ b/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java @@ -1,10 +1,8 @@ -package com.baeldung.templatemethodpatterntest; +package com.baeldung.pattern.templatemethod.test; -import com.baeldung.templatemethodpattern.model.Computer; -import com.baeldung.templatemethodpattern.model.HighEndComputerBuilder; -import com.baeldung.templatemethodpattern.model.StandardComputerBuilder; -import com.baeldung.templatemethodpattern.model.HighEndComputer; -import com.baeldung.templatemethodpattern.model.StandardComputer; +import com.baeldung.pattern.templatemethod.model.Computer; +import com.baeldung.pattern.templatemethod.model.HighEndComputerBuilder; +import com.baeldung.pattern.templatemethod.model.StandardComputerBuilder; import org.junit.Assert; import static org.junit.Assert.assertEquals; import org.junit.BeforeClass; @@ -82,7 +80,7 @@ public class TemplateMethodPatternTest { assertEquals(2, highEndComputerBuilder.getComputerParts().size()); } - @Test + @Test public void givenAllHighEndParts_whenComputerisBuilt_thenComputerInstance() { assertThat(standardComputerBuilder.buildComputer(), instanceOf(Computer.class)); } diff --git a/patterns/pom.xml b/patterns/pom.xml index 68e5316f64..1462952e37 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -9,7 +9,7 @@ front-controller intercepting-filter - template-method + behavioral-patterns diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index faaabb9e2e..81e072c3a7 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/java-mongodb/pom.xml b/persistence-modules/java-mongodb/pom.xml index aab48921a6..9784b2c5a8 100644 --- a/persistence-modules/java-mongodb/pom.xml +++ b/persistence-modules/java-mongodb/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/liquibase/pom.xml b/persistence-modules/liquibase/pom.xml index 020c2516a2..a574ba497c 100644 --- a/persistence-modules/liquibase/pom.xml +++ b/persistence-modules/liquibase/pom.xml @@ -6,7 +6,7 @@ parent-modules com.baeldung 1.0.0-SNAPSHOT - ../ + ../../ 4.0.0 diff --git a/persistence-modules/querydsl/pom.xml b/persistence-modules/querydsl/pom.xml index 27f383e0c6..c2943875f1 100644 --- a/persistence-modules/querydsl/pom.xml +++ b/persistence-modules/querydsl/pom.xml @@ -15,7 +15,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/redis/pom.xml b/persistence-modules/redis/pom.xml index ef081a2c69..4321b491eb 100644 --- a/persistence-modules/redis/pom.xml +++ b/persistence-modules/redis/pom.xml @@ -15,7 +15,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/solr/pom.xml b/persistence-modules/solr/pom.xml index 2fd0bdd721..966bd8755b 100644 --- a/persistence-modules/solr/pom.xml +++ b/persistence-modules/solr/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-data-cassandra/pom.xml b/persistence-modules/spring-data-cassandra/pom.xml index 607d7b90ba..1358210a45 100644 --- a/persistence-modules/spring-data-cassandra/pom.xml +++ b/persistence-modules/spring-data-cassandra/pom.xml @@ -13,7 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-data-gemfire/pom.xml b/persistence-modules/spring-data-gemfire/pom.xml index 9108865b4c..3f7fcd03e5 100644 --- a/persistence-modules/spring-data-gemfire/pom.xml +++ b/persistence-modules/spring-data-gemfire/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-data-neo4j/pom.xml b/persistence-modules/spring-data-neo4j/pom.xml index 0055850ec3..bdd51e9659 100644 --- a/persistence-modules/spring-data-neo4j/pom.xml +++ b/persistence-modules/spring-data-neo4j/pom.xml @@ -10,7 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index b184d7e369..6cb49f11cf 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-data-solr/pom.xml b/persistence-modules/spring-data-solr/pom.xml index 0759c1dbc0..e24d8314ba 100644 --- a/persistence-modules/spring-data-solr/pom.xml +++ b/persistence-modules/spring-data-solr/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-hibernate-3/pom.xml b/persistence-modules/spring-hibernate-3/pom.xml index 8eee819572..f1873a84d3 100644 --- a/persistence-modules/spring-hibernate-3/pom.xml +++ b/persistence-modules/spring-hibernate-3/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index f1f3d10347..23cf9a4d44 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ @@ -57,6 +57,11 @@ jta ${jta.version} + + org.hibernate + hibernate-search-orm + ${hibernatesearch.version} + org.apache.tomcat @@ -184,6 +189,7 @@ 5.2.10.Final + 5.8.2.Final 8.0.7-dmr 9.0.0.M26 1.1 diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java new file mode 100644 index 0000000000..6bbd2625fc --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java @@ -0,0 +1,76 @@ +package com.baeldung.hibernatesearch; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + +@EnableTransactionManagement +@Configuration +@PropertySource({ "classpath:persistence-h2.properties" }) +@EnableJpaRepositories(basePackages = { "com.baeldung.hibernatesearch" }) +@ComponentScan({ "com.baeldung.hibernatesearch" }) +public class HibernateSearchConfig { + + @Autowired + private Environment env; + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "com.baeldung.hibernatesearch.model" }); + + JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + em.setJpaProperties(additionalProperties()); + + return em; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(emf); + + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + Properties additionalProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", Preconditions.checkNotNull(env.getProperty("hibernate.hbm2ddl.auto"))); + properties.setProperty("hibernate.dialect", Preconditions.checkNotNull(env.getProperty("hibernate.dialect"))); + return properties; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java new file mode 100644 index 0000000000..210c1c58b3 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java @@ -0,0 +1,195 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; +import org.apache.lucene.search.Query; +import org.hibernate.search.engine.ProjectionConstants; +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.FullTextQuery; +import org.hibernate.search.jpa.Search; +import org.hibernate.search.query.dsl.QueryBuilder; +import org.springframework.stereotype.Repository; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +@Repository +public class ProductSearchDao { + + @PersistenceContext + private EntityManager entityManager; + + public List searchProductNameByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameByFuzzyQuery(String text) { + + Query fuzzyQuery = getQueryBuilder() + .keyword() + .fuzzy() + .withEditDistanceUpTo(2) + .withPrefixLength(0) + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(fuzzyQuery).getResultList(); + + return results; + } + + public List searchProductNameByWildcardQuery(String text) { + + Query wildcardQuery = getQueryBuilder() + .keyword() + .wildcard() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(wildcardQuery).getResultList(); + + return results; + } + + public List searchProductDescriptionByPhraseQuery(String text) { + + Query phraseQuery = getQueryBuilder() + .phrase() + .withSlop(1) + .onField("description") + .sentence(text) + .createQuery(); + + List results = getJpaQuery(phraseQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionBySimpleQueryStringQuery(String text) { + + Query simpleQueryStringQuery = getQueryBuilder() + .simpleQueryString() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(simpleQueryStringQuery).getResultList(); + + return results; + } + + public List searchProductNameByRangeQuery(int low, int high) { + + Query rangeQuery = getQueryBuilder() + .range() + .onField("memory") + .from(low) + .to(high) + .createQuery(); + + List results = getJpaQuery(rangeQuery).getResultList(); + + return results; + } + + public List searchProductNameByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByCombinedQuery(String manufactorer, int memoryLow, int memoryTop, String extraFeature, String exclude) { + + Query combinedQuery = getQueryBuilder() + .bool() + .must(getQueryBuilder().keyword() + .onField("productName") + .matching(manufactorer) + .createQuery()) + .must(getQueryBuilder() + .range() + .onField("memory") + .from(memoryLow) + .to(memoryTop) + .createQuery()) + .should(getQueryBuilder() + .phrase() + .onField("description") + .sentence(extraFeature) + .createQuery()) + .must(getQueryBuilder() + .keyword() + .onField("productName") + .matching(exclude) + .createQuery()) + .not() + .createQuery(); + + List results = getJpaQuery(combinedQuery).getResultList(); + + return results; + } + + private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class); + } + + private QueryBuilder getQueryBuilder() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.getSearchFactory() + .buildQueryBuilder() + .forEntity(Product.class) + .get(); + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java new file mode 100644 index 0000000000..3ca020fe57 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java @@ -0,0 +1,94 @@ +package com.baeldung.hibernatesearch.model; + +import org.hibernate.search.annotations.*; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Indexed +@Table(name = "product") +public class Product { + + @Id + private int id; + + @Field(termVector = TermVector.YES) + private String productName; + + @Field(termVector = TermVector.YES) + private String description; + + @Field + private int memory; + + public Product(int id, String productName, int memory, String description) { + this.id = id; + this.productName = productName; + this.memory = memory; + this.description = description; + } + + public Product() { + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Product)) + return false; + + Product product = (Product) o; + + if (id != product.id) + return false; + if (memory != product.memory) + return false; + if (!productName.equals(product.productName)) + return false; + return description.equals(product.description); + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + productName.hashCode(); + result = 31 * result + memory; + result = 31 * result + description.hashCode(); + return result; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public int getMemory() { + return memory; + } + + public void setMemory(int memory) { + this.memory = memory; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java index 74ac0a269e..e64f0a4efe 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -21,7 +21,7 @@ import java.util.Properties; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-h2.properties" }) +@PropertySource({ "classpath:persistence-mysql.properties" }) @ComponentScan({ "com.baeldung.persistence" }) public class PersistenceConfig { diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml index 8a10fc1580..3c753a89af 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml +++ b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml @@ -4,24 +4,12 @@ "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - - com.mysql.jdbc.Driver - - - buddhinisam123 - - - jdbc:mysql://localhost:3306/spring_hibernate_many_to_many - - - root - - - org.hibernate.dialect.MySQLDialect - - - thread - + com.mysql.jdbc.Driver + tutorialmy5ql + jdbc:mysql://localhost:3306/spring_hibernate_many_to_many + tutorialuser + org.hibernate.dialect.MySQLDialect + thread true diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties index 696e805cff..915bc4317b 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties @@ -9,5 +9,9 @@ hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop +# hibernate.search.X +hibernate.search.default.directory_provider = filesystem +hibernate.search.default.indexBase = /data/index/default + # envers.X envers.audit_table_suffix=_audit_log diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java index d6ecdb29d6..1572f23ed1 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java @@ -4,7 +4,6 @@ import com.baeldung.hibernate.immutable.entities.Event; import com.baeldung.hibernate.immutable.entities.EventGeneratedId; import com.baeldung.hibernate.immutable.util.HibernateUtil; import com.google.common.collect.Sets; -import org.hibernate.CacheMode; import org.hibernate.Session; import org.junit.*; import org.junit.rules.ExpectedException; @@ -14,6 +13,9 @@ import javax.persistence.PersistenceException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; +/** + * Configured in: immutable.cfg.xml + */ public class HibernateImmutableIntegrationTest { private static Session session; @@ -98,6 +100,7 @@ public class HibernateImmutableIntegrationTest { public void updateEventGenerated() { createEventGenerated(); EventGeneratedId eventGeneratedId = (EventGeneratedId) session.createQuery("FROM EventGeneratedId WHERE name LIKE '%John%'").list().get(0); + eventGeneratedId.setName("Mike"); session.update(eventGeneratedId); session.flush(); @@ -115,7 +118,6 @@ public class HibernateImmutableIntegrationTest { private static void createEventGenerated() { EventGeneratedId eventGeneratedId = new EventGeneratedId("John", "Doe"); - eventGeneratedId.setId(4L); session.save(eventGeneratedId); } diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java index 61d821e85e..614de6d3ad 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationJavaConfigMainIntegrationTest.java @@ -1,6 +1,5 @@ package com.baeldung.hibernate.manytomany; - import java.util.HashSet; import java.util.Set; import org.hibernate.Session; @@ -17,10 +16,8 @@ import com.baeldung.hibernate.manytomany.model.Employee; import com.baeldung.hibernate.manytomany.model.Project; import com.baeldung.manytomany.spring.PersistenceConfig; - - @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { @Autowired @@ -28,7 +25,6 @@ public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { private Session session; - @Before public final void before() { session = sessionFactory.openSession(); @@ -43,11 +39,11 @@ public class HibernateManyToManyAnnotationJavaConfigMainIntegrationTest { @Test public final void whenEntitiesAreCreated_thenNoExceptions() { - Set projects = new HashSet(); - projects.add(new Project("IT Project")); - projects.add(new Project("Networking Project")); - session.persist(new Employee("Peter", "Oven", projects)); - session.persist(new Employee("Allan", "Norman", projects)); + Set projects = new HashSet(); + projects.add(new Project("IT Project")); + projects.add(new Project("Networking Project")); + session.persist(new Employee("Peter", "Oven", projects)); + session.persist(new Employee("Allan", "Norman", projects)); } } diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 9a536a0f80..0073e181cc 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -17,6 +17,9 @@ import com.baeldung.hibernate.manytomany.util.HibernateUtil; import com.baeldung.hibernate.manytomany.model.Employee; import com.baeldung.hibernate.manytomany.model.Project; +/** + * Configured in: manytomany.cfg.xml + */ public class HibernateManyToManyAnnotationMainIntegrationTest { private static SessionFactory sessionFactory; diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java new file mode 100644 index 0000000000..b69f8d3a60 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java @@ -0,0 +1,187 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; + +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.*; + +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.Search; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Commit; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { HibernateSearchConfig.class }, loader = AnnotationConfigContextLoader.class) +@Transactional +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class HibernateSearchIntegrationTest { + + @Autowired + ProductSearchDao dao; + + @PersistenceContext + private EntityManager entityManager; + + private List products; + + @Before + public void setupTestData() { + + products = Arrays.asList(new Product(1, "Apple iPhone X 256 GB", 256, "The current high-end smartphone from Apple, with lots of memory and also Face ID"), + new Product(2, "Apple iPhone X 128 GB", 128, "The current high-end smartphone from Apple, with Face ID"), new Product(3, "Apple iPhone 8 128 GB", 128, "The latest smartphone from Apple within the regular iPhone line, supporting wireless charging"), + new Product(4, "Samsung Galaxy S7 128 GB", 64, "A great Android smartphone"), new Product(5, "Microsoft Lumia 650 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), + new Product(6, "Microsoft Lumia 640 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), new Product(7, "Microsoft Lumia 630 16 GB", 16, "A cheaper smartphone, coming with Windows Mobile")); + } + + @Commit + @Test + public void testA_whenInitialTestDataInserted_thenSuccess() { + + for (int i = 0; i < products.size() - 1; i++) { + entityManager.persist(products.get(i)); + } + } + + @Test + public void testB_whenIndexInitialized_thenCorrectIndexSize() throws InterruptedException { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + fullTextEntityManager.createIndexer() + .startAndWait(); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size() - 1, indexSize); + } + + @Commit + @Test + public void testC_whenAdditionalTestDataInserted_thenSuccess() { + + entityManager.persist(products.get(products.size() - 1)); + } + + @Test + public void testD_whenAdditionalTestDataInserted_thenIndexUpdatedAutomatically() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size(), indexSize); + } + + @Test + public void testE_whenKeywordSearchOnName_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testF_whenFuzzySearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByFuzzyQuery("iPhaen"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testG_whenWildcardSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(4), products.get(5), products.get(6)); + List results = dao.searchProductNameByWildcardQuery("6*"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testH_whenPhraseSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(2)); + List results = dao.searchProductDescriptionByPhraseQuery("with wireless charging"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testI_whenSimpleQueryStringSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1)); + List results = dao.searchProductNameAndDescriptionBySimpleQueryStringQuery("Aple~2 + \"iPhone X\" + (256 | 128)"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testJ_whenRangeSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2), products.get(3)); + List results = dao.searchProductNameByRangeQuery(64, 256); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testK_whenMoreLikeThisSearch_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + + } + + @Test + public void testL_whenKeywordSearchOnNameAndDescription_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testM_whenMoreLikeThisSearchOnProductNameAndDescription_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameAndDescriptionByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + } + + @Test + public void testN_whenCombinedSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByCombinedQuery("apple", 64, 128, "face id", "samsung"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } +} diff --git a/persistence-modules/spring-jpa/.gitignore b/persistence-modules/spring-jpa/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/spring-jpa/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-jpa/README.md b/persistence-modules/spring-jpa/README.md similarity index 100% rename from spring-jpa/README.md rename to persistence-modules/spring-jpa/README.md diff --git a/spring-jpa/pom.xml b/persistence-modules/spring-jpa/pom.xml similarity index 99% rename from spring-jpa/pom.xml rename to persistence-modules/spring-jpa/pom.xml index 960dcbc588..04c64fafc3 100644 --- a/spring-jpa/pom.xml +++ b/persistence-modules/spring-jpa/pom.xml @@ -13,6 +13,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT + ../ diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJNDIConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigL2Cache.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfigXml.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/ProductConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/SpringWebConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJPAH2Config.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/StudentJpaConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/UserConfig.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/UserConfig.java diff --git a/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java diff --git a/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDao.java diff --git a/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDataSourceRouter.java diff --git a/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabase.java diff --git a/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientDatabaseContextHolder.java diff --git a/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/dsrouting/ClientService.java diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedRepositoryImpl.java diff --git a/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/extended/persistence/dao/ExtendedStudentRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/dao/StudentRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/inmemory/persistence/model/Student.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/FooDao.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/IFooDao.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Bar.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Foo.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/product/ProductRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/PossessionRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/dao/user/UserRepository.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/product/Product.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/Possession.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/multiple/model/user/User.java diff --git a/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/service/FooService.java diff --git a/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/sqlfiles/Country.java diff --git a/spring-jpa/src/main/java/org/baeldung/web/MainController.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/web/MainController.java similarity index 100% rename from spring-jpa/src/main/java/org/baeldung/web/MainController.java rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/web/MainController.java diff --git a/spring-jpa/src/main/resources/context.xml b/persistence-modules/spring-jpa/src/main/resources/context.xml similarity index 100% rename from spring-jpa/src/main/resources/context.xml rename to persistence-modules/spring-jpa/src/main/resources/context.xml diff --git a/persistence-modules/spring-jpa/src/main/resources/logback.xml b/persistence-modules/spring-jpa/src/main/resources/logback.xml new file mode 100644 index 0000000000..ec0dc2469a --- /dev/null +++ b/persistence-modules/spring-jpa/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + web - %date [%thread] %-5level %logger{36} - %message%n + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-jpa/src/main/resources/persistence-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-h2.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-h2.properties diff --git a/spring-jpa/src/main/resources/persistence-jndi.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-jndi.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-jndi.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-jndi.properties diff --git a/spring-jpa/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-multiple-db.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-multiple-db.properties diff --git a/spring-jpa/src/main/resources/persistence-mysql.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-mysql.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-mysql.properties diff --git a/spring-jpa/src/main/resources/persistence-student-h2.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-student-h2.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-student-h2.properties diff --git a/spring-jpa/src/main/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/main/resources/persistence-student.properties similarity index 100% rename from spring-jpa/src/main/resources/persistence-student.properties rename to persistence-modules/spring-jpa/src/main/resources/persistence-student.properties diff --git a/spring-jpa/src/main/resources/persistence.xml b/persistence-modules/spring-jpa/src/main/resources/persistence.xml similarity index 100% rename from spring-jpa/src/main/resources/persistence.xml rename to persistence-modules/spring-jpa/src/main/resources/persistence.xml diff --git a/spring-jpa/src/main/resources/server.xml b/persistence-modules/spring-jpa/src/main/resources/server.xml similarity index 100% rename from spring-jpa/src/main/resources/server.xml rename to persistence-modules/spring-jpa/src/main/resources/server.xml diff --git a/spring-jpa/src/main/resources/sqlfiles.properties b/persistence-modules/spring-jpa/src/main/resources/sqlfiles.properties similarity index 100% rename from spring-jpa/src/main/resources/sqlfiles.properties rename to persistence-modules/spring-jpa/src/main/resources/sqlfiles.properties diff --git a/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp b/persistence-modules/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp similarity index 100% rename from spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp rename to persistence-modules/spring-jpa/src/main/webapp/WEB-INF/views/jsp/index.jsp diff --git a/spring-jpa/src/test/java/META-INF/persistence.xml b/persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml similarity index 100% rename from spring-jpa/src/test/java/META-INF/persistence.xml rename to persistence-modules/spring-jpa/src/test/java/META-INF/persistence.xml diff --git a/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/dsrouting/DataSourceRoutingTestConfiguration.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/config/PersistenceJPAConfigDeletion.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Bar.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Baz.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/deletion/model/Foo.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/ExtendedStudentRepositoryIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/repository/InMemoryDBIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/DeletionIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/JpaMultipleDBIntegrationTest.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/PersistenceTestSuite.java diff --git a/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java b/persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java similarity index 100% rename from spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java rename to persistence-modules/spring-jpa/src/test/java/org/baeldung/persistence/service/SecondLevelCacheIntegrationTest.java diff --git a/persistence-modules/spring-jpa/src/test/resources/.gitignore b/persistence-modules/spring-jpa/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/persistence-modules/spring-jpa/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-jpa/src/test/resources/dsrouting-db.sql b/persistence-modules/spring-jpa/src/test/resources/dsrouting-db.sql similarity index 100% rename from spring-jpa/src/test/resources/dsrouting-db.sql rename to persistence-modules/spring-jpa/src/test/resources/dsrouting-db.sql diff --git a/spring-jpa/src/test/resources/persistence-student.properties b/persistence-modules/spring-jpa/src/test/resources/persistence-student.properties similarity index 100% rename from spring-jpa/src/test/resources/persistence-student.properties rename to persistence-modules/spring-jpa/src/test/resources/persistence-student.properties diff --git a/pom.xml b/pom.xml index 20f7c4ffad..cf01712cba 100644 --- a/pom.xml +++ b/pom.xml @@ -107,6 +107,7 @@ logging-modules/log-mdc logging-modules/log4j logging-modules/log4j2 + logging-modules/logback lombok mapstruct @@ -141,6 +142,7 @@ spark-java spring-5-mvc + spring-acl spring-activiti spring-akka spring-amqp @@ -177,7 +179,7 @@ spring-jmeter-jenkins spring-jms spring-jooq - spring-jpa + persistence-modules/spring-jpa spring-kafka spring-katharsis spring-ldap @@ -200,6 +202,7 @@ spring-rest-query-language spring-rest spring-rest-simple + spring-security-acl spring-security-cache-control spring-security-client/spring-security-jsp-authentication spring-security-client/spring-security-jsp-authorize diff --git a/spring-5/README.md b/spring-5/README.md index 15e12cb5dc..1b65d01811 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -10,4 +10,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) - [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) - [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) - +- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 7e30179f07..b6b6f9d370 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.M6 + 2.0.0.M7 diff --git a/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java new file mode 100644 index 0000000000..6b0a6f9808 --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitConfigTest.java @@ -0,0 +1,33 @@ +package com.baeldung.jupiter; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; + +/** + * @SpringJUnitConfig(SpringJUnitConfigTest.Config.class) is equivalent to: + * + * @ExtendWith(SpringExtension.class) + * @ContextConfiguration(classes = SpringJUnitConfigTest.Config.class ) + * + */ +@SpringJUnitConfig(SpringJUnitConfigTest.Config.class) +public class SpringJUnitConfigTest { + + @Configuration + static class Config { + } + + @Autowired + private ApplicationContext applicationContext; + + @Test + void givenAppContext_WhenInjected_ThenItShouldNotBeNull() { + assertNotNull(applicationContext); + } + +} diff --git a/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java new file mode 100644 index 0000000000..c679dce77f --- /dev/null +++ b/spring-5/src/test/java/com/baeldung/jupiter/SpringJUnitWebConfigTest.java @@ -0,0 +1,34 @@ +package com.baeldung.jupiter; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig; +import org.springframework.web.context.WebApplicationContext; + +/** + * @SpringJUnitWebConfig(SpringJUnitWebConfigTest.Config.class) is equivalent to: + * + * @ExtendWith(SpringExtension.class) + * @WebAppConfiguration + * @ContextConfiguration(classes = SpringJUnitWebConfigTest.Config.class ) + * + */ +@SpringJUnitWebConfig(SpringJUnitWebConfigTest.Config.class) +public class SpringJUnitWebConfigTest { + + @Configuration + static class Config { + } + + @Autowired + private WebApplicationContext webAppContext; + + @Test + void givenWebAppContext_WhenInjected_ThenItShouldNotBeNull() { + assertNotNull(webAppContext); + } + +} diff --git a/spring-acl/pom.xml b/spring-acl/pom.xml new file mode 100644 index 0000000000..3bcc0cf596 --- /dev/null +++ b/spring-acl/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.baeldung + spring-acl + 0.0.1-SNAPSHOT + war + + spring-acl + Spring ACL + + + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + + + + org.springframework + spring-test + test + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security + spring-security-acl + + + org.springframework.security + spring-security-config + + + org.springframework + spring-context-support + + + net.sf.ehcache + ehcache-core + 2.6.11 + jar + + + + + diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java b/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java new file mode 100644 index 0000000000..63a4ea58ef --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/ACLContext.java @@ -0,0 +1,80 @@ +package org.baeldung.acl.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cache.ehcache.EhCacheFactoryBean; +import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.acls.AclPermissionCacheOptimizer; +import org.springframework.security.acls.AclPermissionEvaluator; +import org.springframework.security.acls.domain.AclAuthorizationStrategy; +import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl; +import org.springframework.security.acls.domain.ConsoleAuditLogger; +import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; +import org.springframework.security.acls.domain.EhCacheBasedAclCache; +import org.springframework.security.acls.jdbc.BasicLookupStrategy; +import org.springframework.security.acls.jdbc.JdbcMutableAclService; +import org.springframework.security.acls.jdbc.LookupStrategy; +import org.springframework.security.acls.model.PermissionGrantingStrategy; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +@Configuration +@EnableAutoConfiguration +public class ACLContext { + + @Autowired + DataSource dataSource; + + @Bean + public EhCacheBasedAclCache aclCache() { + return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy()); + } + + @Bean + public EhCacheFactoryBean aclEhCacheFactoryBean() { + EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean(); + ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject()); + ehCacheFactoryBean.setCacheName("aclCache"); + return ehCacheFactoryBean; + } + + @Bean + public EhCacheManagerFactoryBean aclCacheManager() { + return new EhCacheManagerFactoryBean(); + } + + @Bean + public PermissionGrantingStrategy permissionGrantingStrategy() { + return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()); + } + + @Bean + public AclAuthorizationStrategy aclAuthorizationStrategy() { + return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN")); + } + + @Bean + public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { + DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); + AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService()); + expressionHandler.setPermissionEvaluator(permissionEvaluator); + expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService())); + return expressionHandler; + } + + @Bean + public LookupStrategy lookupStrategy() { + return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger()); + } + + @Bean + public JdbcMutableAclService aclService() { + return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache()); + } + +} \ No newline at end of file diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java b/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java new file mode 100644 index 0000000000..110c4a6d24 --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java @@ -0,0 +1,21 @@ +package org.baeldung.acl.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { + + @Autowired + MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler; + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + return defaultMethodSecurityExpressionHandler; + } + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java b/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java new file mode 100644 index 0000000000..9b87efa92c --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.acl.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = "org.baeldung.acl.persistence.dao") +@PropertySource("classpath:org.baeldung.acl.datasource.properties") +@EntityScan(basePackages={ "org.baeldung.acl.persistence.entity" }) +public class JPAPersistenceConfig { + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java b/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java new file mode 100644 index 0000000000..8662c88d6c --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java @@ -0,0 +1,24 @@ +package org.baeldung.acl.persistence.dao; + +import java.util.List; + +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.security.access.prepost.PostAuthorize; +import org.springframework.security.access.prepost.PostFilter; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface NoticeMessageRepository extends JpaRepository{ + + @PostFilter("hasPermission(filterObject, 'READ')") + List findAll(); + + @PostAuthorize("hasPermission(returnObject, 'READ')") + NoticeMessage findById(Integer id); + + @SuppressWarnings("unchecked") + @PreAuthorize("hasPermission(#noticeMessage, 'WRITE')") + NoticeMessage save(@Param("noticeMessage")NoticeMessage noticeMessage); + +} diff --git a/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java b/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java new file mode 100644 index 0000000000..23f01a8edb --- /dev/null +++ b/spring-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java @@ -0,0 +1,29 @@ +package org.baeldung.acl.persistence.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="system_message") +public class NoticeMessage { + + @Id + @Column + private Integer id; + @Column + private String content; + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } +} \ No newline at end of file diff --git a/spring-acl/src/main/resources/acl-data.sql b/spring-acl/src/main/resources/acl-data.sql new file mode 100644 index 0000000000..6c01eaacc2 --- /dev/null +++ b/spring-acl/src/main/resources/acl-data.sql @@ -0,0 +1,28 @@ +INSERT INTO system_message(id,content) VALUES (1,'First Level Message'); +INSERT INTO system_message(id,content) VALUES (2,'Second Level Message'); +INSERT INTO system_message(id,content) VALUES (3,'Third Level Message'); + +INSERT INTO acl_class (id, class) VALUES +(1, 'org.baeldung.acl.persistence.entity.NoticeMessage'); + +INSERT INTO acl_sid (id, principal, sid) VALUES +(1, 1, 'manager'), +(2, 1, 'hr'), +(3, 1, 'admin'), +(4, 0, 'ROLE_EDITOR'); + +INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES +(1, 1, 1, NULL, 3, 0), +(2, 1, 2, NULL, 3, 0), +(3, 1, 3, NULL, 3, 0) +; + +INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES +(1, 1, 1, 1, 1, 1, 1, 1), +(2, 1, 2, 1, 2, 1, 1, 1), +(3, 1, 3, 4, 1, 1, 1, 1), +(4, 2, 1, 2, 1, 1, 1, 1), +(5, 2, 2, 4, 1, 1, 1, 1), +(6, 3, 1, 4, 1, 1, 1, 1), +(7, 3, 2, 4, 2, 1, 1, 1) +; \ No newline at end of file diff --git a/spring-acl/src/main/resources/acl-schema.sql b/spring-acl/src/main/resources/acl-schema.sql new file mode 100644 index 0000000000..58e9394b2b --- /dev/null +++ b/spring-acl/src/main/resources/acl-schema.sql @@ -0,0 +1,58 @@ +create table system_message (id integer not null, content varchar(255), primary key (id)); + +CREATE TABLE IF NOT EXISTS acl_sid ( + id bigint(20) NOT NULL AUTO_INCREMENT, + principal tinyint(1) NOT NULL, + sid varchar(100) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_1 (sid,principal) +); + +CREATE TABLE IF NOT EXISTS acl_class ( + id bigint(20) NOT NULL AUTO_INCREMENT, + class varchar(255) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_2 (class) +); + +CREATE TABLE IF NOT EXISTS acl_entry ( + id bigint(20) NOT NULL AUTO_INCREMENT, + acl_object_identity bigint(20) NOT NULL, + ace_order int(11) NOT NULL, + sid bigint(20) NOT NULL, + mask int(11) NOT NULL, + granting tinyint(1) NOT NULL, + audit_success tinyint(1) NOT NULL, + audit_failure tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order) +); + +CREATE TABLE IF NOT EXISTS acl_object_identity ( + id bigint(20) NOT NULL AUTO_INCREMENT, + object_id_class bigint(20) NOT NULL, + object_id_identity bigint(20) NOT NULL, + parent_object bigint(20) DEFAULT NULL, + owner_sid bigint(20) DEFAULT NULL, + entries_inheriting tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity) +); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (sid) REFERENCES acl_sid(id); + +-- +-- Constraints for table acl_object_identity +-- +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (object_id_class) REFERENCES acl_class (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (owner_sid) REFERENCES acl_sid (id); \ No newline at end of file diff --git a/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties b/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties new file mode 100644 index 0000000000..739dd3f07c --- /dev/null +++ b/spring-acl/src/main/resources/org.baeldung.acl.datasource.properties @@ -0,0 +1,12 @@ +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + +spring.h2.console.path=/myconsole +spring.h2.console.enabled=true +spring.datasource.initialize=true +spring.datasource.schema=classpath:acl-schema.sql +spring.datasource.data=classpath:acl-data.sql \ No newline at end of file diff --git a/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java b/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java new file mode 100644 index 0000000000..fd9069d9bc --- /dev/null +++ b/spring-acl/src/test/java/org/baeldung/acl/SpringAclTest.java @@ -0,0 +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); + } +} + \ No newline at end of file diff --git a/spring-aop/src/main/resources/logback.xml b/spring-aop/src/main/resources/logback.xml index ec0dc2469a..3245e94f08 100644 --- a/spring-aop/src/main/resources/logback.xml +++ b/spring-aop/src/main/resources/logback.xml @@ -13,7 +13,11 @@ - + + + + + \ No newline at end of file diff --git a/spring-cloud/README.md b/spring-cloud/README.md index 1b793144b1..b24e5b0296 100644 --- a/spring-cloud/README.md +++ b/spring-cloud/README.md @@ -15,6 +15,7 @@ - [Intro to Spring Cloud Netflix - Hystrix](http://www.baeldung.com/spring-cloud-netflix-hystrix) - [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application) - [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon) +- [A Quick Guide to Spring Cloud Consul](http://www.baeldung.com/spring-cloud-consul) ### Relevant Articles: - [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon) diff --git a/spring-cloud/pom.xml b/spring-cloud/pom.xml index e6d78f292d..d11455f90c 100644 --- a/spring-cloud/pom.xml +++ b/spring-cloud/pom.xml @@ -19,6 +19,7 @@ spring-cloud-stream spring-cloud-connectors-heroku spring-cloud-aws + spring-cloud-consul pom 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 index 2c3909b3eb..81bbc579ec 100644 --- 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 @@ -2,8 +2,10 @@ package com.baeldung.spring.cloud.aws; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ImportResource; @SpringBootApplication +@ImportResource("classpath:aws-config.xml") public class SpringCloudAwsApplication { public static void main(String[] args) { diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java new file mode 100644 index 0000000000..03a7db26de --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2EnableMetadata.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import org.springframework.cloud.aws.context.config.annotation.EnableContextInstanceData; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableContextInstanceData +public class EC2EnableMetadata { +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java new file mode 100644 index 0000000000..9466c14560 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/java/com/baeldung/spring/cloud/aws/ec2/EC2Metadata.java @@ -0,0 +1,62 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Lazy +@Component +public class EC2Metadata { + + @Value("${ami-id:N/A}") + private String amiId; + + @Value("${hostname:N/A}") + private String hostname; + + @Value("${instance-type:N/A}") + private String instanceType; + + @Value("${services/domain:N/A}") + private String serviceDomain; + + @Value("#{instanceData['Name'] ?: 'N/A'}") + private String name; + + public String getAmiId() { + return amiId; + } + + public String getHostname() { + return hostname; + } + + public String getInstanceType() { + return instanceType; + } + + public String getServiceDomain() { + return serviceDomain; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("EC2Metadata [amiId="); + builder.append(amiId); + builder.append(", hostname="); + builder.append(hostname); + builder.append(", instanceType="); + builder.append(instanceType); + builder.append(", serviceDomain="); + builder.append(serviceDomain); + builder.append(", name="); + builder.append(name); + builder.append("]"); + return builder.toString(); + } +} diff --git a/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml b/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml new file mode 100644 index 0000000000..5ca48f6b1e --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/main/resources/aws-config.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java new file mode 100644 index 0000000000..1e75134194 --- /dev/null +++ b/spring-cloud/spring-cloud-aws/src/test/java/com/baeldung/spring/cloud/aws/ec2/EC2MetadataIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.spring.cloud.aws.ec2; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Assume; +import org.junit.Before; +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.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import com.amazonaws.regions.Regions; +import com.amazonaws.services.ec2.AmazonEC2; + +@SpringBootTest +@RunWith(SpringRunner.class) +@TestPropertySource("classpath:application-test.properties") +public class EC2MetadataIntegrationTest { + + private static final Logger logger = LoggerFactory.getLogger(EC2MetadataIntegrationTest.class); + + private boolean serverEc2; + + @Before + public void setUp() { + serverEc2 = Regions.getCurrentRegion() != null; + } + + @Autowired + private EC2Metadata eC2Metadata; + + @Autowired + private AmazonEC2 amazonEC2; + + @Test + public void whenEC2ClinentNotNull_thenSuccess() { + assertThat(amazonEC2).isNotNull(); + } + + @Test + public void whenEC2MetadataNotNull_thenSuccess() { + assertThat(eC2Metadata).isNotNull(); + } + + @Test + public void whenMetdataValuesNotNull_thenSuccess() { + Assume.assumeTrue(serverEc2); + assertThat(eC2Metadata.getAmiId()).isNotEqualTo("N/A"); + assertThat(eC2Metadata.getInstanceType()).isNotEqualTo("N/A"); + } + + @Test + public void whenMetadataLogged_thenSuccess() { + logger.info("Environment is EC2: {}", serverEc2); + logger.info(eC2Metadata.toString()); + } +} diff --git a/spring-cloud/spring-cloud-consul/pom.xml b/spring-cloud/spring-cloud-consul/pom.xml new file mode 100644 index 0000000000..0a0650ec8b --- /dev/null +++ b/spring-cloud/spring-cloud-consul/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.baeldung + spring-cloud-consul + jar + + spring-cloud-consul + + + com.baeldung.spring.cloud + spring-cloud + 1.0.0-SNAPSHOT + + + + UTF-8 + 3.6.0 + + + + + org.springframework.cloud + spring-cloud-starter-consul-all + 1.3.0.RELEASE + + + + org.springframework.cloud + spring-cloud-starter-consul-config + 1.3.0.RELEASE + + + + + + + + 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-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java new file mode 100644 index 0000000000..d013969ad3 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.consul.discovery; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +@SpringBootApplication +@EnableDiscoveryClient +public class DiscoveryClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(DiscoveryClientApplication.class).web(true) + .run(args); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java new file mode 100644 index 0000000000..1436096d10 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/discovery/DiscoveryClientController.java @@ -0,0 +1,50 @@ +package com.baeldung.spring.cloud.consul.discovery; + +import java.net.URI; +import java.util.Optional; + +import javax.naming.ServiceUnavailableException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +@RestController +public class DiscoveryClientController { + + @Autowired + private DiscoveryClient discoveryClient; + + private final RestTemplate restTemplate = new RestTemplate(); + + @GetMapping("/discoveryClient") + public String discoveryPing() throws RestClientException, ServiceUnavailableException { + URI service = serviceUrl().map(s -> s.resolve("/ping")) + .orElseThrow(ServiceUnavailableException::new); + return restTemplate.getForEntity(service, String.class) + .getBody(); + } + + @GetMapping("/ping") + public String ping() { + return "pong"; + } + + @GetMapping("/my-health-check") + public ResponseEntity myCustomCheck() { + return new ResponseEntity<>(HttpStatus.OK); + } + + public Optional serviceUrl() { + return discoveryClient.getInstances("myApp") + .stream() + .findFirst() + .map(si -> si.getUri()); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java new file mode 100644 index 0000000000..020d7d017c --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.cloud.consul.health; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +public class ServiceDiscoveryApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(ServiceDiscoveryApplication.class).web(true) + .run(args); + } + +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java new file mode 100644 index 0000000000..20deba993f --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/health/ServiceDiscoveryController.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.consul.health; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ServiceDiscoveryController { + + @GetMapping("/ping") + public String ping() { + return "pong"; + } + + @GetMapping("/my-health-check") + public ResponseEntity myCustomCheck() { + String message = "Testing my healh check function"; + return new ResponseEntity<>(message, HttpStatus.FORBIDDEN); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java new file mode 100644 index 0000000000..c1d2b0acc5 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class DistributedPropertiesApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(DistributedPropertiesApplication.class).web(true) + .run(args); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java new file mode 100644 index 0000000000..da2d37eb76 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/DistributedPropertiesController.java @@ -0,0 +1,27 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DistributedPropertiesController { + + @Value("${my.prop}") + String value; + + @Autowired + private MyProperties properties; + + @GetMapping("/getConfigFromValue") + public String getConfigFromValue() { + return value; + } + + @GetMapping("/getConfigFromProperty") + public String getConfigFromProperty() { + return properties.getProp(); + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java new file mode 100644 index 0000000000..d92b18ed51 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/java/com/baeldung/spring/cloud/consul/properties/MyProperties.java @@ -0,0 +1,22 @@ +package com.baeldung.spring.cloud.consul.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +@RefreshScope +@Configuration +@ConfigurationProperties("my") +public class MyProperties { + + private String prop; + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + +} diff --git a/spring-cloud/spring-cloud-consul/src/main/resources/application.yml b/spring-cloud/spring-cloud-consul/src/main/resources/application.yml new file mode 100644 index 0000000000..ccdc3fdeee --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/resources/application.yml @@ -0,0 +1,14 @@ +spring: + application: + name: myApp + cloud: + consul: + host: localhost + port: 8500 + discovery: + healthCheckPath: /my-health-check + healthCheckInterval: 20s + enabled: true + instanceId: ${spring.application.name}:${random.value} +server: + port: 0 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml b/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml new file mode 100644 index 0000000000..6318170135 --- /dev/null +++ b/spring-cloud/spring-cloud-consul/src/main/resources/bootstrap.yml @@ -0,0 +1,9 @@ +spring: + application: + name: myApp + cloud: + consul: + host: localhost + port: 8500 + config: + enabled: true \ No newline at end of file diff --git a/spring-integration/README.md b/spring-integration/README.md index e5b0f601ce..750ad994eb 100644 --- a/spring-integration/README.md +++ b/spring-integration/README.md @@ -1,2 +1,5 @@ ### Relevant Articles: - [Introduction to Spring Integration](http://www.baeldung.com/spring-integration) + +### Running the Sample +Executing the `mvn exec:java` maven command (either from the command line or from an IDE) will start up the application. Follow the command prompt for further instructions. diff --git a/spring-integration/pom.xml b/spring-integration/pom.xml index a162f18b9c..4e210122b0 100644 --- a/spring-integration/pom.xml +++ b/spring-integration/pom.xml @@ -22,7 +22,7 @@ 1.1.4.RELEASE 1.4.7 1.1.1 - + 4.12 2.10 1.5.0 @@ -56,7 +56,7 @@ exec-maven-plugin ${exec-maven-plugin.version} - com.baeldung.samples.Main + com.baeldung.samples.FileCopyConfig @@ -106,6 +106,12 @@ spring-integration-file ${spring.integration.version} + + junit + junit + ${junit.version} + test + diff --git a/spring-security-acl/README.md b/spring-security-acl/README.md new file mode 100644 index 0000000000..fb3e8160ab --- /dev/null +++ b/spring-security-acl/README.md @@ -0,0 +1,4 @@ +## Spring Security ACL Project + +### Relevant Articles +- [Introduction to Spring Security ACL](http://www.baeldung.com/spring-security-acl) diff --git a/spring-security-acl/pom.xml b/spring-security-acl/pom.xml new file mode 100644 index 0000000000..67197bc2f8 --- /dev/null +++ b/spring-security-acl/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + com.baeldung + spring-security-acl + 0.0.1-SNAPSHOT + war + + spring-security-acl + Spring Security ACL + + + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + + + + org.springframework + spring-test + test + + + + org.springframework.security + spring-security-test + test + + + + org.springframework.security + spring-security-acl + + + org.springframework.security + spring-security-config + + + org.springframework + spring-context-support + + + net.sf.ehcache + ehcache-core + 2.6.11 + jar + + + + + diff --git a/spring-security-acl/src/main/java/org/baeldung/acl/config/ACLContext.java b/spring-security-acl/src/main/java/org/baeldung/acl/config/ACLContext.java new file mode 100644 index 0000000000..337e745c3c --- /dev/null +++ b/spring-security-acl/src/main/java/org/baeldung/acl/config/ACLContext.java @@ -0,0 +1,80 @@ +package org.baeldung.acl.config; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.cache.ehcache.EhCacheFactoryBean; +import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.acls.AclPermissionCacheOptimizer; +import org.springframework.security.acls.AclPermissionEvaluator; +import org.springframework.security.acls.domain.AclAuthorizationStrategy; +import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl; +import org.springframework.security.acls.domain.ConsoleAuditLogger; +import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; +import org.springframework.security.acls.domain.EhCacheBasedAclCache; +import org.springframework.security.acls.jdbc.BasicLookupStrategy; +import org.springframework.security.acls.jdbc.JdbcMutableAclService; +import org.springframework.security.acls.jdbc.LookupStrategy; +import org.springframework.security.acls.model.PermissionGrantingStrategy; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +@Configuration +@EnableAutoConfiguration +public class ACLContext { + + @Autowired + DataSource dataSource; + + @Bean + public EhCacheBasedAclCache aclCache() { + return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy()); + } + + @Bean + public EhCacheFactoryBean aclEhCacheFactoryBean() { + EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean(); + ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject()); + ehCacheFactoryBean.setCacheName("aclCache"); + return ehCacheFactoryBean; + } + + @Bean + public EhCacheManagerFactoryBean aclCacheManager() { + return new EhCacheManagerFactoryBean(); + } + + @Bean + public PermissionGrantingStrategy permissionGrantingStrategy() { + return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()); + } + + @Bean + public AclAuthorizationStrategy aclAuthorizationStrategy() { + return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN")); + } + + @Bean + public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { + DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); + AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService()); + expressionHandler.setPermissionEvaluator(permissionEvaluator); + expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService())); + return expressionHandler; + } + + @Bean + public LookupStrategy lookupStrategy() { + return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger()); + } + + @Bean + public JdbcMutableAclService aclService() { + return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache()); + } + +} \ No newline at end of file diff --git a/spring-security-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java b/spring-security-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java new file mode 100644 index 0000000000..e503cb1a41 --- /dev/null +++ b/spring-security-acl/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java @@ -0,0 +1,21 @@ +package org.baeldung.acl.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) +public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { + + @Autowired + MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler; + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + return defaultMethodSecurityExpressionHandler; + } + +} diff --git a/spring-security-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java b/spring-security-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java new file mode 100644 index 0000000000..24d170e56c --- /dev/null +++ b/spring-security-acl/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java @@ -0,0 +1,16 @@ +package org.baeldung.acl.config; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories(basePackages = "org.baeldung.acl.persistence.dao") +@PropertySource("classpath:org.baeldung.acl.datasource.properties") +@EntityScan(basePackages={ "org.baeldung.acl.persistence.entity" }) +public class JPAPersistenceConfig { + +} diff --git a/spring-security-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java b/spring-security-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java new file mode 100644 index 0000000000..91a2af7d83 --- /dev/null +++ b/spring-security-acl/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java @@ -0,0 +1,24 @@ +package org.baeldung.acl.persistence.dao; + +import java.util.List; + +import org.baeldung.acl.persistence.entity.NoticeMessage; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.security.access.prepost.PostAuthorize; +import org.springframework.security.access.prepost.PostFilter; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface NoticeMessageRepository extends JpaRepository{ + + @PostFilter("hasPermission(filterObject, 'READ')") + List findAll(); + + @PostAuthorize("hasPermission(returnObject, 'READ')") + NoticeMessage findById(Integer id); + + @SuppressWarnings("unchecked") + @PreAuthorize("hasPermission(#noticeMessage, 'WRITE')") + NoticeMessage save(@Param("noticeMessage")NoticeMessage noticeMessage); + +} diff --git a/spring-security-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java b/spring-security-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java new file mode 100644 index 0000000000..bd1e866f83 --- /dev/null +++ b/spring-security-acl/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java @@ -0,0 +1,29 @@ +package org.baeldung.acl.persistence.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="system_message") +public class NoticeMessage { + + @Id + @Column + private Integer id; + @Column + private String content; + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } +} \ No newline at end of file diff --git a/spring-security-acl/src/main/resources/acl-data.sql b/spring-security-acl/src/main/resources/acl-data.sql new file mode 100644 index 0000000000..a4e0011834 --- /dev/null +++ b/spring-security-acl/src/main/resources/acl-data.sql @@ -0,0 +1,26 @@ +INSERT INTO acl_sid (id, principal, sid) VALUES +(1, 1, 'manager'), +(2, 1, 'hr'), +(3, 0, 'ROLE_EDITOR'); + +INSERT INTO acl_class (id, class) VALUES +(1, 'org.baeldung.acl.persistence.entity.NoticeMessage'); + +INSERT INTO system_message(id,content) VALUES +(1,'First Level Message'), +(2,'Second Level Message'), +(3,'Third Level Message'); + +INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES +(1, 1, 1, NULL, 3, 0), +(2, 1, 2, NULL, 3, 0), +(3, 1, 3, NULL, 3, 0); + +INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES +(1, 1, 1, 1, 1, 1, 1, 1), +(2, 1, 2, 1, 2, 1, 1, 1), +(3, 1, 3, 3, 1, 1, 1, 1), +(4, 2, 1, 2, 1, 1, 1, 1), +(5, 2, 2, 3, 1, 1, 1, 1), +(6, 3, 1, 3, 1, 1, 1, 1), +(7, 3, 2, 3, 2, 1, 1, 1); \ No newline at end of file diff --git a/spring-security-acl/src/main/resources/acl-schema.sql b/spring-security-acl/src/main/resources/acl-schema.sql new file mode 100644 index 0000000000..9f74048230 --- /dev/null +++ b/spring-security-acl/src/main/resources/acl-schema.sql @@ -0,0 +1,58 @@ +create table IF NOT EXISTS system_message (id integer not null, content varchar(255), primary key (id)); + +CREATE TABLE IF NOT EXISTS acl_sid ( + id bigint(20) NOT NULL AUTO_INCREMENT, + principal tinyint(1) NOT NULL, + sid varchar(100) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_1 (sid,principal) +); + +CREATE TABLE IF NOT EXISTS acl_class ( + id bigint(20) NOT NULL AUTO_INCREMENT, + class varchar(255) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_2 (class) +); + +CREATE TABLE IF NOT EXISTS acl_entry ( + id bigint(20) NOT NULL AUTO_INCREMENT, + acl_object_identity bigint(20) NOT NULL, + ace_order int(11) NOT NULL, + sid bigint(20) NOT NULL, + mask int(11) NOT NULL, + granting tinyint(1) NOT NULL, + audit_success tinyint(1) NOT NULL, + audit_failure tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order) +); + +CREATE TABLE IF NOT EXISTS acl_object_identity ( + id bigint(20) NOT NULL AUTO_INCREMENT, + object_id_class bigint(20) NOT NULL, + object_id_identity bigint(20) NOT NULL, + parent_object bigint(20) DEFAULT NULL, + owner_sid bigint(20) DEFAULT NULL, + entries_inheriting tinyint(1) NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity) +); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id); + +ALTER TABLE acl_entry +ADD FOREIGN KEY (sid) REFERENCES acl_sid(id); + +-- +-- Constraints for table acl_object_identity +-- +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (object_id_class) REFERENCES acl_class (id); + +ALTER TABLE acl_object_identity +ADD FOREIGN KEY (owner_sid) REFERENCES acl_sid (id); \ No newline at end of file diff --git a/spring-security-acl/src/main/resources/org.baeldung.acl.datasource.properties b/spring-security-acl/src/main/resources/org.baeldung.acl.datasource.properties new file mode 100644 index 0000000000..40f1e6ef38 --- /dev/null +++ b/spring-security-acl/src/main/resources/org.baeldung.acl.datasource.properties @@ -0,0 +1,12 @@ +spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE +spring.datasource.username=sa +spring.datasource.password= +spring.datasource.driverClassName=org.h2.Driver +spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect + +spring.h2.console.path=/myconsole +spring.h2.console.enabled=true +spring.datasource.initialize=true +spring.datasource.schema=classpath:acl-schema.sql +spring.datasource.data=classpath:acl-data.sql \ No newline at end of file diff --git a/spring-security-acl/src/test/java/org/baeldung/acl/SpringAclTest.java b/spring-security-acl/src/test/java/org/baeldung/acl/SpringAclTest.java new file mode 100644 index 0000000000..b864639d74 --- /dev/null +++ b/spring-security-acl/src/test/java/org/baeldung/acl/SpringAclTest.java @@ -0,0 +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 givenUserManager_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 givenUserManager_whenFind1stMessageByIdAndUpdateItsContent_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_thenReturn3Message(){ + 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_whenFind1stMessageByIdAndUpdateContent_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/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java b/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java index b3c98c3e71..8a40744bdc 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java @@ -5,12 +5,13 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.FilterType; @Configuration @EnableAutoConfiguration -@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.voter.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleauthproviders.*"), - @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multiplelogin.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleentrypoints.*") }) +@ComponentScan({ "org.baeldung.config", "org.baeldung.persistence", "org.baeldung.security", "org.baeldung.web" }) +// @ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.voter.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleauthproviders.*"), +// @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multiplelogin.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleentrypoints.*"), +// @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.rolesauthorities.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.acl.*") }) public class Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Application.class, args); diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..cf1ac7de89 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,15 @@ +package org.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Application.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/testing-modules/groovy-spock/pom.xml b/testing-modules/groovy-spock/pom.xml index f4e61e6786..3d67657224 100644 --- a/testing-modules/groovy-spock/pom.xml +++ b/testing-modules/groovy-spock/pom.xml @@ -17,7 +17,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 2be8937d04..684a9253d5 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -14,7 +14,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/junit-5/src/main/java/com/baeldung/junit5/bean/NumbersBean.java b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/bean/NumbersBean.java new file mode 100644 index 0000000000..48730fd844 --- /dev/null +++ b/testing-modules/junit-5/src/main/java/com/baeldung/junit5/bean/NumbersBean.java @@ -0,0 +1,22 @@ +package com.baeldung.junit5.bean; + +/** + * Bean that contains utility methods to work with numbers. + * + * @author Donato Rimenti + * + */ +public class NumbersBean { + + /** + * Returns true if a number is even, false otherwise. + * + * @param number + * the number to check + * @return true if the argument is even, false otherwise + */ + public boolean isNumberEven(int number) { + return number % 2 == 0; + } + +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java new file mode 100644 index 0000000000..0297d010e8 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/junit5/bean/test/NumbersBeanUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.junit5.bean.test; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import com.baeldung.junit5.bean.NumbersBean; + +/** + * Test class for {@link NumbersBean}. + * + * @author Donato Rimenti + * + */ +public class NumbersBeanUnitTest { + + /** + * The bean to test. + */ + private NumbersBean bean = new NumbersBean(); + + /** + * Tests that when an even number is passed to + * {@link NumbersBean#isNumberEven(int)}, true is returned. + */ + @Test + void givenEvenNumber_whenCheckingIsNumberEven_thenTrue() { + boolean result = bean.isNumberEven(8); + + Assertions.assertTrue(result); + } + + /** + * Tests that when an odd number is passed to + * {@link NumbersBean#isNumberEven(int)}, false is returned. + */ + @Test + void givenOddNumber_whenCheckingIsNumberEven_thenFalse() { + boolean result = bean.isNumberEven(3); + + Assertions.assertFalse(result); + } + +} diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index 0291ac4ec1..2d119ae8af 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -12,7 +12,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/mockito/pom.xml b/testing-modules/mockito/pom.xml index aa3dd9b20a..0e83c46926 100644 --- a/testing-modules/mockito/pom.xml +++ b/testing-modules/mockito/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java new file mode 100644 index 0000000000..9cc586fb84 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java @@ -0,0 +1,104 @@ +package org.baeldung.bddmockito; + +import static org.junit.Assert.fail; +import static org.mockito.BDDMockito.*; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; + + +public class BDDMockitoTest { + + PhoneBookService phoneBookService; + PhoneBookRepository phoneBookRepository; + + String momContactName = "Mom"; + String momPhoneNumber = "01234"; + String xContactName = "x"; + String tooLongPhoneNumber = "01111111111111"; + + @Before + public void init() { + phoneBookRepository = Mockito.mock(PhoneBookRepository.class); + phoneBookService = new PhoneBookService(phoneBookRepository); + } + + @Test + public void givenValidContactName_whenSearchInPhoneBook_thenRetunPhoneNumber() { + given(phoneBookRepository.contains(momContactName)).willReturn(true); + given(phoneBookRepository.getPhoneNumberByContactName(momContactName)) + .will((InvocationOnMock invocation) -> { + if(invocation.getArgument(0).equals(momContactName)) { + return momPhoneNumber; + } else { + return null; + } + }); + + String phoneNumber = phoneBookService.search(momContactName); + + then(phoneBookRepository).should().contains(momContactName); + then(phoneBookRepository).should().getPhoneNumberByContactName(momContactName); + Assert.assertEquals(phoneNumber, momPhoneNumber); + } + + @Test + public void givenInvalidContactName_whenSearch_thenRetunNull() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + + String phoneNumber = phoneBookService.search(xContactName); + + then(phoneBookRepository).should().contains(xContactName); + then(phoneBookRepository).should(never()).getPhoneNumberByContactName(xContactName); + Assert.assertEquals(phoneNumber, null); + } + + @Test + public void givenValidContactNameAndPhoneNumber_whenRegister_thenSucceed() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(momContactName, momPhoneNumber); + + verify(phoneBookRepository).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenEmptyPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(xContactName, ""); + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenLongPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + willThrow(new RuntimeException()) + .given(phoneBookRepository).insert(any(String.class), eq(tooLongPhoneNumber)); + + try { + phoneBookService.register(xContactName, tooLongPhoneNumber); + fail("Should throw exception"); + } catch (RuntimeException ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, tooLongPhoneNumber); + } + + @Test + public void givenExistentContactName_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)) + .willThrow(new RuntimeException("Name already exist")); + + try { + phoneBookService.register(momContactName, momPhoneNumber); + fail("Should throw exception"); + } catch(Exception ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java new file mode 100644 index 0000000000..b73a1d835c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java @@ -0,0 +1,26 @@ +package org.baeldung.bddmockito; + +public interface PhoneBookRepository { + + /** + * Insert phone record + * @param name Contact name + * @param phone Phone number + */ + void insert(String name, String phone); + + /** + * Search for contact phone number + * @param name Contact name + * @return phone number + */ + String getPhoneNumberByContactName(String name); + + /** + * Check if the phonebook contains this contact + * @param name Contact name + * @return true if this contact name exists + */ + boolean contains(String name); + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java new file mode 100644 index 0000000000..645884af02 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java @@ -0,0 +1,34 @@ +package org.baeldung.bddmockito; + +public class PhoneBookService { + + private PhoneBookRepository phoneBookRepository; + + public PhoneBookService(PhoneBookRepository phoneBookRepository) { + this.phoneBookRepository = phoneBookRepository; + } + + /** + * Register a contact + * @param name Contact name + * @param phone Phone number + */ + public void register(String name, String phone) { + if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) { + phoneBookRepository.insert(name, phone); + } + } + + /** + * Search for a phone number by contact name + * @param name Contact name + * @return Phone number + */ + public String search(String name) { + if(!name.isEmpty() && phoneBookRepository.contains(name)) { + return phoneBookRepository.getPhoneNumberByContactName(name); + } + return null; + } + +} diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index 959c1851d6..6473f07c13 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -6,7 +6,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ mocks diff --git a/testing-modules/rest-assured/pom.xml b/testing-modules/rest-assured/pom.xml index 0c0826c5c3..1006e9a373 100644 --- a/testing-modules/rest-assured/pom.xml +++ b/testing-modules/rest-assured/pom.xml @@ -10,7 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index 4b838720da..ea63ee0e58 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/selenium-junit-testng/pom.xml b/testing-modules/selenium-junit-testng/pom.xml index 14169e5749..418dd495a4 100644 --- a/testing-modules/selenium-junit-testng/pom.xml +++ b/testing-modules/selenium-junit-testng/pom.xml @@ -9,7 +9,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/testing/pom.xml b/testing-modules/testing/pom.xml index 3ad503558f..7aff0a93e0 100644 --- a/testing-modules/testing/pom.xml +++ b/testing-modules/testing/pom.xml @@ -10,7 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index f7a50954fc..7aed1837e5 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -11,7 +11,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../ + ../../ diff --git a/undertow/dependency-reduced-pom.xml b/undertow/dependency-reduced-pom.xml new file mode 100644 index 0000000000..0654c82b74 --- /dev/null +++ b/undertow/dependency-reduced-pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + com.baeldung.undertow + undertow + undertow + 1.0-SNAPSHOT + http://maven.apache.org + + ${project.artifactId} + + + maven-shade-plugin + + + package + + shade + + + + + + maven-jar-plugin + + + + com.baeldung.undertow.SimpleServer + + + + + + + + 1.8 + 1.8 + + + diff --git a/vavr/src/main/java/com/baeldung/vavr/future/Util.java b/vavr/src/main/java/com/baeldung/vavr/future/Util.java new file mode 100644 index 0000000000..790ef2bf88 --- /dev/null +++ b/vavr/src/main/java/com/baeldung/vavr/future/Util.java @@ -0,0 +1,20 @@ +package com.baeldung.vavr.future; + +public class Util { + + public static String appendData(String initial) { + return initial + "Baeldung!"; + } + + public static int divideByZero(int num) { + return num / 0; + } + + public static String getSubstringMinusOne(String s) { + return s.substring(-1); + } + + public static String getSubstringMinusTwo(String s) { + return s.substring(-2); + } +} diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java new file mode 100644 index 0000000000..1f2a3761eb --- /dev/null +++ b/vavr/src/test/java/com/baeldung/vavr/future/FutureTest.java @@ -0,0 +1,177 @@ +package com.baeldung.vavr.future; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; + +import org.junit.Test; + +import io.vavr.Tuple; +import io.vavr.Tuple2; +import io.vavr.concurrent.Future; +import io.vavr.control.Option; +import io.vavr.control.Try; + +public class FutureTest { + + @Test + public void whenChangeExecutorService_thenCorrect() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of( + Executors.newSingleThreadExecutor(), + () -> Util.appendData(initialValue)); + String result = resultFuture.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenAppendData_thenCorrect1() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)); + String result = resultFuture.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenAppendData_thenCorrect2() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)); + resultFuture.await(); + Option> futureOption = resultFuture.getValue(); + Try futureTry = futureOption.get(); + String result = futureTry.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenAppendData_thenSuccess() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)) + .onSuccess(finalResult -> System.out.println("Successfully Completed - Result: " + finalResult)) + .onFailure(finalResult -> System.out.println("Failed - Result: " + finalResult)); + String result = resultFuture.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenChainingCallbacks_thenCorrect() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)) + .andThen(finalResult -> System.out.println("Completed - 1: " + finalResult)) + .andThen(finalResult -> System.out.println("Completed - 2: " + finalResult)); + String result = resultFuture.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenCallAwait_thenCorrect() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)); + resultFuture = resultFuture.await(); + String result = resultFuture.get(); + + assertThat(result).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenDivideByZero_thenGetThrowable1() { + Future resultFuture = Future.of(() -> Util.divideByZero(10)); + Future throwableFuture = resultFuture.failed(); + Throwable throwable = throwableFuture.get(); + + assertThat(throwable.getMessage()).isEqualTo("/ by zero"); + } + + @Test + public void whenDivideByZero_thenGetThrowable2() { + Future resultFuture = Future.of(() -> Util.divideByZero(10)); + resultFuture.await(); + Option throwableOption = resultFuture.getCause(); + Throwable throwable = throwableOption.get(); + + assertThat(throwable.getMessage()).isEqualTo("/ by zero"); + } + + @Test + public void whenDivideByZero_thenCorrect() throws InterruptedException { + Future resultFuture = Future.of(() -> Util.divideByZero(10)); + resultFuture.await(); + + assertThat(resultFuture.isCompleted()).isTrue(); + assertThat(resultFuture.isSuccess()).isFalse(); + assertThat(resultFuture.isFailure()).isTrue(); + } + + @Test + public void whenAppendData_thenFutureNotEmpty() { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)); + resultFuture.await(); + + assertThat(resultFuture.isEmpty()).isFalse(); + } + + @Test + public void whenCallZip_thenCorrect() { + Future> future = Future.of(() -> "John") + .zip(Future.of(() -> new Integer(5))); + future.await(); + + assertThat(future.get()).isEqualTo(Tuple.of("John", new Integer(5))); + } + + @Test + public void whenConvertToCompletableFuture_thenCorrect() throws InterruptedException, ExecutionException { + String initialValue = "Welcome to "; + Future resultFuture = Future.of(() -> Util.appendData(initialValue)); + CompletableFuture convertedFuture = resultFuture.toCompletableFuture(); + + assertThat(convertedFuture.get()).isEqualTo("Welcome to Baeldung!"); + } + + @Test + public void whenCallMap_thenCorrect() { + Future futureResult = Future.of(() -> new StringBuilder("from Baeldung")) + .map(a -> "Hello " + a); + futureResult.await(); + + assertThat(futureResult.get()).isEqualTo("Hello from Baeldung"); + } + + @Test + public void whenFutureFails_thenGetErrorMessage() { + Future resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello")); + Future errorMessageFuture = resultFuture.recover(Throwable::getMessage); + String errorMessage = errorMessageFuture.get(); + + assertThat(errorMessage).isEqualTo("String index out of range: -1"); + } + + @Test + public void whenFutureFails_thenGetAnotherFuture() { + Future resultFuture = Future.of(() -> Util.getSubstringMinusOne("Hello")); + Future errorMessageFuture = resultFuture.recoverWith(a -> Future.of(a::getMessage)); + String errorMessage = errorMessageFuture.get(); + + assertThat(errorMessage).isEqualTo("String index out of range: -1"); + } + + @Test + public void whenBothFuturesFail_thenGetErrorMessage() { + Future future1 = Future.of(() -> Util.getSubstringMinusOne("Hello")); + Future future2 = Future.of(() -> Util.getSubstringMinusTwo("Hello")); + Future errorMessageFuture = future1.fallbackTo(future2); + Future errorMessage = errorMessageFuture.failed(); + + assertThat( + errorMessage.get().getMessage()) + .isEqualTo("String index out of range: -1"); + } +} diff --git a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java deleted file mode 100644 index 437742c964..0000000000 --- a/vavr/src/test/java/com/baeldung/vavr/future/FutureUnitTest.java +++ /dev/null @@ -1,289 +0,0 @@ -package com.baeldung.vavr.future; - -import static io.vavr.API.$; -import static io.vavr.API.Case; -import static io.vavr.API.Match; -import static io.vavr.Predicates.exists; -import static io.vavr.Predicates.forAll; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.CancellationException; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import org.junit.Test; -import org.mockito.Mockito; -import org.mockito.internal.verification.VerificationModeFactory; -import org.mockito.verification.Timeout; - -import io.vavr.Tuple; -import io.vavr.Tuple2; -import io.vavr.collection.List; -import io.vavr.concurrent.Future; -import io.vavr.control.Try; - -public class FutureUnitTest { - - private final String SUCCESS = "Success"; - private final String FAILURE = "Failure"; - - @Test - public void givenFunctionReturnInteger_WhenCallWithFuture_ShouldReturnFunctionValue() { - Future future = Future.of(() -> 1); - - assertEquals(1, future.get().intValue()); - } - - @Test - public void givenFunctionGetRemoteHttpResourceAsString_WhenCallSuccessWithFuture_ShouldReturnContentValueAsString() { - String url = "http://resource"; - String content = "Content from " + url; - Future future = Future.of(() -> getResource(url)); - - assertEquals(content, future.get()); - } - - @Test - public void givenFunctionThrowException_WhenCallWithFuture_ShouldReturnFailure() { - Future future = Future.of(() -> getResourceThrowException("")); - future.await(); - - assertTrue(future.isFailure()); - } - - @Test - public void givenAFutureReturnZero_WhenCheckFutureWithExistEvenValue_ShouldReturnRight() { - Future future = Future.of(() -> 2); - boolean result = future.exists(i -> i % 2 == 0); - - assertTrue(result); - } - - @Test - public void givenFunction_WhenCallWithFutureAndRegisterConsumerForSuccess_ShouldCallConsumerToStoreValue() { - Future future = Future.of(() -> 1); - MockConsumer consumer = Mockito.mock(MockConsumer.class); - future.onSuccess(consumer); - Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(1); - } - - @Test - public void givenFunctionThrowException_WhenCallWithFutureAndRegisterConsumerForFailer_ShouldCallConsumerToStoreException() { - Future future = Future.of(() -> getResourceThrowException("")); - MockThrowableConsumer consumer = Mockito.mock(MockThrowableConsumer.class); - future.onFailure(consumer); - Mockito.verify(consumer, new Timeout(1000, VerificationModeFactory.times(1))).accept(Mockito.any()); - } - - @Test - public void givenAFuture_WhenAddAndThenConsumer_ShouldCallConsumerWithResultOfFutureAction() { - MockTryConsumer consumer1 = Mockito.mock(MockTryConsumer.class); - MockTryConsumer consumer2 = Mockito.mock(MockTryConsumer.class); - Future future = Future.of(() -> 1); - Future andThenFuture = future.andThen(consumer1).andThen(consumer2); - andThenFuture.await(); - Mockito.verify(consumer1, VerificationModeFactory.times(1)).accept(Try.success(1)); - Mockito.verify(consumer2, VerificationModeFactory.times(1)).accept(Try.success(1)); - } - - @Test - public void givenAFailureFuture_WhenCallOrElseFunction_ShouldReturnNewFuture() { - Future future = Future.failed(new RuntimeException()); - Future future2 = future.orElse(Future.of(() -> 2)); - - assertEquals(2, future2.get().intValue()); - } - - @Test(expected = CancellationException.class) - public void givenAFuture_WhenCallCancel_ShouldReturnCancellationException() { - long waitTime = 1000; - Future future = Future.of(() -> { - Thread.sleep(waitTime); - return 1; - }); - future.cancel(); - future.await(); - future.get(); - } - - @Test - public void givenAFuture_WhenCallFallBackWithSuccessFuture_ShouldReturnFutureResult() { - String expectedResult = "take this"; - Future future = Future.of(() -> expectedResult); - Future secondFuture = Future.of(() -> "take that"); - Future futureResult = future.fallbackTo(secondFuture); - futureResult.await(); - - assertEquals(expectedResult, futureResult.get()); - } - - @Test - public void givenAFuture_WhenCallFallBackWithFailureFuture_ShouldReturnValueOfFallBackFuture() { - String expectedResult = "take that"; - Future future = Future.failed(new RuntimeException()); - Future fallbackFuture = Future.of(() -> expectedResult); - Future futureResult = future.fallbackTo(fallbackFuture); - - assertEquals(expectedResult, futureResult.get()); - } - - @Test - public void givenAFuture_WhenTransformByAddingOne_ShouldReturn() { - Future future = Future.of(() -> 1).transformValue(f -> Try.of(() -> "Hello: " + f.get())); - - assertEquals("Hello: 1", future.get()); - } - - @Test - public void givenAFutureOfInt_WhenMapToString_ShouldCombineAndReturn() { - Future future = Future.of(()->1).map(i -> "Hello: " + i); - - assertEquals("Hello: 1", future.get()); - } - - @Test - public void givenAFutureOfInt_WhenFlatMapToString_ShouldCombineAndReturn() { - Future futureMap = Future.of(() -> 1).flatMap((i) -> Future.of(() -> "Hello: " + i)); - - assertEquals("Hello: 1", futureMap.get()); - } - - @Test - public void givenAFutureOf2String_WhenZip_ShouldReturnTupleOf2String() { - Future> future = Future.of(() -> "hello").zip(Future.of(() -> "world")); - - assertEquals(Tuple.of("hello", "world"), future.get()); - } - - @Test - public void givenGetResourceWithFuture_WhenWaitAndMatchWithPredicate_ShouldReturnSuccess() { - String url = "http://resource"; - Future future = Future.of(() -> getResource(url)); - future.await(); - String s = Match(future).of( - Case($(future0 -> future0.isSuccess()), SUCCESS), - Case($(), FAILURE)); - - assertEquals(SUCCESS, s); - } - - @Test - public void givenAFailedFuture_WhenWaitAndMatchWithPredicateCheckSuccess_ShouldReturnFailed() { - Future future = Future.failed(new RuntimeException()); - future.await(); - String s = Match(future).of( - Case($(future0 -> future0.isSuccess()), SUCCESS), - Case($(), FAILURE)); - - assertEquals(FAILURE, s); - } - - @Test - public void givenAFuture_WhenMatchWithFuturePredicate_ShouldReturnSuccess() { - Future future = Future.of(() -> { - Thread.sleep(10); - return 1; - }); - Predicate> predicate = f -> f.exists(i -> i % 2 == 1); - - String s = Match(future).of( - Case($(predicate), "Even"), - Case($(), "Odd")); - - assertEquals("Even", s); - } - - @Test - public void givenAListOfFutureReturnFist3Integers_WhenMatchWithExistEvenNumberPredicate_ShouldReturnSuccess() { - List> futures = getFutureOfFirst3Number(); - Predicate> predicate0 = future -> future.exists(i -> i % 2 == 0); - String s = Match(futures).of( - Case($(exists(predicate0)), "Even"), - Case($(), "Odd")); - - assertEquals("Even", s); - } - - @Test - public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberBiggerThanZeroPredicate_ShouldReturnSuccess() { - List> futures = getFutureOfFirst3Number(); - Predicate> predicate0 = future -> future.exists(i -> i > 0); - String s = Match(futures).of( - Case($(forAll(predicate0)), "Positive numbers"), - Case($(), "None")); - - assertEquals("Positive numbers", s); - } - - @Test - public void givenAListOfFutureReturnFist3Integers_WhenMatchWithForAllNumberSmallerThanZeroPredicate_ShouldReturnFailed() { - List> futures = getFutureOfFirst3Number(); - Predicate> predicate0 = future -> future.exists(i -> i < 0); - String s = Match(futures).of( - Case($(forAll(predicate0)), "Negative numbers"), - Case($(), "None")); - - assertEquals("None", s); - } - - private String getResource(String url) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - return "Content from " + url; - } - - private String getResourceThrowException(String url) { - throw new RuntimeException("Exception when get resource " + url); - } - - private List> getFutureOfFirst3Number() { - List> futures = List.of(Future.of(() -> 1), Future.of(() -> 2), Future.of(() -> 3)); - return futures; - } - - private static void checkOnSuccessFunction() { - Future future = Future.of(() -> 1); - future.onSuccess(i -> System.out.println("Future finish with result: " + i)); - } - - private static void checkOnFailureFunction() { - Future future = Future.of(() -> {throw new RuntimeException("Failed");}); - future.onFailure(t -> System.out.println("Future failures with exception: " + t)); - } - - private static void runAndThenConsumer() { - Future future = Future.of(() -> 1); - future.andThen(i -> System.out.println("Do side-effect action 1 with input: " + i.get())). - andThen((i) -> System.out.println("Do side-effect action 2 with input: " + i.get())); - } - - public static void main(String[] args) throws InterruptedException { - checkOnSuccessFunction(); - checkOnFailureFunction(); - runAndThenConsumer(); - Thread.sleep(1000); - } -} - - -class MockConsumer implements Consumer { - @Override - public void accept(Integer t) { - } -} - -class MockTryConsumer implements Consumer> { - @Override - public void accept(Try t) { - } -} - -class MockThrowableConsumer implements Consumer { - @Override - public void accept(Throwable t) { - } -} diff --git a/xml/src/test/resources/example_dom4j_new.xml b/xml/src/test/resources/example_dom4j_new.xml new file mode 100644 index 0000000000..020760fdd3 --- /dev/null +++ b/xml/src/test/resources/example_dom4j_new.xml @@ -0,0 +1,10 @@ + + + + + XML with Dom4J + XML handling with Dom4J + 14/06/2016 + Dom4J tech writer + + diff --git a/xml/src/test/resources/example_jaxb_new.xml b/xml/src/test/resources/example_jaxb_new.xml new file mode 100644 index 0000000000..646d938869 --- /dev/null +++ b/xml/src/test/resources/example_jaxb_new.xml @@ -0,0 +1,9 @@ + + + + Jaxb author + 04/02/2015 + XML Binding with Jaxb + XML with Jaxb + +