diff --git a/apache-olingo/olingo2/.gitignore b/apache-olingo/.gitignore similarity index 99% rename from apache-olingo/olingo2/.gitignore rename to apache-olingo/.gitignore index 153c9335eb..b85b366850 100644 --- a/apache-olingo/olingo2/.gitignore +++ b/apache-olingo/.gitignore @@ -27,3 +27,4 @@ HELP.md ### VS Code ### .vscode/ + diff --git a/apache-olingo/Samples.md b/apache-olingo/Samples.md index def8971d64..66f514b4d9 100644 --- a/apache-olingo/Samples.md +++ b/apache-olingo/Samples.md @@ -4,15 +4,15 @@ This following table contains test URLs that can be used with the Olingo V2 demo | URL | Description | |------------------------------------------|-------------------------------------------------| -| `http://localhost:8180/odata/$metadata` | fetch OData metadata document | -| `http://localhost:8180/odata/CarMakers?$top=10&$skip=10` | Get 10 entities starting at offset 10 | -| `http://localhost:8180/odata/CarMakers?$count` | Return total count of entities in this set | -| `http://localhost:8180/odata/CarMakers?$filter=startswith(Name,'B')` | Return entities where the *Name* property starts with 'B' | -| `http://localhost:8180/odata/CarModels?$filter=Year eq 2008 and CarMakerDetails/Name eq 'BWM'` | Return *CarModel* entities where the *Name* property of its maker starts with 'B' | -| `http://localhost:8180/odata/CarModels(1L)?$expand=CarMakerDetails` | Return the *CarModel* with primary key '1', along with its maker| -| `http://localhost:8180/odata/CarModels(1L)?$select=Name,Sku` | Return the *CarModel* with primary key '1', returing only its *Name* and *Sku* properties | -| `http://localhost:8180/odata/CarModels?$orderBy=Name asc,Sku desc` | Return *CarModel* entities, ordered by the their *Name* and *Sku* properties | -| `http://localhost:8180/odata/CarModels?$format=json` | Return *CarModel* entities, using a JSON representation| +| `http://localhost:8080/odata/$metadata` | fetch OData metadata document | +| `http://localhost:8080/odata/CarMakers?$top=10&$skip=10` | Get 10 entities starting at offset 10 | +| `http://localhost:8080/odata/CarMakers?$count` | Return total count of entities in this set | +| `http://localhost:8080/odata/CarMakers?$filter=startswith(Name,'B')` | Return entities where the *Name* property starts with 'B' | +| `http://localhost:8080/odata/CarModels?$filter=Year eq 2008 and CarMakerDetails/Name eq 'BWM'` | Return *CarModel* entities where the *Name* property of its maker starts with 'B' | +| `http://localhost:8080/odata/CarModels(1L)?$expand=CarMakerDetails` | Return the *CarModel* with primary key '1', along with its maker| +| `http://localhost:8080/odata/CarModels(1L)?$select=Name,Sku` | Return the *CarModel* with primary key '1', returing only its *Name* and *Sku* properties | +| `http://localhost:8080/odata/CarModels?$orderBy=Name asc,Sku desc` | Return *CarModel* entities, ordered by the their *Name* and *Sku* properties | +| `http://localhost:8080/odata/CarModels?$format=json` | Return *CarModel* entities, using a JSON representation| diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/pom.xml similarity index 85% rename from apache-olingo/olingo2/pom.xml rename to apache-olingo/pom.xml index c86428d054..5de0dfd511 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/pom.xml @@ -3,16 +3,16 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.examples.olingo2 - olingo2 - olingo2 - Sample Olingo 2 Project + com.baeldung.examples.olingo + apache-olingo + apache-olingo + Sample Apache Olingo Project com.baeldung parent-boot-2 0.0.1-SNAPSHOT - ../../parent-boot-2 + ../parent-boot-2 @@ -43,7 +43,7 @@ org.apache.olingo olingo-odata2-core - ${olingo2.version} + ${olingo.version} @@ -55,12 +55,12 @@ org.apache.olingo olingo-odata2-jpa-processor-core - ${olingo2.version} + ${olingo.version} org.apache.olingo olingo-odata2-jpa-processor-ref - ${olingo2.version} + ${olingo.version} org.eclipse.persistence @@ -80,7 +80,7 @@ - 2.0.11 + 2.0.11 - \ No newline at end of file + diff --git a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java similarity index 97% rename from apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java rename to apache-olingo/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java index 55155732c8..343af93de9 100644 --- a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java +++ b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java @@ -27,11 +27,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -/** - * ODataJPAServiceFactory implementation for our sample domain - * @author Philippe - * - */ @Component public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { @@ -44,7 +39,7 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { /** * This method will be called by Olingo on every request to - * initialize the ODataJPAContext that will be used. + * initialize the ODataJPAContext that will be used. */ @Override public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException { @@ -54,14 +49,14 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { ODataContext octx = ctx.getODataContext(); HttpServletRequest request = (HttpServletRequest)octx.getParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT); EntityManager em = (EntityManager)request.getAttribute(JerseyConfig.EntityManagerFilter.EM_REQUEST_ATTRIBUTE); - + // Here we're passing the EM that was created by the EntityManagerFilter (see JerseyConfig) ctx.setEntityManager(new EntityManagerWrapper(em)); ctx.setPersistenceUnitName("default"); - + // We're managing the EM's lifecycle, so we must inform Olingo that it should not // try to manage transactions and/or persistence sessions - ctx.setContainerManaged(true); + ctx.setContainerManaged(true); return ctx; } diff --git a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java similarity index 89% rename from apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java rename to apache-olingo/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java index 02e5ce5adf..f300f552fe 100644 --- a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java +++ b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/JerseyConfig.java @@ -1,6 +1,12 @@ - package com.baeldung.examples.olingo2; +package com.baeldung.examples.olingo2; -import java.io.IOException; +import org.apache.olingo.odata2.api.ODataServiceFactory; +import org.apache.olingo.odata2.core.rest.ODataRootLocator; +import org.apache.olingo.odata2.core.rest.app.ODataApplication; +import org.glassfish.jersey.server.ResourceConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; @@ -15,28 +21,15 @@ import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; -import org.apache.olingo.odata2.api.ODataServiceFactory; -import org.apache.olingo.odata2.core.rest.ODataRootLocator; -import org.apache.olingo.odata2.core.rest.app.ODataApplication; -import org.glassfish.jersey.server.ResourceConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -/** - * Jersey JAX-RS configuration - * @author Philippe - * - */ @Component @ApplicationPath("/odata") public class JerseyConfig extends ResourceConfig { - - - public JerseyConfig(CarsODataJPAServiceFactory serviceFactory, EntityManagerFactory emf) { - + + + public JerseyConfig(CarsODataJPAServiceFactory serviceFactory, EntityManagerFactory emf) { + ODataApplication app = new ODataApplication(); - + app .getClasses() .forEach( c -> { @@ -46,11 +39,11 @@ public class JerseyConfig extends ResourceConfig { register(c); } }); - - register(new CarsRootLocator(serviceFactory)); + + register(new CarsRootLocator(serviceFactory)); register( new EntityManagerFilter(emf)); } - + /** * This filter handles the EntityManager transaction lifecycle. * @author Philippe @@ -72,7 +65,7 @@ public class JerseyConfig extends ResourceConfig { } @Override - public void filter(ContainerRequestContext ctx) throws IOException { + public void filter(ContainerRequestContext ctx) { log.info("[I60] >>> filter"); EntityManager em = this.emf.createEntityManager(); httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, em); @@ -85,7 +78,7 @@ public class JerseyConfig extends ResourceConfig { } @Override - public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { log.info("[I68] <<< filter"); EntityManager em = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE); diff --git a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java similarity index 88% rename from apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java rename to apache-olingo/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java index f76e0e00e3..7210f4c812 100644 --- a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java +++ b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/Olingo2SampleApplication.java @@ -7,7 +7,7 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer @SpringBootApplication public class Olingo2SampleApplication extends SpringBootServletInitializer { - public static void main(String[] args) { + public static void main(String[] args) { SpringApplication.run(Olingo2SampleApplication.class); } } diff --git a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/domain/CarMaker.java b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/domain/CarMaker.java similarity index 100% rename from apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/domain/CarMaker.java rename to apache-olingo/src/main/java/com/baeldung/examples/olingo2/domain/CarMaker.java diff --git a/apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/domain/CarModel.java b/apache-olingo/src/main/java/com/baeldung/examples/olingo2/domain/CarModel.java similarity index 100% rename from apache-olingo/olingo2/src/main/java/com/baeldung/examples/olingo2/domain/CarModel.java rename to apache-olingo/src/main/java/com/baeldung/examples/olingo2/domain/CarModel.java diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/src/main/resources/application.yml similarity index 100% rename from apache-olingo/olingo2/src/main/resources/application.yml rename to apache-olingo/src/main/resources/application.yml diff --git a/apache-olingo/olingo2/src/main/resources/data.sql b/apache-olingo/src/main/resources/data.sql similarity index 100% rename from apache-olingo/olingo2/src/main/resources/data.sql rename to apache-olingo/src/main/resources/data.sql diff --git a/apache-olingo/olingo2/src/main/resources/logback.xml b/apache-olingo/src/main/resources/logback.xml similarity index 100% rename from apache-olingo/olingo2/src/main/resources/logback.xml rename to apache-olingo/src/main/resources/logback.xml diff --git a/apache-olingo/olingo2/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java b/apache-olingo/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationIntegrationTest.java similarity index 84% rename from apache-olingo/olingo2/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java rename to apache-olingo/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationIntegrationTest.java index 74033a49cd..402c288673 100644 --- a/apache-olingo/olingo2/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationUnitTest.java +++ b/apache-olingo/src/test/java/com/baeldung/examples/olingo2/Olingo2SampleApplicationIntegrationTest.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class Olingo2SampleApplicationUnitTest { +public class Olingo2SampleApplicationIntegrationTest { @Test public void contextLoads() { diff --git a/apache-olingo/olingo2/src/test/resources/logback-test.xml b/apache-olingo/src/test/resources/logback-test.xml similarity index 100% rename from apache-olingo/olingo2/src/test/resources/logback-test.xml rename to apache-olingo/src/test/resources/logback-test.xml diff --git a/apache-olingo/olingo2/src/test/resources/olingo2-queries.json b/apache-olingo/src/test/resources/olingo2-queries.json similarity index 100% rename from apache-olingo/olingo2/src/test/resources/olingo2-queries.json rename to apache-olingo/src/test/resources/olingo2-queries.json diff --git a/apache-shiro/pom.xml b/apache-shiro/pom.xml index 325a9939b9..850653ef98 100644 --- a/apache-shiro/pom.xml +++ b/apache-shiro/pom.xml @@ -47,7 +47,7 @@ 1.5.3 - 1.2.17 + 2.17.1 \ No newline at end of file diff --git a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java index 4b2d9e1127..01e7d3adfc 100644 --- a/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java +++ b/apache-spark/src/test/java/com/baeldung/differences/rdd/TransformationsUnitTest.java @@ -1,9 +1,9 @@ package com.baeldung.differences.rdd; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; @@ -12,12 +12,15 @@ import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import java.io.File; + public class TransformationsUnitTest { - + public static final String COMMA_DELIMITER = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; + private static JavaSparkContext sc; private static JavaRDD tourists; - + @BeforeClass public static void init() { SparkConf conf = new SparkConf().setAppName("uppercaseCountries") @@ -25,8 +28,11 @@ public class TransformationsUnitTest { sc = new JavaSparkContext(conf); tourists = sc.textFile("data/Tourist.csv") .filter(line -> !line.startsWith("Region")); //filter header row + + // delete previous output dir and files + FileUtils.deleteQuietly(new File("data/output")); } - + @AfterClass public static void cleanup() { sc.close(); @@ -39,9 +45,9 @@ public class TransformationsUnitTest { return columns[1].toUpperCase(); }) .distinct(); - + upperCaseCountries.saveAsTextFile("data/output/uppercase.txt"); - + upperCaseCountries.foreach(country -> { //replace non alphanumerical characters country = country.replaceAll("[^a-zA-Z]", ""); @@ -52,9 +58,9 @@ public class TransformationsUnitTest { @Test public void whenFilterByCountry_thenShowRequestedCountryRecords() { JavaRDD touristsInMexico = tourists.filter(line -> line.split(COMMA_DELIMITER)[1].equals("Mexico")); - + touristsInMexico.saveAsTextFile("data/output/touristInMexico.txt"); - + touristsInMexico.foreach(record -> { assertEquals("Mexico", record.split(COMMA_DELIMITER)[1]); }); diff --git a/book b/book deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/iterators/Iterators.java b/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/iterators/Iterators.java index 23e6bbda77..4daf7dd9d1 100644 --- a/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/iterators/Iterators.java +++ b/core-java-modules/core-java-collections-3/src/main/java/com/baeldung/collections/iterators/Iterators.java @@ -1,17 +1,16 @@ package com.baeldung.collections.iterators; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; -/** - * Source code https://github.com/eugenp/tutorials - * - * @author Santosh Thakur - */ - public class Iterators { + private static final Logger LOG = LoggerFactory.getLogger(Iterators.class); + public static int failFast1() { ArrayList numbers = new ArrayList<>(); @@ -44,7 +43,7 @@ public class Iterators { } } - System.out.println("using iterator's remove method = " + numbers); + LOG.debug("using iterator's remove method = {}", numbers); iterator = numbers.iterator(); while (iterator.hasNext()) { diff --git a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/bitset/BitSetUnitTest.java b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/bitset/BitSetUnitTest.java index d9340f45c1..7141dbf79f 100644 --- a/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/bitset/BitSetUnitTest.java +++ b/core-java-modules/core-java-collections-3/src/test/java/com/baeldung/collections/bitset/BitSetUnitTest.java @@ -3,6 +3,8 @@ package com.baeldung.collections.bitset; import org.junit.Test; import org.openjdk.jol.info.ClassLayout; import org.openjdk.jol.info.GraphLayout; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.BitSet; @@ -10,18 +12,20 @@ import static org.assertj.core.api.Assertions.assertThat; public class BitSetUnitTest { + private static final Logger LOG = LoggerFactory.getLogger(BitSetUnitTest.class); + @Test public void givenBoolArray_whenMemoryLayout_thenConsumeMoreThanOneBit() { boolean[] bits = new boolean[1024 * 1024]; - System.out.println(ClassLayout.parseInstance(bits).toPrintable()); + LOG.debug(ClassLayout.parseInstance(bits).toPrintable()); } @Test public void givenBitSet_whenMemoryLayout_thenConsumeOneBitPerFlag() { BitSet bitSet = new BitSet(1024 * 1024); - System.out.println(GraphLayout.parseInstance(bitSet).toPrintable()); + LOG.debug(GraphLayout.parseInstance(bitSet).toPrintable()); } @Test @@ -157,7 +161,7 @@ public class BitSetUnitTest { BitSet bitSet = new BitSet(); bitSet.set(15, 25); - bitSet.stream().forEach(System.out::println); + bitSet.stream().forEach(bit -> LOG.debug(String.valueOf(bit))); assertThat(bitSet.stream().count()).isEqualTo(10); } diff --git a/core-java-modules/core-java-collections-3/src/test/resources/logback.xml b/core-java-modules/core-java-collections-3/src/test/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-modules/core-java-collections-3/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java b/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java index 9900d1c63d..b0866cb7f0 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/concurrent/prioritytaskexecution/Job.java @@ -1,9 +1,15 @@ package com.baeldung.concurrent.prioritytaskexecution; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Job implements Runnable { - private String jobName; - private JobPriority jobPriority; - + + private static final Logger LOGGER = LoggerFactory.getLogger(Job.class); + + private final String jobName; + private final JobPriority jobPriority; + public Job(String jobName, JobPriority jobPriority) { this.jobName = jobName; this.jobPriority = jobPriority != null ? jobPriority : JobPriority.MEDIUM; @@ -16,8 +22,7 @@ public class Job implements Runnable { @Override public void run() { try { - System.out.println("Job:" + jobName + - " Priority:" + jobPriority); + LOGGER.debug("Job:{} Priority:{}", jobName, jobPriority); Thread.sleep(1000); } catch (InterruptedException ignored) { } diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java b/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java index ebe59e33b1..26d620ba07 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/main/java/com/baeldung/forkjoin/CustomRecursiveAction.java @@ -1,19 +1,21 @@ package com.baeldung.forkjoin; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveAction; -import java.util.logging.Logger; public class CustomRecursiveAction extends RecursiveAction { + final Logger logger = LoggerFactory.getLogger(CustomRecursiveAction.class); + private String workLoad = ""; private static final int THRESHOLD = 4; - private static Logger logger = Logger.getAnonymousLogger(); - public CustomRecursiveAction(String workLoad) { this.workLoad = workLoad; } @@ -43,7 +45,7 @@ public class CustomRecursiveAction extends RecursiveAction { private void processing(String work) { String result = work.toUpperCase(); - logger.info("This result - (" + result + ") - was processed by " + Thread.currentThread() + logger.debug("This result - (" + result + ") - was processed by " + Thread.currentThread() .getName()); } } diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java index 1e67fe45c1..20e6a5ef5b 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/concurrent/prioritytaskexecution/PriorityJobSchedulerUnitTest.java @@ -3,9 +3,9 @@ package com.baeldung.concurrent.prioritytaskexecution; import org.junit.Test; public class PriorityJobSchedulerUnitTest { - private static int POOL_SIZE = 1; - private static int QUEUE_SIZE = 10; - + private static final int POOL_SIZE = 1; + private static final int QUEUE_SIZE = 10; + @Test public void whenMultiplePriorityJobsQueued_thenHighestPriorityJobIsPicked() { Job job1 = new Job("Job1", JobPriority.LOW); @@ -14,19 +14,19 @@ public class PriorityJobSchedulerUnitTest { Job job4 = new Job("Job4", JobPriority.MEDIUM); Job job5 = new Job("Job5", JobPriority.LOW); Job job6 = new Job("Job6", JobPriority.HIGH); - + PriorityJobScheduler pjs = new PriorityJobScheduler(POOL_SIZE, QUEUE_SIZE); - + pjs.scheduleJob(job1); pjs.scheduleJob(job2); pjs.scheduleJob(job3); pjs.scheduleJob(job4); pjs.scheduleJob(job5); pjs.scheduleJob(job6); - + // ensure no tasks is pending before closing the scheduler while (pjs.getQueuedTaskCount() != 0); - + // delay to avoid job sleep (added for demo) being interrupted try { Thread.sleep(2000); @@ -34,7 +34,7 @@ public class PriorityJobSchedulerUnitTest { Thread.currentThread().interrupt(); throw new RuntimeException(e); } - + pjs.closeScheduler(); } } diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/forkjoin/Java8ForkJoinIntegrationTest.java b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/forkjoin/Java8ForkJoinIntegrationTest.java index c469fe0195..ec10e2be79 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/forkjoin/Java8ForkJoinIntegrationTest.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/forkjoin/Java8ForkJoinIntegrationTest.java @@ -1,18 +1,15 @@ package com.baeldung.forkjoin; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import com.baeldung.forkjoin.util.PoolUtil; +import org.junit.Before; +import org.junit.Test; import java.util.Random; import java.util.concurrent.ForkJoinPool; -import org.junit.Before; -import org.junit.Test; - -import com.baeldung.forkjoin.CustomRecursiveAction; -import com.baeldung.forkjoin.CustomRecursiveTask; -import com.baeldung.forkjoin.util.PoolUtil; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class Java8ForkJoinIntegrationTest { @@ -63,11 +60,11 @@ public class Java8ForkJoinIntegrationTest { ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); forkJoinPool.execute(customRecursiveTask); - int result = customRecursiveTask.join(); + customRecursiveTask.join(); assertTrue(customRecursiveTask.isDone()); forkJoinPool.submit(customRecursiveTask); - int resultTwo = customRecursiveTask.join(); + customRecursiveTask.join(); assertTrue(customRecursiveTask.isDone()); } diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java index 85cff51eb3..dc30ce6c74 100644 --- a/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced-2/src/test/java/com/baeldung/thread/join/ThreadJoinUnitTest.java @@ -1,12 +1,12 @@ package com.baeldung.thread.join; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.logging.Logger; - import org.junit.Ignore; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; /** * Demonstrates Thread.join behavior. @@ -14,55 +14,55 @@ import org.junit.Test; */ public class ThreadJoinUnitTest { - final static Logger LOGGER = Logger.getLogger(ThreadJoinUnitTest.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(ThreadJoinUnitTest.class); - class SampleThread extends Thread { - public int processingCount = 0; + static class SampleThread extends Thread { + public int processingCount; SampleThread(int processingCount) { this.processingCount = processingCount; - LOGGER.info("Thread " + this.getName() + " created"); + LOGGER.debug("Thread " + this.getName() + " created"); } @Override public void run() { - LOGGER.info("Thread " + this.getName() + " started"); + LOGGER.debug("Thread " + this.getName() + " started"); while (processingCount > 0) { try { Thread.sleep(1000); // Simulate some work being done by thread } catch (InterruptedException e) { - LOGGER.info("Thread " + this.getName() + " interrupted."); + LOGGER.debug("Thread " + this.getName() + " interrupted."); } processingCount--; - LOGGER.info("Inside Thread " + this.getName() + ", processingCount = " + processingCount); + LOGGER.debug("Inside Thread " + this.getName() + ", processingCount = " + processingCount); } - LOGGER.info("Thread " + this.getName() + " exiting"); + LOGGER.debug("Thread " + this.getName() + " exiting"); } } @Test public void givenNewThread_whenJoinCalled_returnsImmediately() throws InterruptedException { Thread t1 = new SampleThread(0); - LOGGER.info("Invoking join."); + LOGGER.debug("Invoking join."); t1.join(); - LOGGER.info("Returned from join"); - LOGGER.info("Thread state is" + t1.getState()); + LOGGER.debug("Returned from join"); + LOGGER.debug("Thread state is" + t1.getState()); assertFalse(t1.isAlive()); } @Test - public void givenStartedThread_whenJoinCalled_waitsTillCompletion() + public void givenStartedThread_whenJoinCalled_waitsTillCompletion() throws InterruptedException { Thread t2 = new SampleThread(1); t2.start(); - LOGGER.info("Invoking join."); + LOGGER.debug("Invoking join."); t2.join(); - LOGGER.info("Returned from join"); + LOGGER.debug("Returned from join"); assertFalse(t2.isAlive()); } @Test - public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() + public void givenStartedThread_whenTimedJoinCalled_waitsUntilTimedout() throws InterruptedException { Thread t3 = new SampleThread(10); t3.start(); @@ -72,18 +72,18 @@ public class ThreadJoinUnitTest { @Test @Ignore - public void givenThreadTerminated_checkForEffect_notGuaranteed() + public void givenThreadTerminated_checkForEffect_notGuaranteed() throws InterruptedException { SampleThread t4 = new SampleThread(10); t4.start(); //not guaranteed to stop even if t4 finishes. do { - - } while (t4.processingCount > 0); + + } while (t4.processingCount > 0); } @Test - public void givenJoinWithTerminatedThread_checkForEffect_guaranteed() + public void givenJoinWithTerminatedThread_checkForEffect_guaranteed() throws InterruptedException { SampleThread t4 = new SampleThread(10); t4.start(); diff --git a/core-java-modules/core-java-concurrency-advanced-2/src/test/resources/logback.xml b/core-java-modules/core-java-concurrency-advanced-2/src/test/resources/logback.xml new file mode 100644 index 0000000000..b2fa0488f3 --- /dev/null +++ b/core-java-modules/core-java-concurrency-advanced-2/src/test/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/core-java-modules/core-java-concurrency-basic-2/README.md b/core-java-modules/core-java-concurrency-basic-2/README.md index 1dad941e57..af46046709 100644 --- a/core-java-modules/core-java-concurrency-basic-2/README.md +++ b/core-java-modules/core-java-concurrency-basic-2/README.md @@ -12,7 +12,6 @@ This module contains articles about basic Java concurrency - [Guide to AtomicMarkableReference](https://www.baeldung.com/java-atomicmarkablereference) - [Why are Local Variables Thread-Safe in Java](https://www.baeldung.com/java-local-variables-thread-safe) - [How to Stop Execution After a Certain Time in Java](https://www.baeldung.com/java-stop-execution-after-certain-time) -- [How to Handle InterruptedException in Java](https://www.baeldung.com/java-interrupted-exception) - [How to Get the Number of Threads in a Java Process](https://www.baeldung.com/java-get-number-of-threads) - [Set the Name of a Thread in Java](https://www.baeldung.com/java-set-thread-name) -- [[<-- Prev]](/core-java-modules/core-java-concurrency-basic) +- [[<-- Prev]](../core-java-concurrency-basic)[[Next -->]](../core-java-concurrency-basic-3) diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/resources/logback.xml b/core-java-modules/core-java-concurrency-basic-2/src/main/resources/logback.xml index 56af2d397e..7d900d8ea8 100644 --- a/core-java-modules/core-java-concurrency-basic-2/src/main/resources/logback.xml +++ b/core-java-modules/core-java-concurrency-basic-2/src/main/resources/logback.xml @@ -7,12 +7,6 @@ - - - - - - diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md new file mode 100644 index 0000000000..477f37e00a --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -0,0 +1,8 @@ +## Core Java Concurrency Basic + +This module contains articles about basic Java concurrency. + +### Relevant Articles: + +- [How to Handle InterruptedException in Java](https://www.baeldung.com/java-interrupted-exception) +- [[<-- Prev]](../core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-basic-3/pom.xml b/core-java-modules/core-java-concurrency-basic-3/pom.xml new file mode 100644 index 0000000000..20615e3250 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + core-java-concurrency-basic-3 + 0.1.0-SNAPSHOT + core-java-concurrency-basic-3 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + core-java-concurrency-basic-3 + + + src/main/resources + true + + + + + diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/interrupt/CustomInterruptedException.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/interrupt/CustomInterruptedException.java similarity index 100% rename from core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/interrupt/CustomInterruptedException.java rename to core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/interrupt/CustomInterruptedException.java diff --git a/core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/interrupt/InterruptExample.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/interrupt/InterruptExample.java similarity index 100% rename from core-java-modules/core-java-concurrency-basic-2/src/main/java/com/baeldung/concurrent/interrupt/InterruptExample.java rename to core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/interrupt/InterruptExample.java diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/resources/logback.xml b/core-java-modules/core-java-concurrency-basic-3/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java similarity index 81% rename from core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java rename to core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java index 1ea3f9aa9b..d11ac670f3 100644 --- a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/interrupt/InterruptExampleUnitTest.java @@ -1,7 +1,7 @@ package com.baeldung.concurrent.interrupt; -import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -9,23 +9,23 @@ public class InterruptExampleUnitTest { @Test public void whenPropagateException_thenThrowsInterruptedException() { - assertThrows(InterruptedException.class, () -> InterruptExample.propagateException()); + assertThrows(InterruptedException.class, InterruptExample::propagateException); } @Test public void whenRestoreTheState_thenReturnsTrue() { assertTrue(InterruptExample.restoreTheState()); } - + @Test public void whenThrowCustomException_thenContainsExpectedMessage() { - Exception exception = assertThrows(CustomInterruptedException.class, () -> InterruptExample.throwCustomException()); + Exception exception = assertThrows(CustomInterruptedException.class, InterruptExample::throwCustomException); String expectedMessage = "This thread was interrupted"; String actualMessage = exception.getMessage(); assertTrue(actualMessage.contains(expectedMessage)); } - + @Test public void whenHandleWithCustomException_thenReturnsTrue() throws CustomInterruptedException{ assertTrue(InterruptExample.handleWithCustomException()); diff --git a/core-java-modules/core-java-exceptions-4/README.md b/core-java-modules/core-java-exceptions-4/README.md new file mode 100644 index 0000000000..259feb685c --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception) diff --git a/core-java-modules/core-java-exceptions-4/pom.xml b/core-java-modules/core-java-exceptions-4/pom.xml new file mode 100644 index 0000000000..cc81fdc40b --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + com.baeldung.exceptions + core-java-exceptions-4 + 0.1.0-SNAPSHOT + core-java-exceptions-4 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + com.h2database + h2 + ${h2.version} + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + + + + + + + + + + 1.4.191 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemo.java b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemo.java new file mode 100644 index 0000000000..6b320976a6 --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/src/main/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemo.java @@ -0,0 +1,31 @@ +package com.baeldung.exception.arrayindexoutofbounds; + +import java.util.Arrays; +import java.util.List; + +public class ArrayIndexOutOfBoundsExceptionDemo { + + public static void main(String[] args) { + int[] numbers = new int[] { 1, 2, 3, 4, 5 }; + + getArrayElementAtIndex(numbers, 5); + getListElementAtIndex(5); + addArrayElementsUsingLoop(numbers); + } + + public static void addArrayElementsUsingLoop(int[] numbers) { + int sum = 0; + for (int i = 0; i <= numbers.length; i++) { + sum += numbers[i]; + } + } + + public static int getListElementAtIndex(int index) { + List numbersList = Arrays.asList(1, 2, 3, 4, 5); + return numbersList.get(index); + } + + public static int getArrayElementAtIndex(int[] numbers, int index) { + return numbers[index]; + } +} diff --git a/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemoUnitTest.java b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemoUnitTest.java new file mode 100644 index 0000000000..e1ad2b8021 --- /dev/null +++ b/core-java-modules/core-java-exceptions-4/src/test/java/com/baeldung/exception/arrayindexoutofbounds/ArrayIndexOutOfBoundsExceptionDemoUnitTest.java @@ -0,0 +1,34 @@ +package com.baeldung.exception.arrayindexoutofbounds; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class ArrayIndexOutOfBoundsExceptionDemoUnitTest { + + private static int[] numbers; + + @BeforeAll + public static void setUp() { + numbers = new int[] { 1, 2, 3, 4, 5 }; + } + + @Test + void givenAnArrayOfSizeFive_whenAccessedElementBeyondRange_thenShouldThrowArrayIndexOutOfBoundsException() { + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> ArrayIndexOutOfBoundsExceptionDemo.addArrayElementsUsingLoop(numbers)); + } + + @Test + void givenAnArrayOfSizeFive_whenAccessedAnElementAtIndexEqualToSize_thenShouldThrowArrayIndexOutOfBoundsException() { + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> ArrayIndexOutOfBoundsExceptionDemo.getArrayElementAtIndex(numbers, 5)); + } + + @Test + void givenAListReturnedByArraysAsListMethod_whenAccessedAnElementAtIndexEqualToSize_thenShouldThrowArrayIndexOutOfBoundsException() { + assertThrows(ArrayIndexOutOfBoundsException.class, + () -> ArrayIndexOutOfBoundsExceptionDemo.getListElementAtIndex(5)); + } +} diff --git a/core-java-modules/core-java-io/src/main/resources/log4j.properties b/core-java-modules/core-java-io/src/main/resources/log4j.properties deleted file mode 100644 index 621cf01735..0000000000 --- a/core-java-modules/core-java-io/src/main/resources/log4j.properties +++ /dev/null @@ -1,6 +0,0 @@ -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/core-java-modules/core-java-io/src/main/resources/log4jstructuraldp.properties b/core-java-modules/core-java-io/src/main/resources/log4jstructuraldp.properties deleted file mode 100644 index 5bc2bfe4b9..0000000000 --- a/core-java-modules/core-java-io/src/main/resources/log4jstructuraldp.properties +++ /dev/null @@ -1,9 +0,0 @@ - -# Root logger -log4j.rootLogger=INFO, file, stdout - -# Write to console -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/core-java-modules/core-java-io/src/main/resources/logback.xml b/core-java-modules/core-java-io/src/main/resources/logback.xml index 617917dca2..c404714347 100644 --- a/core-java-modules/core-java-io/src/main/resources/logback.xml +++ b/core-java-modules/core-java-io/src/main/resources/logback.xml @@ -7,13 +7,8 @@ - - - - - diff --git a/core-java-modules/multimodulemavenproject/README.md b/core-java-modules/multimodulemavenproject/README.md index fc4ca60b6b..13d87c36ec 100644 --- a/core-java-modules/multimodulemavenproject/README.md +++ b/core-java-modules/multimodulemavenproject/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms) +- [Importing Maven Project into Eclipse](https://www.baeldung.com/maven-import-eclipse) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 809aa72966..a25cf11454 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -46,6 +46,7 @@ core-java-concurrency-advanced-4 core-java-concurrency-basic core-java-concurrency-basic-2 + core-java-concurrency-basic-3 core-java-concurrency-collections core-java-concurrency-collections-2 core-java-console @@ -55,6 +56,7 @@ core-java-exceptions core-java-exceptions-2 core-java-exceptions-3 + core-java-exceptions-4 core-java-function core-java-functional core-java-io diff --git a/feign/README.md b/feign/README.md index 03051671d5..eeff55a4d4 100644 --- a/feign/README.md +++ b/feign/README.md @@ -5,4 +5,5 @@ This module contains articles about Feign ### Relevant Articles: - [Intro to Feign](https://www.baeldung.com/intro-to-feign) +- [Retrying Feign Calls](https://www.baeldung.com/feign-retry) diff --git a/javaxval/README.md b/javaxval/README.md index cc237e1e59..24c2cf98c5 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -11,3 +11,4 @@ This module contains articles about Bean Validation. - [Grouping Javax Validation Constraints](https://www.baeldung.com/javax-validation-groups) - [Validations for Enum Types](https://www.baeldung.com/javax-validations-enums) - [Guide to ParameterMessageInterpolator](https://www.baeldung.com/hibernate-parametermessageinterpolator) +- [Hibernate Validator Annotation Processor in Depth](https://www.baeldung.com/hibernate-validator-annotation-processor) diff --git a/javaxval/pom.xml b/javaxval/pom.xml index 57369c6f52..4131ddeb97 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -15,7 +15,7 @@ - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate-validator.version} @@ -36,10 +36,45 @@ + + + 6.0.13.Final + 6.2.0.Final + 3.6.1 + 1.8 + 1.8 3.0.0 5.0.2.RELEASE - \ No newline at end of file + diff --git a/javaxval/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java b/javaxval/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java new file mode 100644 index 0000000000..55d6dafad7 --- /dev/null +++ b/javaxval/src/main/java/com/baeldung/javaxval/hibernate/validator/ap/Message.java @@ -0,0 +1,95 @@ +package com.baeldung.javaxval.hibernate.validator.ap; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Past; +import java.util.List; +import java.util.Optional; + +public class Message { + + @NotNull(message = "Content cannot be null") + private String content; + + private boolean isDelivered; + + private List<@NotBlank String> recipients; + + // uncomment in order to trigger AP annotation detection + // The annotation @Past is disallowed for this data type. + // @Past + private String createdAt; + + public String getContent() { + return content; + } + + public Message(String content, boolean isDelivered, List<@NotBlank String> recipients, String createdAt) { + this.content = content; + this.isDelivered = isDelivered; + this.recipients = recipients; + this.createdAt = createdAt; + } + + // uncomment in order to trigger AP annotation detection + // The annotation @Min is disallowed for the return type of this method. + // @Min(3) + public boolean broadcast() { + // setup a logic + // to send to recipients + return true; + } + + // uncomment in order to trigger AP annotation detection + // Void methods may not be annotated with constraint annotations. + // @NotNull + public void archive() { + // archive the message + } + + // uncomment in order to trigger AP annotation detection + // Constraint annotations must not be specified at methods, which are no valid JavaBeans getter methods. + // NOTE: add -AmethodConstraintsSupported=false to compiler args before + // @AssertTrue + public boolean delete() { + // delete the message + return false; + } + + public void setContent(String content) { + this.content = content; + } + + public boolean isDelivered() { + return isDelivered; + } + + public void setDelivered(boolean delivered) { + isDelivered = delivered; + } + + public List getRecipients() { + return recipients; + } + + public void setRecipients(List recipients) { + this.recipients = recipients; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getName() { + return content; + } + + public void setName(String content) { + this.content = content; + } + + public Optional<@Past String> getCreatedAt() { + return Optional.ofNullable(createdAt); + } + +} diff --git a/logging-modules/log-mdc/pom.xml b/logging-modules/log-mdc/pom.xml index a21b9a8fb7..c329a9dbdb 100644 --- a/logging-modules/log-mdc/pom.xml +++ b/logging-modules/log-mdc/pom.xml @@ -94,7 +94,7 @@ - 2.7 + 2.17.1 3.3.6 3.3.0.Final diff --git a/logging-modules/log4j/pom.xml b/logging-modules/log4j/pom.xml index d3c7f8287e..ac7c8620cd 100644 --- a/logging-modules/log4j/pom.xml +++ b/logging-modules/log4j/pom.xml @@ -46,8 +46,8 @@ 1.2.17 - 2.7 - 2.7 + 2.17.1 + 2.17.1 3.3.6 diff --git a/logging-modules/log4j2/README.md b/logging-modules/log4j2/README.md index 06f218f469..f53df508bf 100644 --- a/logging-modules/log4j2/README.md +++ b/logging-modules/log4j2/README.md @@ -7,3 +7,4 @@ - [Get Log Output in JSON](http://www.baeldung.com/java-log-json-output) - [System.out.println vs Loggers](https://www.baeldung.com/java-system-out-println-vs-loggers) - [Log4j 2 Plugins](https://www.baeldung.com/log4j2-plugins) +- [Printing Thread Info in Log File Using Log4j2](https://www.baeldung.com/log4j2-print-thread-info) diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 0b6fa9b902..c3a3f4e0f9 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -111,7 +111,7 @@ 2.1.1 - 2.11.0 + 2.17.1 yyyyMMddHHmmss diff --git a/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2threadinfo/Log4j2ThreadInfo.java b/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2threadinfo/Log4j2ThreadInfo.java new file mode 100644 index 0000000000..2c9b8870e2 --- /dev/null +++ b/logging-modules/log4j2/src/main/java/com/baeldung/logging/log4j2threadinfo/Log4j2ThreadInfo.java @@ -0,0 +1,18 @@ +package com.baeldung.logging.log4j2threadinfo; + +import java.util.stream.IntStream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class Log4j2ThreadInfo { + private static final Logger logger = LogManager.getLogger(Log4j2ThreadInfo.class); + + public static void main(String[] args) { + IntStream.range(0, 5).forEach(i -> { + Runnable runnable = () -> logger.info("Logging info"); + Thread thread = new Thread(runnable); + thread.start(); + }); + } +} diff --git a/logging-modules/log4j2/src/main/resources/log4j2.xml b/logging-modules/log4j2/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..6c0bc75a94 --- /dev/null +++ b/logging-modules/log4j2/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} --- thread_id="%tid" thread_name="%tn" thread_priority="%tp" --- [%p] %m%n + + + + + + ${LOG_PATTERN} + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maven-modules/maven-dependency/README.md b/maven-modules/maven-simple/maven-dependency/README.md similarity index 100% rename from maven-modules/maven-dependency/README.md rename to maven-modules/maven-simple/maven-dependency/README.md diff --git a/maven-modules/maven-dependency/pom.xml b/maven-modules/maven-simple/maven-dependency/pom.xml similarity index 89% rename from maven-modules/maven-dependency/pom.xml rename to maven-modules/maven-simple/maven-dependency/pom.xml index f17998c327..628c1b62d4 100644 --- a/maven-modules/maven-dependency/pom.xml +++ b/maven-modules/maven-simple/maven-dependency/pom.xml @@ -3,14 +3,13 @@ xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung maven-dependency 1.0.0-SNAPSHOT pom com.baeldung - maven-modules + maven-simple 0.0.1-SNAPSHOT @@ -19,7 +18,7 @@ org.apache.commons commons-lang3 - 3.12.0 + ${commons-lang3.version} diff --git a/maven-modules/maven-dependency/src/main/java/com/baeldung/Main.java b/maven-modules/maven-simple/maven-dependency/src/main/java/com/baeldung/Main.java similarity index 100% rename from maven-modules/maven-dependency/src/main/java/com/baeldung/Main.java rename to maven-modules/maven-simple/maven-dependency/src/main/java/com/baeldung/Main.java diff --git a/maven-modules/maven-profiles/README.md b/maven-modules/maven-simple/maven-profiles/README.md similarity index 100% rename from maven-modules/maven-profiles/README.md rename to maven-modules/maven-simple/maven-profiles/README.md diff --git a/maven-modules/maven-profiles/pom.xml b/maven-modules/maven-simple/maven-profiles/pom.xml similarity index 100% rename from maven-modules/maven-profiles/pom.xml rename to maven-modules/maven-simple/maven-profiles/pom.xml diff --git a/maven-modules/maven-simple/parent-project/core/pom.xml b/maven-modules/maven-simple/parent-project/core/pom.xml new file mode 100644 index 0000000000..ec25c9ace5 --- /dev/null +++ b/maven-modules/maven-simple/parent-project/core/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + org.baeldung + core + core + + + parent-project + com.baeldung + 1.0-SNAPSHOT + + + diff --git a/maven-modules/maven-simple/parent-project/pom.xml b/maven-modules/maven-simple/parent-project/pom.xml new file mode 100644 index 0000000000..a68f8e63bc --- /dev/null +++ b/maven-modules/maven-simple/parent-project/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + parent-project + 1.0-SNAPSHOT + parent-project + pom + + + com.baeldung + maven-simple + 0.0.1-SNAPSHOT + + + + core + service + webapp + + diff --git a/maven-modules/maven-simple/parent-project/service/pom.xml b/maven-modules/maven-simple/parent-project/service/pom.xml new file mode 100644 index 0000000000..1953ec8638 --- /dev/null +++ b/maven-modules/maven-simple/parent-project/service/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + org.baeldung + service + service + + + parent-project + com.baeldung + 1.0-SNAPSHOT + + + diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml new file mode 100644 index 0000000000..bd13c5aeb8 --- /dev/null +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + org.baeldung + webapp + webapp + + + parent-project + com.baeldung + 1.0-SNAPSHOT + + + diff --git a/maven-modules/plugin-management/README.md b/maven-modules/maven-simple/plugin-management/README.md similarity index 100% rename from maven-modules/plugin-management/README.md rename to maven-modules/maven-simple/plugin-management/README.md diff --git a/maven-modules/plugin-management/pom.xml b/maven-modules/maven-simple/plugin-management/pom.xml similarity index 96% rename from maven-modules/plugin-management/pom.xml rename to maven-modules/maven-simple/plugin-management/pom.xml index cd75e5dbd0..2fb2d5ed41 100644 --- a/maven-modules/plugin-management/pom.xml +++ b/maven-modules/maven-simple/plugin-management/pom.xml @@ -4,11 +4,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 plugin-management - 0.0.1-SNAPSHOT pom - maven-modules + maven-simple com.baeldung 0.0.1-SNAPSHOT diff --git a/maven-modules/plugin-management/submodule-1/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-1/pom.xml similarity index 100% rename from maven-modules/plugin-management/submodule-1/pom.xml rename to maven-modules/maven-simple/plugin-management/submodule-1/pom.xml diff --git a/maven-modules/plugin-management/submodule-1/src/resources/include.json b/maven-modules/maven-simple/plugin-management/submodule-1/src/resources/include.json similarity index 100% rename from maven-modules/plugin-management/submodule-1/src/resources/include.json rename to maven-modules/maven-simple/plugin-management/submodule-1/src/resources/include.json diff --git a/maven-modules/plugin-management/submodule-1/src/test/java/com/baeldung/CopiesAdditionalResourcesUnitTest.java b/maven-modules/maven-simple/plugin-management/submodule-1/src/test/java/com/baeldung/CopiesAdditionalResourcesUnitTest.java similarity index 100% rename from maven-modules/plugin-management/submodule-1/src/test/java/com/baeldung/CopiesAdditionalResourcesUnitTest.java rename to maven-modules/maven-simple/plugin-management/submodule-1/src/test/java/com/baeldung/CopiesAdditionalResourcesUnitTest.java diff --git a/maven-modules/plugin-management/submodule-2/pom.xml b/maven-modules/maven-simple/plugin-management/submodule-2/pom.xml similarity index 100% rename from maven-modules/plugin-management/submodule-2/pom.xml rename to maven-modules/maven-simple/plugin-management/submodule-2/pom.xml diff --git a/maven-modules/maven-simple/pom.xml b/maven-modules/maven-simple/pom.xml new file mode 100644 index 0000000000..938e2240f8 --- /dev/null +++ b/maven-modules/maven-simple/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + maven-simple + maven-simple + pom + + + com.baeldung + maven-modules + 0.0.1-SNAPSHOT + + + + maven-profiles + plugin-management + maven-dependency + parent-project + + + \ No newline at end of file diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index e09283efb4..21bc0e72e1 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -22,7 +22,6 @@ maven-integration-test maven-multi-source maven-plugins - maven-profiles maven-properties maven-unused-dependencies @@ -34,10 +33,9 @@ maven-printing-plugins maven-builder-plugin host-maven-repo-example - plugin-management maven-surefire-plugin maven-parent-pom-resolution - maven-dependency + maven-simple diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 109bf3b64f..b7f33de237 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -88,7 +88,7 @@ 3.3.0 1.0.22.RELEASE - 2.6.1 + 2.6.3 1.9.1 diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index 7b215bfef1..f245392cb3 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -5,3 +5,4 @@ - [How to Check if a Database Table Exists with JDBC](https://www.baeldung.com/jdbc-check-table-exists) - [Inserting Null Into an Integer Column Using JDBC](https://www.baeldung.com/jdbc-insert-null-into-integer-column) - [A Guide to Auto-Commit in JDBC](https://www.baeldung.com/java-jdbc-auto-commit) +- [JDBC Connection Status](https://www.baeldung.com/jdbc-connection-status) diff --git a/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/connectionstatus/ConnectionValidation.java b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/connectionstatus/ConnectionValidation.java new file mode 100644 index 0000000000..b6818d25c2 --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/main/java/com/baeldung/connectionstatus/ConnectionValidation.java @@ -0,0 +1,65 @@ +package com.baeldung.connectionstatus; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class ConnectionValidation +{ + + public static Connection getConnection() + throws Exception + { + Class.forName("org.h2.Driver"); + String url = "jdbc:h2:mem:testdb"; + return DriverManager.getConnection(url, "user", "password"); + } + + public static void runIfOpened(Connection connection) + throws SQLException + { + if (connection != null && !connection.isClosed()) { + // run sql statements + } + else { + // handle closed connection + } + } + + public static void runIfValid(Connection connection) + throws SQLException + { + // Try to validate connection with a 5 seconds timeout + if (connection.isValid(5)) { + // run sql statements + } + else { + // handle invalid connection + } + } + + public static void runIfConnectionValid(Connection connection) + { + if (isConnectionValid(connection)) { + // run sql statements + } + else { + // handle invalid connection + } + } + + public static boolean isConnectionValid(Connection connection) + { + try { + if (connection != null && !connection.isClosed()) { + // Running a simple validation query + connection.prepareStatement("SELECT 1"); + return true; + } + } + catch (SQLException e) { + // log some useful data here + } + return false; + } +} diff --git a/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/connectionstatus/ConnectionValidationUnitTest.java b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/connectionstatus/ConnectionValidationUnitTest.java new file mode 100644 index 0000000000..26356931cc --- /dev/null +++ b/persistence-modules/core-java-persistence-2/src/test/java/com/baeldung/connectionstatus/ConnectionValidationUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.connectionstatus; + +import org.junit.jupiter.api.Test; + +import java.sql.Connection; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ConnectionValidationUnitTest +{ + @Test + void givenConnectionObject_whenCreated_thenIsNotClosed() + throws Exception + { + Connection connection = ConnectionValidation.getConnection(); + assertNotNull(connection); + assertFalse(connection.isClosed()); + } + + @Test + void givenConnectionObject_whenCreated_thenIsValid() + throws Exception + { + Connection connection = ConnectionValidation.getConnection(); + assertTrue(connection.isValid(0)); + } + + @Test + void givenConnectionObject_whenValidated_thenIsValid() + throws Exception + { + Connection connection = ConnectionValidation.getConnection(); + assertTrue(ConnectionValidation.isConnectionValid(connection)); + } + +} diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 34acd60c57..fe30c2999e 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -12,3 +12,4 @@ This module contains articles about MongoDB in Java. - [MongoDB Aggregations Using Java](https://www.baeldung.com/java-mongodb-aggregations) - [BSON to JSON Document Conversion in Java](https://www.baeldung.com/java-convert-bson-to-json) - [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists) +- [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id) diff --git a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/SpringContextTest.java index 22bd5c6551..83b7b227b3 100644 --- a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/SpringContextTest.java @@ -32,10 +32,10 @@ public class SpringContextTest { public static final String KEYSPACE_ACTIVATE_QUERY = "USE testKeySpace;"; public static final String DATA_TABLE_NAME = "book"; - + @Autowired private CassandraAdminOperations adminTemplate; - + @BeforeClass public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); @@ -47,14 +47,14 @@ public class SpringContextTest { } @Before - public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException { - adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); + public void createTable() { + adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<>()); } - + @Test public void whenSpringContextIsBootstrapped_thenNoExceptions() { } - + @After public void dropTable() { adminTemplate.dropTable(CqlIdentifier.cqlId(DATA_TABLE_NAME)); diff --git a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryLiveTest.java similarity index 92% rename from persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryLiveTest.java index 55e968d6f2..d5758c3574 100644 --- a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/BookRepositoryLiveTest.java @@ -1,17 +1,15 @@ package com.baeldung.spring.data.cassandra.repository; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -import java.io.IOException; -import java.util.HashMap; - +import com.baeldung.spring.data.cassandra.config.CassandraConfig; import com.baeldung.spring.data.cassandra.model.Book; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.collect.ImmutableSet; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.thrift.transport.TTransportException; -import com.baeldung.spring.data.cassandra.config.CassandraConfig; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.After; import org.junit.AfterClass; @@ -25,15 +23,24 @@ import org.springframework.data.cassandra.core.CassandraAdminOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.utils.UUIDs; -import com.google.common.collect.ImmutableSet; +import java.io.IOException; +import java.util.HashMap; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * Live test for Cassandra testing. + * + * This can be converted to IntegrationTest once cassandra-unit tests can be executed in parallel and + * multiple test servers started as part of test suite. + * + * Open cassandra-unit issue for parallel execution: https://github.com/jsevellec/cassandra-unit/issues/155 + */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CassandraConfig.class) -public class BookRepositoryIntegrationTest { - private static final Log LOGGER = LogFactory.getLog(BookRepositoryIntegrationTest.class); +public class BookRepositoryLiveTest { + private static final Log LOGGER = LogFactory.getLog(BookRepositoryLiveTest.class); public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };"; @@ -47,8 +54,6 @@ public class BookRepositoryIntegrationTest { @Autowired private CassandraAdminOperations adminTemplate; - // - @BeforeClass public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); @@ -62,8 +67,8 @@ public class BookRepositoryIntegrationTest { } @Before - public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException { - adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); + public void createTable() { + adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<>()); } @Test diff --git a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateLiveTest.java similarity index 93% rename from persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateLiveTest.java index 90ae68ba98..bc05302d13 100644 --- a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateIntegrationTest.java +++ b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CassandraTemplateLiveTest.java @@ -1,17 +1,13 @@ package com.baeldung.spring.data.cassandra.repository; -import static junit.framework.TestCase.assertNull; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - import com.baeldung.spring.data.cassandra.config.CassandraConfig; import com.baeldung.spring.data.cassandra.model.Book; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.collect.ImmutableSet; import org.apache.cassandra.exceptions.ConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -30,17 +26,28 @@ import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.datastax.driver.core.querybuilder.Select; -import com.datastax.driver.core.utils.UUIDs; -import com.google.common.collect.ImmutableSet; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import static junit.framework.TestCase.assertNull; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; + +/** + * Live test for Cassandra testing. + * + * This can be converted to IntegrationTest once cassandra-unit tests can be executed in parallel and + * multiple test servers started as part of test suite. + * + * Open cassandra-unit issue for parallel execution: https://github.com/jsevellec/cassandra-unit/issues/155 + */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CassandraConfig.class) -public class CassandraTemplateIntegrationTest { - private static final Log LOGGER = LogFactory.getLog(CassandraTemplateIntegrationTest.class); +public class CassandraTemplateLiveTest { + private static final Log LOGGER = LogFactory.getLog(CassandraTemplateLiveTest.class); public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace " + "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };"; @@ -54,8 +61,6 @@ public class CassandraTemplateIntegrationTest { @Autowired private CassandraOperations cassandraTemplate; - // - @BeforeClass public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); @@ -69,8 +74,8 @@ public class CassandraTemplateIntegrationTest { } @Before - public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException { - adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); + public void createTable() { + adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<>()); } @Test @@ -111,7 +116,7 @@ public class CassandraTemplateIntegrationTest { } @Test - public void whenDeletingASelectedBook_thenNotAvailableOnRetrieval() throws InterruptedException { + public void whenDeletingASelectedBook_thenNotAvailableOnRetrieval() { final Book javaBook = new Book(UUIDs.timeBased(), "Head First Java", "OReilly Media", ImmutableSet.of("Computer", "Software")); cassandraTemplate.insert(javaBook); cassandraTemplate.delete(javaBook); diff --git a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesLiveTest.java similarity index 90% rename from persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java rename to persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesLiveTest.java index f948218807..e1c67a1724 100644 --- a/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesIntegrationTest.java +++ b/persistence-modules/spring-data-cassandra/src/test/java/com/baeldung/spring/data/cassandra/repository/CqlQueriesLiveTest.java @@ -1,19 +1,16 @@ package com.baeldung.spring.data.cassandra.repository; -import static junit.framework.TestCase.assertEquals; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.thrift.transport.TTransportException; import com.baeldung.spring.data.cassandra.config.CassandraConfig; import com.baeldung.spring.data.cassandra.model.Book; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.querybuilder.Insert; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.utils.UUIDs; +import com.google.common.collect.ImmutableSet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.After; import org.junit.AfterClass; @@ -28,18 +25,25 @@ import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.datastax.driver.core.Cluster; -import com.datastax.driver.core.Session; -import com.datastax.driver.core.querybuilder.Insert; -import com.datastax.driver.core.querybuilder.QueryBuilder; -import com.datastax.driver.core.querybuilder.Select; -import com.datastax.driver.core.utils.UUIDs; -import com.google.common.collect.ImmutableSet; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; +import static junit.framework.TestCase.assertEquals; + +/** + * Live test for Cassandra testing. + * + * This can be converted to IntegrationTest once cassandra-unit tests can be executed in parallel and + * multiple test servers started as part of test suite. + * + * Open cassandra-unit issue for parallel execution: https://github.com/jsevellec/cassandra-unit/issues/155 + */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = CassandraConfig.class) -public class CqlQueriesIntegrationTest { - private static final Log LOGGER = LogFactory.getLog(CqlQueriesIntegrationTest.class); +public class CqlQueriesLiveTest { + private static final Log LOGGER = LogFactory.getLog(CqlQueriesLiveTest.class); public static final String KEYSPACE_CREATION_QUERY = "CREATE KEYSPACE IF NOT EXISTS testKeySpace " + "WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': '3' };"; @@ -53,10 +57,8 @@ public class CqlQueriesIntegrationTest { @Autowired private CassandraOperations cassandraTemplate; - // - @BeforeClass - public static void startCassandraEmbedded() throws InterruptedException, TTransportException, ConfigurationException, IOException { + public static void startCassandraEmbedded() throws Exception { EmbeddedCassandraServerHelper.startEmbeddedCassandra(25000); final Cluster cluster = Cluster.builder().addContactPoints("127.0.0.1").withPort(9142).build(); LOGGER.info("Server Started at 127.0.0.1:9142... "); @@ -68,8 +70,8 @@ public class CqlQueriesIntegrationTest { } @Before - public void createTable() throws InterruptedException, TTransportException, ConfigurationException, IOException { - adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap()); + public void createTable() { + adminTemplate.createTable(true, CqlIdentifier.cqlId(DATA_TABLE_NAME), Book.class, new HashMap<>()); } @Test diff --git a/persistence-modules/spring-data-jpa-filtering/pom.xml b/persistence-modules/spring-data-jpa-filtering/pom.xml index 287a3136fd..9c10f4a997 100644 --- a/persistence-modules/spring-data-jpa-filtering/pom.xml +++ b/persistence-modules/spring-data-jpa-filtering/pom.xml @@ -67,6 +67,7 @@ com.baeldung.boot.Application 1.10.6 42.2.5 + 2.6.1 \ No newline at end of file diff --git a/persistence-modules/spring-data-mongodb-reactive/pom.xml b/persistence-modules/spring-data-mongodb-reactive/pom.xml index 0e4efed6e6..ac2bf14635 100644 --- a/persistence-modules/spring-data-mongodb-reactive/pom.xml +++ b/persistence-modules/spring-data-mongodb-reactive/pom.xml @@ -124,7 +124,7 @@ - 5.3.13 + 5.3.15 4.5.2 3.3.1.RELEASE 3.2.6 diff --git a/persistence-modules/spring-mybatis/pom.xml b/persistence-modules/spring-mybatis/pom.xml index eb0ebd723d..65a8581f97 100644 --- a/persistence-modules/spring-mybatis/pom.xml +++ b/persistence-modules/spring-mybatis/pom.xml @@ -78,7 +78,7 @@ - 5.3.13 + 5.3.15 2.0.6 3.5.2 diff --git a/pom.xml b/pom.xml index c2979b9ed1..a4cdb35e65 100644 --- a/pom.xml +++ b/pom.xml @@ -353,7 +353,7 @@ apache-cxf apache-kafka apache-libraries - apache-olingo/olingo2 + apache-olingo apache-poi apache-rocketmq apache-shiro @@ -839,7 +839,7 @@ apache-cxf apache-kafka apache-libraries - apache-olingo/olingo2 + apache-olingo apache-poi apache-rocketmq apache-shiro diff --git a/quarkus-vs-springboot/quarkus-project/.mvn/wrapper/maven-wrapper.properties b/quarkus-vs-springboot/quarkus-project/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..8c79a83ae4 --- /dev/null +++ b/quarkus-vs-springboot/quarkus-project/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/quarkus-vs-springboot/quarkus-project/mvnw b/quarkus-vs-springboot/quarkus-project/mvnw new file mode 100755 index 0000000000..5643201c7d --- /dev/null +++ b/quarkus-vs-springboot/quarkus-project/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/quarkus-vs-springboot/quarkus-project/mvnw.cmd b/quarkus-vs-springboot/quarkus-project/mvnw.cmd new file mode 100644 index 0000000000..23b7079a3d --- /dev/null +++ b/quarkus-vs-springboot/quarkus-project/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/quarkus-vs-springboot/spring-project/.mvn/wrapper/maven-wrapper.properties b/quarkus-vs-springboot/spring-project/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..8c79a83ae4 --- /dev/null +++ b/quarkus-vs-springboot/spring-project/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/quarkus-vs-springboot/spring-project/mvnw b/quarkus-vs-springboot/spring-project/mvnw new file mode 100755 index 0000000000..5643201c7d --- /dev/null +++ b/quarkus-vs-springboot/spring-project/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/quarkus-vs-springboot/spring-project/mvnw.cmd b/quarkus-vs-springboot/spring-project/mvnw.cmd new file mode 100644 index 0000000000..23b7079a3d --- /dev/null +++ b/quarkus-vs-springboot/spring-project/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/quarkus-vs-springboot/spring-project/src/main/resources/application.properties b/quarkus-vs-springboot/spring-project/src/main/resources/application.properties index adc2f8b0b4..1d49b67fda 100644 --- a/quarkus-vs-springboot/spring-project/src/main/resources/application.properties +++ b/quarkus-vs-springboot/spring-project/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.r2dbc.url=${DB_URL:'r2dbc:postgresql://localhost:5432/postgres'} +spring.r2dbc.url=${DB_URL:r2dbc:postgresql://localhost:5432/postgres} spring.r2dbc.username=postgres spring.r2dbc.password=example spring.r2dbc.pool.enabled=true diff --git a/spring-4/pom.xml b/spring-4/pom.xml index 41f55ea13b..5887bd43e2 100644 --- a/spring-4/pom.xml +++ b/spring-4/pom.xml @@ -74,10 +74,12 @@ org.apache.logging.log4j log4j-api + ${log4j2.version} org.apache.logging.log4j log4j-core + ${log4j2.version} org.easymock @@ -115,6 +117,7 @@ 3.6 2.4.0 4.0.3 + 2.17.1 \ No newline at end of file diff --git a/spring-5-autowiring-beans/pom.xml b/spring-5-autowiring-beans/pom.xml new file mode 100644 index 0000000000..32b56cc9ad --- /dev/null +++ b/spring-5-autowiring-beans/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + spring-5-autowiring-beans + 0.0.1-SNAPSHOT + spring-5-autowiring-beans + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + + diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java new file mode 100644 index 0000000000..d2d0db7a60 --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/App.java @@ -0,0 +1,14 @@ +package com.baeldung.autowiring; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } + +} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java new file mode 100644 index 0000000000..e0c0d7eeac --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/CorrectController.java @@ -0,0 +1,18 @@ +package com.baeldung.autowiring.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; + +import com.baeldung.autowiring.service.MyService; + +@Controller +public class CorrectController { + + @Autowired + MyService myService; + + public String control() { + return myService.serve(); + } + +} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java new file mode 100644 index 0000000000..673e686f79 --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/controller/FlawedController.java @@ -0,0 +1,15 @@ +package com.baeldung.autowiring.controller; + +import org.springframework.stereotype.Controller; + +import com.baeldung.autowiring.service.MyService; + +@Controller +public class FlawedController { + + public String control() { + MyService userService = new MyService(); + return userService.serve(); + } + +} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java new file mode 100644 index 0000000000..c04ca3f4ba --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyComponent.java @@ -0,0 +1,10 @@ +package com.baeldung.autowiring.service; + +import org.springframework.stereotype.Component; + +@Component +public class MyComponent { + + public void doWork() {} + +} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java new file mode 100644 index 0000000000..3443dc05de --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyService.java @@ -0,0 +1,19 @@ +package com.baeldung.autowiring.service; + +import org.springframework.beans.factory.annotation.Autowired; + +/** + * The bean corresponding to this class is defined in MyServiceConfiguration + * Alternatively, you could choose to decorate this class with @Component or @Service + */ +public class MyService { + + @Autowired + MyComponent myComponent; + + public String serve() { + myComponent.doWork(); + return "success"; + } + +} diff --git a/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java new file mode 100644 index 0000000000..e30e4f770e --- /dev/null +++ b/spring-5-autowiring-beans/src/main/java/com/baeldung/autowiring/service/MyServiceConfiguration.java @@ -0,0 +1,14 @@ +package com.baeldung.autowiring.service; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MyServiceConfiguration { + + @Bean + MyService myService() { + return new MyService(); + } + +} diff --git a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java new file mode 100644 index 0000000000..3807641edd --- /dev/null +++ b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/CorrectControllerIntegrationTest.java @@ -0,0 +1,23 @@ +package com.baeldung.autowiring.controller; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +public class CorrectControllerIntegrationTest { + + @Autowired + CorrectController controller; + + @Test + void whenControl_ThenRunSuccessfully() { + assertDoesNotThrow(() -> controller.control()); + } + +} diff --git a/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java new file mode 100644 index 0000000000..79d446604f --- /dev/null +++ b/spring-5-autowiring-beans/src/test/java/com/baeldung/autowiring/controller/FlawedControllerIntegrationTest.java @@ -0,0 +1,28 @@ +package com.baeldung.autowiring.controller; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +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.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(SpringExtension.class) +@SpringBootTest +public class FlawedControllerIntegrationTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(FlawedControllerIntegrationTest.class); + + @Autowired + FlawedController myController; + + @Test + void whenControl_ThenThrowNullPointerException() { + NullPointerException npe = assertThrows(NullPointerException.class, () -> myController.control()); + LOGGER.error("Got a NullPointerException", npe); + } + +} diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index ac0deaa9e5..4925530a35 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -52,6 +52,7 @@ spring-boot-libraries spring-boot-libraries-2 spring-boot-logging-log4j2 + spring-boot-multiple-datasources spring-boot-mvc spring-boot-mvc-2 spring-boot-mvc-3 diff --git a/spring-boot-modules/spring-boot-1/pom.xml b/spring-boot-modules/spring-boot-1/pom.xml index b6e3717f7c..594e6459a4 100644 --- a/spring-boot-modules/spring-boot-1/pom.xml +++ b/spring-boot-modules/spring-boot-1/pom.xml @@ -68,7 +68,7 @@ - 2.14.1 + 2.17.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-2/pom.xml b/spring-boot-modules/spring-boot-2/pom.xml index 65bacb7c47..08dc517fa0 100644 --- a/spring-boot-modules/spring-boot-2/pom.xml +++ b/spring-boot-modules/spring-boot-2/pom.xml @@ -63,7 +63,7 @@ 2.14.1 - 5.3.13 + 5.3.15 11 11 diff --git a/spring-boot-modules/spring-boot-actuator/README.md b/spring-boot-modules/spring-boot-actuator/README.md index 59f7e929da..ea43377ed2 100644 --- a/spring-boot-modules/spring-boot-actuator/README.md +++ b/spring-boot-modules/spring-boot-actuator/README.md @@ -12,3 +12,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Health Indicators in Spring Boot](https://www.baeldung.com/spring-boot-health-indicators) - [How to Enable All Endpoints in Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuator-enable-endpoints) - [Spring Boot Startup Actuator Endpoint](https://www.baeldung.com/spring-boot-actuator-startup) +- [Metrics for your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) diff --git a/spring-boot-modules/spring-boot-actuator/pom.xml b/spring-boot-modules/spring-boot-actuator/pom.xml index b2c7a4d28e..1ccf436bbf 100644 --- a/spring-boot-modules/spring-boot-actuator/pom.xml +++ b/spring-boot-modules/spring-boot-actuator/pom.xml @@ -23,6 +23,10 @@ org.springframework.boot spring-boot-starter-web + + org.apache.tomcat.embed + tomcat-embed-jasper + org.springframework.boot spring-boot-starter-data-jpa @@ -35,6 +39,16 @@ com.h2database h2 + + javax.servlet + javax.servlet-api + provided + + + javax.servlet + jstl + runtime + org.springframework.boot spring-boot-starter-test @@ -51,6 +65,10 @@ spring-security-test test + + org.awaitility + awaitility + diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/MetricsApplication.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/MetricsApplication.java new file mode 100644 index 0000000000..729b3c0b96 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/MetricsApplication.java @@ -0,0 +1,42 @@ +package com.baeldung.metrics; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.security.servlet.SecurityRequestMatchersManagementContextConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.context.request.RequestContextListener; + +import javax.servlet.ServletContext; + +@EnableScheduling +@ComponentScan("com.baeldung.metrics") +@SpringBootApplication +public class MetricsApplication extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(MetricsApplication.class); + } + + @Override + public void onStartup(ServletContext sc) { + // Manages the lifecycle of the root application context + sc.addListener(new RequestContextListener()); + } + + public static void main(final String[] args) { + // only load properties for this application + System.setProperty("spring.config.location", "classpath:application-metrics.properties"); + SpringApplication.run(MetricsApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/WebConfig.java similarity index 81% rename from spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java rename to spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/WebConfig.java index e35acb0bf0..4c38e4dbad 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/WebConfig.java +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/WebConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.spring; +package com.baeldung.metrics; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -10,14 +10,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration -@ComponentScan("com.baeldung.web") +@ComponentScan("com.baeldung.metrics") @EnableWebMvc public class WebConfig implements WebMvcConfigurer { - public WebConfig() { - super(); - } - @Bean public ViewResolver viewResolver() { final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); @@ -26,11 +22,10 @@ public class WebConfig implements WebMvcConfigurer { return viewResolver; } - // API @Override public void addViewControllers(final ViewControllerRegistry registry) { - registry.addViewController("/graph.html"); - registry.addViewController("/homepage.html"); + registry.addViewController("/metrics/graph.html"); + registry.addViewController("/metrics/homepage.html"); } } \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/controller/MetricsController.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/controller/MetricsController.java new file mode 100644 index 0000000000..e52ddd70f1 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/controller/MetricsController.java @@ -0,0 +1,41 @@ +package com.baeldung.metrics.controller; + +import com.baeldung.metrics.service.InMemoryMetricService; +import com.baeldung.metrics.service.MetricService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Map; + +@Controller +@RequestMapping(value = "/metrics") +@ResponseBody +public class MetricsController { + + @Autowired + private InMemoryMetricService metricService; + + // change the qualifier to use the in-memory implementation + @Autowired + @Qualifier("customActuatorMetricService") + private MetricService graphMetricService; + + @GetMapping(value = "/metric") + public Map> getMetric() { + return metricService.getFullMetric(); + } + + @GetMapping(value = "/status-metric") + public Map getStatusMetric() { + return metricService.getStatusMetric(); + } + + @GetMapping(value = "/metric-graph-data") + public Object[][] getMetricData() { + return graphMetricService.getGraphData(); + } +} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/filter/MetricFilter.java similarity index 64% rename from spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java rename to spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/filter/MetricFilter.java index dee63b226f..0f7579f060 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricFilter.java +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/filter/MetricFilter.java @@ -1,4 +1,11 @@ -package com.baeldung.web.metric; +package com.baeldung.metrics.filter; + +import com.baeldung.metrics.service.CustomActuatorMetricService; +import com.baeldung.metrics.service.InMemoryMetricService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -9,24 +16,23 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import org.springframework.web.context.support.WebApplicationContextUtils; - @Component public class MetricFilter implements Filter { @Autowired - private IMetricService metricService; + private InMemoryMetricService metricService; @Autowired - private ICustomActuatorMetricService actMetricService; + private CustomActuatorMetricService actMetricService; @Override - public void init(final FilterConfig config) throws ServletException { + public void init(final FilterConfig config) { if (metricService == null || actMetricService == null) { - metricService = (IMetricService) WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext()).getBean("metricService"); - actMetricService = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext()).getBean(CustomActuatorMetricService.class); + WebApplicationContext appContext = WebApplicationContextUtils + .getRequiredWebApplicationContext(config.getServletContext()); + + metricService = appContext.getBean(InMemoryMetricService.class); + actMetricService = appContext.getBean(CustomActuatorMetricService.class); } } @@ -42,8 +48,4 @@ public class MetricFilter implements Filter { actMetricService.increaseCount(status); } - @Override - public void destroy() { - - } } diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/ActuatorMetricService.java similarity index 61% rename from spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java rename to spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/ActuatorMetricService.java index 8c26fa04a0..3eef265c02 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ActuatorMetricService.java +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/ActuatorMetricService.java @@ -1,32 +1,31 @@ -package com.baeldung.web.metric; +package com.baeldung.metrics.service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.MeterRegistry; - @Service -public class ActuatorMetricService implements IActuatorMetricService { +public class ActuatorMetricService implements MetricService { + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); @Autowired private MeterRegistry publicMetrics; - private final List> statusMetricsByMinute; + private final List> statusMetricsByMinute; private final List statusList; - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); public ActuatorMetricService() { - super(); - statusMetricsByMinute = new ArrayList>(); - statusList = new ArrayList(); + statusMetricsByMinute = new ArrayList<>(); + statusList = new ArrayList<>(); } @Override @@ -36,19 +35,19 @@ public class ActuatorMetricService implements IActuatorMetricService { final int rowCount = statusMetricsByMinute.size() + 1; final Object[][] result = new Object[rowCount][colCount]; result[0][0] = "Time"; - int j = 1; + int j = 1; for (final String status : statusList) { result[0][j] = status; j++; } for (int i = 1; i < rowCount; i++) { - result[i][0] = dateFormat.format(new Date(current.getTime() - (60000 * (rowCount - i)))); + result[i][0] = DATE_FORMAT.format(new Date(current.getTime() - (60000L * (rowCount - i)))); } List minuteOfStatuses; - List last = new ArrayList(); + List last = new ArrayList<>(); for (int i = 1; i < rowCount; i++) { minuteOfStatuses = statusMetricsByMinute.get(i - 1); @@ -64,11 +63,9 @@ public class ActuatorMetricService implements IActuatorMetricService { return result; } - // Non - API - - @Scheduled(fixedDelay = 60000) + @Scheduled(fixedDelayString = "${fixedDelay.in.milliseconds:60000}") private void exportMetrics() { - final ArrayList lastMinuteStatuses = initializeStatuses(statusList.size()); + final List lastMinuteStatuses = initializeStatuses(statusList.size()); for (final Meter counterMetric : publicMetrics.getMeters()) { updateMetrics(counterMetric, lastMinuteStatuses); @@ -77,34 +74,32 @@ public class ActuatorMetricService implements IActuatorMetricService { statusMetricsByMinute.add(lastMinuteStatuses); } - private ArrayList initializeStatuses(final int size) { - final ArrayList counterList = new ArrayList(); + private List initializeStatuses(int size) { + List counterList = new ArrayList<>(); for (int i = 0; i < size; i++) { counterList.add(0); } return counterList; } - private void updateMetrics(final Meter counterMetric, final ArrayList statusCount) { - String status = ""; - int index = -1; - int oldCount = 0; + private void updateMetrics(Meter counterMetric, List statusCount) { - if (counterMetric.getId().getName().contains("counter.status.")) { - status = counterMetric.getId().getName().substring(15, 18); // example 404, 200 + String metricName = counterMetric.getId().getName(); + + if (metricName.contains("counter.status.")) { + // example 404, 200 + String status = metricName.substring(15, 18); appendStatusIfNotExist(status, statusCount); - index = statusList.indexOf(status); - oldCount = statusCount.get(index) == null ? 0 : statusCount.get(index); + int index = statusList.indexOf(status); + int oldCount = statusCount.get(index) == null ? 0 : statusCount.get(index); statusCount.set(index, (int)((Counter) counterMetric).count() + oldCount); } } - private void appendStatusIfNotExist(final String status, final ArrayList statusCount) { + private void appendStatusIfNotExist(String status, List statusCount) { if (!statusList.contains(status)) { statusList.add(status); statusCount.add(0); } } - - // -} \ No newline at end of file +} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/CustomActuatorMetricService.java similarity index 68% rename from spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java rename to spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/CustomActuatorMetricService.java index ee17825b7c..9b4ccaa875 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/CustomActuatorMetricService.java +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/CustomActuatorMetricService.java @@ -1,40 +1,36 @@ -package com.baeldung.web.metric; +package com.baeldung.metrics.service; + +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.search.Search; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.search.Search; - @Service -public class CustomActuatorMetricService implements ICustomActuatorMetricService { +public class CustomActuatorMetricService implements MetricService { + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); @Autowired private MeterRegistry registry; - private final List> statusMetricsByMinute; + private final List> statusMetricsByMinute; private final List statusList; - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); public CustomActuatorMetricService() { - super(); - statusMetricsByMinute = new ArrayList>(); - statusList = new ArrayList(); + statusMetricsByMinute = new ArrayList<>(); + statusList = new ArrayList<>(); } - // API - - @Override - public void increaseCount(final int status) { + public void increaseCount(int status) { String counterName = "counter.status." + status; - registry.counter(counterName).increment(1); + registry.counter(counterName).increment(); if (!statusList.contains(counterName)) { statusList.add(counterName); } @@ -55,7 +51,7 @@ public class CustomActuatorMetricService implements ICustomActuatorMetricService } for (int i = 1; i < rowCount; i++) { - result[i][0] = dateFormat.format(new Date(current.getTime() - (60000 * (rowCount - i)))); + result[i][0] = DATE_FORMAT.format(new Date(current.getTime() - (60000L * (rowCount - i)))); } List minuteOfStatuses; @@ -72,19 +68,17 @@ public class CustomActuatorMetricService implements ICustomActuatorMetricService return result; } - // Non - API - - @Scheduled(fixedDelay = 60000) + @Scheduled(fixedDelayString = "${fixedDelay.in.milliseconds:60000}") private void exportMetrics() { - final ArrayList statusCount = new ArrayList(); + List statusCount = new ArrayList<>(); for (final String status : statusList) { Search search = registry.find(status); - if (search != null) { - Counter counter = search.counter(); - statusCount.add(counter != null ? ((int) counter.count()) : 0); - registry.remove(counter); - } else { + Counter counter = search.counter(); + if (counter == null) { statusCount.add(0); + } else { + statusCount.add((int) counter.count()); + registry.remove(counter); } } statusMetricsByMinute.add(statusCount); diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/InMemoryMetricService.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/InMemoryMetricService.java new file mode 100644 index 0000000000..0be5c21727 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/InMemoryMetricService.java @@ -0,0 +1,112 @@ +package com.baeldung.metrics.service; + +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class InMemoryMetricService implements MetricService { + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + private final Map> metricMap; + private final Map statusMetric; + private final Map> timeMap; + + public InMemoryMetricService() { + metricMap = new ConcurrentHashMap<>(); + statusMetric = new ConcurrentHashMap<>(); + timeMap = new ConcurrentHashMap<>(); + } + + public void increaseCount(String request, int status) { + increaseMainMetric(request, status); + increaseStatusMetric(status); + updateTimeMap(status); + } + + public Map> getFullMetric() { + return metricMap; + } + + public Map getStatusMetric() { + return statusMetric; + } + + public Object[][] getGraphData() { + final int colCount = statusMetric.keySet().size() + 1; + final Set allStatus = statusMetric.keySet(); + final int rowCount = timeMap.keySet().size() + 1; + + final Object[][] result = new Object[rowCount][colCount]; + result[0][0] = "Time"; + + int j = 1; + for (final int status : allStatus) { + result[0][j] = status; + j++; + } + int i = 1; + Map tempMap; + for (final Entry> entry : timeMap.entrySet()) { + result[i][0] = entry.getKey(); + tempMap = entry.getValue(); + for (j = 1; j < colCount; j++) { + result[i][j] = tempMap.get((Integer) result[0][j]); + if (result[i][j] == null) { + result[i][j] = 0; + } + } + i++; + } + + for (int k = 1; k < result[0].length; k++) { + result[0][k] = result[0][k].toString(); + } + + return result; + } + + private void increaseMainMetric(String request, int status) { + Map statusMap = metricMap.get(request); + if (statusMap == null) { + statusMap = new ConcurrentHashMap<>(); + } + + Integer count = statusMap.get(status); + if (count == null) { + count = 1; + } else { + count++; + } + statusMap.put(status, count); + metricMap.put(request, statusMap); + } + + private void increaseStatusMetric(int status) { + statusMetric.merge(status, 1, Integer::sum); + } + + private void updateTimeMap(int status) { + final String time = DATE_FORMAT.format(new Date()); + Map statusMap = timeMap.get(time); + if (statusMap == null) { + statusMap = new ConcurrentHashMap<>(); + } + + Integer count = statusMap.get(status); + if (count == null) { + count = 1; + } else { + count++; + } + statusMap.put(status, count); + timeMap.put(time, statusMap); + } + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/MetricService.java b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/MetricService.java new file mode 100644 index 0000000000..3642102b67 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/java/com/baeldung/metrics/service/MetricService.java @@ -0,0 +1,7 @@ +package com.baeldung.metrics.service; + +public interface MetricService { + + Object[][] getGraphData(); + +} diff --git a/spring-boot-modules/spring-boot-actuator/src/main/resources/application-metrics.properties b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-metrics.properties new file mode 100644 index 0000000000..5f753a0c62 --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/main/resources/application-metrics.properties @@ -0,0 +1,9 @@ +management.endpoints.web.exposure.include=info,health,metrics + +# JPA and Security is not required for Metrics application +spring.autoconfigure.exclude= org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, \ + org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, \ + org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, \ + org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, \ + org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration, \ + org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration diff --git a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/api-servlet.xml similarity index 100% rename from spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/api-servlet.xml rename to spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/api-servlet.xml diff --git a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/view/metrics/graph.jsp similarity index 93% rename from spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp rename to spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/view/metrics/graph.jsp index e1d5fdc987..75976557a0 100644 --- a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/graph.jsp +++ b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/view/metrics/graph.jsp @@ -11,7 +11,7 @@ }); function drawChart() { - $.get("", + $.get("", function(mydata) { var data = google.visualization.arrayToDataTable(mydata); diff --git a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/view/metrics/homepage.jsp similarity index 100% rename from spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/view/homepage.jsp rename to spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/view/metrics/homepage.jsp diff --git a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/web.xml b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/web.xml similarity index 91% rename from spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/web.xml rename to spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/web.xml index 7129b6b4af..84566ba93d 100644 --- a/spring-web-modules/spring-rest-testing/src/main/webapp/WEB-INF/web.xml +++ b/spring-boot-modules/spring-boot-actuator/src/main/webapp/WEB-INF/web.xml @@ -16,7 +16,7 @@ contextConfigLocation - com.baeldung.spring + com.baeldung.metrics @@ -37,7 +37,7 @@ metricFilter - com.baeldung.web.metric.MetricFilter + com.baeldung.metrics.filter.MetricFilter diff --git a/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/metrics/MetricsApplicationIntegrationTest.java b/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/metrics/MetricsApplicationIntegrationTest.java new file mode 100644 index 0000000000..c83d4625dc --- /dev/null +++ b/spring-boot-modules/spring-boot-actuator/src/test/java/com/baeldung/metrics/MetricsApplicationIntegrationTest.java @@ -0,0 +1,64 @@ +package com.baeldung.metrics; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.test.context.ActiveProfiles; + +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; + +@SpringBootTest( + classes = MetricsApplication.class, + webEnvironment = RANDOM_PORT, + properties = {"fixedDelay.in.milliseconds=2000"} +) +@ActiveProfiles("metrics") +class MetricsApplicationIntegrationTest { + + @Autowired + private TestRestTemplate restTemplate; + + @Test + void givenStatuses_WhenScheduledMethodExecuted_ExpectCountsAreAggregated() { + restTemplate.getForObject("/metrics/metric/notFound", String.class); + restTemplate.getForObject("/metrics/metric", String.class); + + await().untilAsserted(() -> { + Object[][] statusCounts = restTemplate.getForObject("/metrics/metric-graph-data", Object[][].class); + + assertThat(statusCounts[0]).contains("counter.status.200", "counter.status.404"); + + List requestCounts = getRequestCounts(statusCounts); + verify404RequestFrom(requestCounts); + verify200RequestsFrom(requestCounts); + }); + } + + private static void verify200RequestsFrom(List requestCounts) { + assertThat(requestCounts.size()).isGreaterThan(1); + } + + private static void verify404RequestFrom(List requestCounts) { + assertThat(requestCounts).contains(1); + } + + private static List getRequestCounts(Object[][] statusCounts) { + List requestCounts = new ArrayList<>(); + for (int i = 1; i < statusCounts.length; i++) { + for (int j = 1; j < statusCounts[i].length; j++) { + Integer count = (Integer) statusCounts[i][j]; + if (count >= 1) { + requestCounts.add(count); + } + } + } + return requestCounts; + } + +} diff --git a/spring-boot-modules/spring-boot-artifacts/pom.xml b/spring-boot-modules/spring-boot-artifacts/pom.xml index 6bf75491eb..0292dc95cf 100644 --- a/spring-boot-modules/spring-boot-artifacts/pom.xml +++ b/spring-boot-modules/spring-boot-artifacts/pom.xml @@ -101,7 +101,7 @@ maven-failsafe-plugin 2.18 - integration-tests @@ -110,7 +110,7 @@ verify - **/ExternalPropertyFileLoaderIntegrationTest.java @@ -186,7 +186,7 @@ - com.baeldung.boot.Application + com.baeldung.wrapper.DemoApplication 3.1.1 3.3.7-1 2.2 @@ -195,4 +195,4 @@ 4.5.8 - \ No newline at end of file + diff --git a/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoApplication.java b/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoApplication.java new file mode 100644 index 0000000000..d0a7e96bec --- /dev/null +++ b/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.wrapper; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = { "com.baeldung" }) +public class DemoApplication { + + public static void main(String[] args) { + SpringApplication.run(DemoApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoController.java b/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoController.java new file mode 100644 index 0000000000..530a1d584e --- /dev/null +++ b/spring-boot-modules/spring-boot-artifacts/src/main/java/com/baeldung/wrapper/DemoController.java @@ -0,0 +1,15 @@ +package com.baeldung.wrapper; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class DemoController { + + @GetMapping(value = "/demo") + public String demo(Model model) { + return "index"; + } + +} diff --git a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java index 21cb98710d..4119b624e1 100644 --- a/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java +++ b/spring-boot-modules/spring-boot-data-2/src/main/java/com/baeldung/boot/noconverterfound/controller/StudentRestController.java @@ -1,5 +1,6 @@ package com.baeldung.boot.noconverterfound.controller; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -18,4 +19,14 @@ public class StudentRestController { return ResponseEntity.ok(new Student(id, "John", "Wiliams", "AA")); } + @GetMapping(value = "/student/v2/{id}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity getV2(@PathVariable("id") int id) { + return ResponseEntity.ok(new Student(id, "Kevin", "Cruyff", "AA")); + } + + @GetMapping(value = "/student/v3/{id}", produces = MediaType.APPLICATION_XML_VALUE) + public ResponseEntity getV3(@PathVariable("id") int id) { + return ResponseEntity.ok(new Student(id, "Robert", "Miller", "BB")); + } + } diff --git a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java index f8ded91e65..6f89ef0e58 100644 --- a/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java +++ b/spring-boot-modules/spring-boot-data-2/src/test/java/com/baeldung/boot/noconverterfound/NoConverterFoundIntegrationTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,16 +26,16 @@ public class NoConverterFoundIntegrationTest { /* Remove Getters from Student class to successfully run this test case * @Test public void whenGettersNotDefined_thenThrowException() throws Exception { - + String url = "/api/student/1"; - + this.mockMvc.perform(get(url)) .andExpect(status().isInternalServerError()) .andExpect(result -> assertThat(result.getResolvedException()) .isInstanceOf(HttpMessageNotWritableException.class)) .andExpect(result -> assertThat(result.getResolvedException().getMessage()) .contains("No converter found for return value of type")); - + } */ @@ -44,9 +45,28 @@ public class NoConverterFoundIntegrationTest { String url = "/api/student/2"; this.mockMvc.perform(get(url)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.firstName").value("John")); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.firstName").value("John")); + } + @Test + public void whenJsonConverterIsFound_thenReturnResponse() throws Exception { + String url = "/api/student/v2/1"; + + this.mockMvc.perform(get(url)) + .andExpect(status().isOk()) + .andExpect(content().json("{'id':1,'firstName':'Kevin','lastName':'Cruyff', 'grade':'AA'}")); + } + + @Test + public void whenConverterNotFound_thenThrowException() throws Exception { + String url = "/api/student/v3/1"; + + this.mockMvc.perform(get(url)) + .andExpect(status().isInternalServerError()) + .andExpect(result -> assertThat(result.getResolvedException()).isInstanceOf(HttpMessageNotWritableException.class)) + .andExpect(result -> assertThat(result.getResolvedException() + .getMessage()).contains("No converter for [class com.baeldung.boot.noconverterfound.model.Student] with preset Content-Type")); } } diff --git a/spring-boot-modules/spring-boot-multiple-datasources/.gitignore b/spring-boot-modules/spring-boot-multiple-datasources/.gitignore new file mode 100644 index 0000000000..87a3fce287 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/.gitignore @@ -0,0 +1 @@ +.local-db diff --git a/spring-boot-modules/spring-boot-multiple-datasources/pom.xml b/spring-boot-modules/spring-boot-multiple-datasources/pom.xml new file mode 100644 index 0000000000..d66095bc2c --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + spring-boot-multiple-datasources + 0.1.0-SNAPSHOT + spring-boot-multiple-datasources + jar + Module For Spring Boot With Multiple Datasources + + + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT + ../pom.xml + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + provided + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 2.6.3 + + + diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/MultipleDatasourcesApplication.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/MultipleDatasourcesApplication.java new file mode 100644 index 0000000000..efdff387df --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/MultipleDatasourcesApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.datasources; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MultipleDatasourcesApplication { + + public static void main(String[] args) { + SpringApplication.run(MultipleDatasourcesApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/Todo.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/Todo.java new file mode 100644 index 0000000000..6f8557e258 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/Todo.java @@ -0,0 +1,48 @@ +package com.baeldung.spring.datasources.todos; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Todo { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String title; + private boolean completed; + + public Todo() { + } + + public Todo(String title) { + this.title = title; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isCompleted() { + return completed; + } + + public void setCompleted(boolean completed) { + this.completed = completed; + } + +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoDatasourceConfiguration.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoDatasourceConfiguration.java new file mode 100644 index 0000000000..3bfc8e2855 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoDatasourceConfiguration.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.datasources.todos; + +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import javax.sql.DataSource; + +@Configuration +public class TodoDatasourceConfiguration { + + @Bean + @ConfigurationProperties("spring.datasource.todos") + public DataSourceProperties todosDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + @Primary + public DataSource todosDataSource() { + return todosDataSourceProperties() + .initializeDataSourceBuilder() + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoJpaConfiguration.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoJpaConfiguration.java new file mode 100644 index 0000000000..655a3a55c2 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoJpaConfiguration.java @@ -0,0 +1,40 @@ +package com.baeldung.spring.datasources.todos; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Objects; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackageClasses = Todo.class, + entityManagerFactoryRef = "todosEntityManagerFactory", + transactionManagerRef = "todosTransactionManager" +) +public class TodoJpaConfiguration { + + @Bean + public LocalContainerEntityManagerFactoryBean todosEntityManagerFactory( + @Qualifier("todosDataSource") DataSource dataSource, + EntityManagerFactoryBuilder builder) { + return builder + .dataSource(dataSource) + .packages(Todo.class) + .build(); + } + + @Bean + public PlatformTransactionManager todosTransactionManager( + @Qualifier("todosEntityManagerFactory") LocalContainerEntityManagerFactoryBean todosEntityManagerFactory) { + return new JpaTransactionManager(Objects.requireNonNull(todosEntityManagerFactory.getObject())); + } +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoRepository.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoRepository.java new file mode 100644 index 0000000000..09fb8c6500 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/todos/TodoRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.spring.datasources.todos; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TodoRepository extends JpaRepository { +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/Topic.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/Topic.java new file mode 100644 index 0000000000..1d1f20f111 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/Topic.java @@ -0,0 +1,39 @@ +package com.baeldung.spring.datasources.topics; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Topic { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String title; + + public Topic() { + } + + public Topic(String title) { + this.title = title; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicDatasourceConfiguration.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicDatasourceConfiguration.java new file mode 100644 index 0000000000..a06983d681 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicDatasourceConfiguration.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.datasources.topics; + +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +@Configuration +public class TopicDatasourceConfiguration { + + @Bean + @ConfigurationProperties("spring.datasource.topics") + public DataSourceProperties topicsDataSourceProperties() { + return new DataSourceProperties(); + } + + @Bean + public DataSource topicsDataSource() { + return topicsDataSourceProperties() + .initializeDataSourceBuilder() + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicJpaConfiguration.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicJpaConfiguration.java new file mode 100644 index 0000000000..d800813b8c --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicJpaConfiguration.java @@ -0,0 +1,41 @@ +package com.baeldung.spring.datasources.topics; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.Objects; + +@Configuration +@EnableTransactionManagement +@EnableJpaRepositories( + basePackageClasses = Topic.class, + entityManagerFactoryRef = "topicsEntityManagerFactory", + transactionManagerRef = "topicsTransactionManager" +) +public class TopicJpaConfiguration { + + @Bean + public LocalContainerEntityManagerFactoryBean topicsEntityManagerFactory( + @Qualifier("topicsDataSource") DataSource dataSource, + EntityManagerFactoryBuilder builder + ) { + return builder + .dataSource(dataSource) + .packages(Topic.class) + .build(); + } + + @Bean + public PlatformTransactionManager topicsTransactionManager( + @Qualifier("topicsEntityManagerFactory") LocalContainerEntityManagerFactoryBean topicsEntityManagerFactory) { + return new JpaTransactionManager(Objects.requireNonNull(topicsEntityManagerFactory.getObject())); + } +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicRepository.java b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicRepository.java new file mode 100644 index 0000000000..499b72650a --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/java/com/baeldung/spring/datasources/topics/TopicRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.spring.datasources.topics; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TopicRepository extends JpaRepository { +} diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/main/resources/application.yml b/spring-boot-modules/spring-boot-multiple-datasources/src/main/resources/application.yml new file mode 100644 index 0000000000..4754acfc0f --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/main/resources/application.yml @@ -0,0 +1,23 @@ +spring: + datasource: + todos: + url: jdbc:h2:./.local-db/todos;DB_CLOSE_DELAY=-1;MODE=DB2;AUTO_SERVER=TRUE + username: sa + password: null + driverClassName: org.h2.Driver + topics: + url: jdbc:h2:./.local-db/topics;DB_CLOSE_DELAY=-1;MODE=DB2;AUTO_SERVER=TRUE + username: sa + password: null + driverClassName: org.h2.Driver + h2: + console: + enabled: true + path: /h2-console + jpa: + generate-ddl: true + hibernate: + ddl-auto: update + properties: + hibernate: + dialect: org.hibernate.dialect.H2Dialect diff --git a/spring-boot-modules/spring-boot-multiple-datasources/src/test/java/com/baeldung/spring/datasources/MultipleDatasourcesIntegrationTest.java b/spring-boot-modules/spring-boot-multiple-datasources/src/test/java/com/baeldung/spring/datasources/MultipleDatasourcesIntegrationTest.java new file mode 100644 index 0000000000..397992f6c8 --- /dev/null +++ b/spring-boot-modules/spring-boot-multiple-datasources/src/test/java/com/baeldung/spring/datasources/MultipleDatasourcesIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.spring.datasources; + +import com.baeldung.spring.datasources.todos.Todo; +import com.baeldung.spring.datasources.todos.TodoRepository; +import com.baeldung.spring.datasources.topics.Topic; +import com.baeldung.spring.datasources.topics.TopicRepository; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest // no test database! +class MultipleDatasourcesIntegrationTest { + + @Autowired + TodoRepository todoRepo; + @Autowired + TopicRepository topicRepo; + + @Test + void shouldSaveTodoToTodoDB() { + Todo todo = new Todo("test"); + Todo saved =todoRepo.save(todo); + Optional result= todoRepo.findById(saved.getId()); + assertThat(result).isPresent(); + } + + @Test + void shouldSaveTopicToTopicDB() { + Topic todo = new Topic("test"); + Topic saved =topicRepo.save(todo); + Optional result= topicRepo.findById(saved.getId()); + assertThat(result).isPresent(); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/README.md b/spring-boot-modules/spring-boot-swagger/README.md index ef33be8e07..174bfe626d 100644 --- a/spring-boot-modules/spring-boot-swagger/README.md +++ b/spring-boot-modules/spring-boot-swagger/README.md @@ -3,3 +3,5 @@ - [Hiding Endpoints From Swagger Documentation in Spring Boot](https://www.baeldung.com/spring-swagger-hiding-endpoints) - [Swagger @Api Description Is Deprecated](https://www.baeldung.com/java-swagger-api-description-deprecated) - [Generate PDF from Swagger API Documentation](https://www.baeldung.com/swagger-generate-pdf) +- [Remove Basic Error Controller In SpringFox Swagger-UI](https://www.baeldung.com/spring-swagger-remove-error-controller) +- [Setting Example and Description with Swagger](https://www.baeldung.com/swagger-set-example-description) diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java new file mode 100644 index 0000000000..1d2e129f26 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/SpringBootSwaggerConfApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.swaggerconf; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootSwaggerConfApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootSwaggerConfApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java new file mode 100644 index 0000000000..a78335a2fe --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/configuration/SwaggerConfiguration.java @@ -0,0 +1,37 @@ +package com.baeldung.swaggerconf.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.Collections; + +import static springfox.documentation.builders.PathSelectors.regex; + +@Configuration +@EnableSwagger2 +public class SwaggerConfiguration { + + private ApiInfo apiInfo() { + return new ApiInfo("My REST API", "Some custom description of API.", "API TOS", "Terms of service", + new Contact("General UserName", "www.baeldung.com", "user-name@gmail.com"), + "License of API", "API license URL", Collections.emptyList()); + } + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.baeldung.swaggerconf.controller")) + .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) + .paths(regex("/good-path/.*")) + .build(); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java new file mode 100644 index 0000000000..65059bf446 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForAnnotation.java @@ -0,0 +1,17 @@ +package com.baeldung.swaggerconf.controller; + +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; + +@Component +@RequestMapping("good-path/error-excluded-annotation") +public class ErrorControllerExcludedForAnnotation extends BasicErrorController { + + public ErrorControllerExcludedForAnnotation(ErrorAttributes errorAttributes, ServerProperties serverProperties) { + super(errorAttributes, serverProperties.getError()); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java new file mode 100644 index 0000000000..88208d8446 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForApiIgnore.java @@ -0,0 +1,21 @@ +package com.baeldung.swaggerconf.controller; + +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import springfox.documentation.annotations.ApiIgnore; + +@Component +@RequestMapping("good-path/error-excluded-apiignore") +@RestController +@ApiIgnore +public class ErrorControllerExcludedForApiIgnore extends BasicErrorController { + + public ErrorControllerExcludedForApiIgnore(ErrorAttributes errorAttributes, ServerProperties serverProperties) { + super(errorAttributes, serverProperties.getError()); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java new file mode 100644 index 0000000000..5cea4f5ef9 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/ErrorControllerExcludedForPath.java @@ -0,0 +1,19 @@ +package com.baeldung.swaggerconf.controller; + +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Component +@RequestMapping("wrong-path/error-excluded-path") +@RestController +public class ErrorControllerExcludedForPath extends BasicErrorController { + + public ErrorControllerExcludedForPath(ErrorAttributes errorAttributes, ServerProperties serverProperties) { + super(errorAttributes, serverProperties.getError()); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java new file mode 100644 index 0000000000..163826e626 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/controller/RegularRestController.java @@ -0,0 +1,33 @@ +package com.baeldung.swaggerconf.controller; + +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDate; +import java.time.LocalTime; + +@RestController +@RequestMapping("good-path") +public class RegularRestController { + + @ApiOperation(value = "This method is used to get the author name.") + @GetMapping("/getAuthor") + public String getAuthor() { + return "Name Surname"; + } + + @ApiOperation(value = "This method is used to get the current date.") + @GetMapping("/getDate") + public LocalDate getDate() { + return LocalDate.now(); + } + + @ApiOperation(value = "This method is used to get the current time.") + @GetMapping("/getTime") + public LocalTime getTime() { + return LocalTime.now(); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java new file mode 100644 index 0000000000..a3b5a3fe63 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerconf/excluded/ErrorControllerExcludedForPackage.java @@ -0,0 +1,17 @@ +package com.baeldung.swaggerconf.excluded; + +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.RequestMapping; + +@Component +@RequestMapping("good-path/error-excluded-package") +public class ErrorControllerExcludedForPackage extends BasicErrorController { + + public ErrorControllerExcludedForPackage(ErrorAttributes errorAttributes, ServerProperties serverProperties) { + super(errorAttributes, serverProperties.getError()); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/SwaggerExampleApplication.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/SwaggerExampleApplication.java new file mode 100644 index 0000000000..4859224bb2 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/SwaggerExampleApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.swaggerexample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SwaggerExampleApplication { + + public static void main(String[] args) { + SpringApplication.run(SwaggerExampleApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java new file mode 100644 index 0000000000..32dbe87bae --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/config/SwaggerConfig.java @@ -0,0 +1,38 @@ +package com.baeldung.swaggerexample.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.Collections; + +@Configuration +@EnableWebMvc +public class SwaggerConfig { + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.baeldung.swaggerexample")) + .paths(PathSelectors.any()) + .build(); + } + + private ApiInfo apiInfo() { + return new ApiInfo( + "Products API", + "API to let you add and view product", + "0.0.1", + "Terms of service", + new Contact("John Doe", "www.example.com", "myemail@company.com"), + "License of API", "API license URL", Collections.emptyList()); + } +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java new file mode 100644 index 0000000000..7500c01bc0 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/controller/ProductController.java @@ -0,0 +1,34 @@ +package com.baeldung.swaggerexample.controller; + +import com.baeldung.swaggerexample.entity.Product; +import io.swagger.annotations.*; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@ApiOperation("Products API") +public class ProductController { + + @ApiOperation(value = "Create a new product", notes = "Creates a new product as per the request body") + @ApiResponses(value = { + @ApiResponse(code = 201, message = "Successfully created"), + @ApiResponse(code = 400, message = "Bad request - The product is not valid"), + @ApiResponse(code = 500, message = "Internal server error - Something went wrong") + }) + @PostMapping(value = "/products") + public ResponseEntity createProduct(@RequestBody Product product) { + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @ApiOperation(value = "Get a product by id", notes = "Returns a product as per the id") + @ApiResponses(value = { + @ApiResponse(code = 200, message = "Successfully retrieved"), + @ApiResponse(code = 404, message = "Not found - The product was not found") + }) + @GetMapping("/products/{id}") + public ResponseEntity getProduct(@PathVariable("id") @ApiParam(name = "id", value = "Product id", example = "1") Long id) { + //retrieval logic + return ResponseEntity.ok(new Product(1, "Product 1", "$21.99")); + } +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java new file mode 100644 index 0000000000..122addadd5 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/main/java/com/baeldung/swaggerexample/entity/Product.java @@ -0,0 +1,46 @@ +package com.baeldung.swaggerexample.entity; + +import io.swagger.annotations.ApiModelProperty; + +import java.io.Serializable; + +public class Product implements Serializable { + @ApiModelProperty(notes = "Product ID", example = "1", required = true) + private Long id; + @ApiModelProperty(notes = "Product name", example = "Product 1", required = false) + private String name; + @ApiModelProperty(notes = "Product price", example = "$100.00", required = true) + private String price; + + // constructor and getter/setters + + public Product(long id, String name, String price) { + this.id = id; + this.name = name; + this.price = price; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } +} diff --git a/spring-boot-modules/spring-boot-swagger/src/main/resources/application.properties b/spring-boot-modules/spring-boot-swagger/src/main/resources/application.properties index e69de29bb2..a4e98652bc 100644 --- a/spring-boot-modules/spring-boot-swagger/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-swagger/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.mvc.pathmatch.matching-strategy = ANT_PATH_MATCHER \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-swagger/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java b/spring-boot-modules/spring-boot-swagger/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java new file mode 100644 index 0000000000..c0a5c54d69 --- /dev/null +++ b/spring-boot-modules/spring-boot-swagger/src/test/java/com/baeldung/swaggerconf/SwaggerConfExcludeErrorControllerIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.swaggerconf; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@AutoConfigureMockMvc +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class SwaggerConfExcludeErrorControllerIntegrationTest { + + @Autowired + private MockMvc mvc; + + @Test + public void whenCallingSwaggerJSON_stringObjectDoesNotContainAnyErrorControllers() throws Exception { + ResultActions resultActions = mvc.perform(get("/v2/api-docs")).andExpect(status().isOk()); + MvcResult result = resultActions.andReturn(); + String content = result.getResponse().getContentAsString(); + Assert.assertNotNull(content); + Assert.assertFalse(content.contains("error-controller")); + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml index 7dfb2c7436..bdd75d0635 100644 --- a/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml +++ b/spring-cloud/spring-cloud-archaius/zookeeper-config/pom.xml @@ -45,6 +45,7 @@ 2.0.0.RELEASE 3.4.13 + 2.17.1 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/README.md b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/README.md new file mode 100644 index 0000000000..91a0c5503b --- /dev/null +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Customizing Zuul Exceptions](https://www.baeldung.com/zuul-customize-exception) diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorApplication.java b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorApplication.java new file mode 100644 index 0000000000..ae8c3040ef --- /dev/null +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.cloud.zuul.filter; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; + +@EnableZuulProxy +@SpringBootApplication +public class CustomZuulErrorApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(CustomZuulErrorApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilter.java b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilter.java new file mode 100644 index 0000000000..d3e52843eb --- /dev/null +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilter.java @@ -0,0 +1,62 @@ +package com.baeldung.spring.cloud.zuul.filter; + +import java.net.ConnectException; +import java.time.Instant; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.exception.ZuulException; + +@Component +public class CustomZuulErrorFilter extends ZuulFilter { + + private static final Logger log = LoggerFactory.getLogger(CustomZuulErrorFilter.class); + + private static final String RESPONSE_BODY = "{\n" + " \"timestamp\": " + "\"" + Instant.now() + .toString() + "\"" + ",\n" + " \"status\": 503,\n" + " \"error\": \"Service Unavailable\"\n" + "}"; + + @Override + public Object run() { + RequestContext context = RequestContext.getCurrentContext(); + Throwable throwable = context.getThrowable(); + + if (throwable instanceof ZuulException) { + final ZuulException zuulException = (ZuulException) throwable; + log.error("Zuul exception: " + zuulException.getMessage()); + + if (throwable.getCause().getCause().getCause() instanceof ConnectException) { + + // reset throwable to prevent further error handling in follow up filters + context.remove("throwable"); + + // set custom response attributes + context.setResponseBody(RESPONSE_BODY); + context.getResponse() + .setContentType("application/json"); + context.setResponseStatusCode(503); + } + + } + return null; + } + + @Override + public boolean shouldFilter() { + return true; + } + + @Override + public int filterOrder() { + return -1; + } + + @Override + public String filterType() { + return "error"; + } + +} diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/ZuulConfiguration.java b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/ZuulConfiguration.java new file mode 100644 index 0000000000..3122862050 --- /dev/null +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/java/com/baeldung/spring/cloud/zuul/filter/ZuulConfiguration.java @@ -0,0 +1,98 @@ +package com.baeldung.spring.cloud.zuul.filter; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.cglib.proxy.Callback; +import org.springframework.cglib.proxy.CallbackFilter; +import org.springframework.cglib.proxy.Enhancer; +import org.springframework.cglib.proxy.MethodInterceptor; +import org.springframework.cglib.proxy.MethodProxy; +import org.springframework.cglib.proxy.NoOp; +import org.springframework.cloud.netflix.zuul.filters.RouteLocator; +import org.springframework.cloud.netflix.zuul.web.ZuulController; +import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Fix for Zuul configuration with Spring Boot 2.5.x + Zuul - "NoSuchMethodError: ErrorController.getErrorPath()": + */ +@Configuration +public class ZuulConfiguration { + /** + * The path returned by ErrorController.getErrorPath() with Spring Boot < 2.5 + * (and no longer available on Spring Boot >= 2.5). + */ + private static final String ERROR_PATH = "/error"; + private static final String METHOD = "lookupHandler"; + + /** + * Constructs a new bean post-processor for Zuul. + * + * @param routeLocator the route locator. + * @param zuulController the Zuul controller. + * @param errorController the error controller. + * @return the new bean post-processor. + */ + @Bean + public ZuulPostProcessor zuulPostProcessor(@Autowired RouteLocator routeLocator, @Autowired ZuulController zuulController, @Autowired(required = false) ErrorController errorController) { + return new ZuulPostProcessor(routeLocator, zuulController, errorController); + } + + private enum LookupHandlerCallbackFilter implements CallbackFilter { + INSTANCE; + + @Override + public int accept(Method method) { + if (METHOD.equals(method.getName())) { + return 0; + } + return 1; + } + } + + private enum LookupHandlerMethodInterceptor implements MethodInterceptor { + INSTANCE; + + @Override + public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { + if (ERROR_PATH.equals(args[0])) { + // by entering this branch we avoid the ZuulHandlerMapping.lookupHandler method to trigger the + // NoSuchMethodError + return null; + } + return methodProxy.invokeSuper(target, args); + } + } + + private static final class ZuulPostProcessor implements BeanPostProcessor { + + private final RouteLocator routeLocator; + private final ZuulController zuulController; + private final boolean hasErrorController; + + ZuulPostProcessor(RouteLocator routeLocator, ZuulController zuulController, ErrorController errorController) { + this.routeLocator = routeLocator; + this.zuulController = zuulController; + this.hasErrorController = (errorController != null); + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (hasErrorController && (bean instanceof ZuulHandlerMapping)) { + Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(ZuulHandlerMapping.class); + enhancer.setCallbackFilter(LookupHandlerCallbackFilter.INSTANCE); // only for lookupHandler + enhancer.setCallbacks(new Callback[] { LookupHandlerMethodInterceptor.INSTANCE, NoOp.INSTANCE }); + Constructor ctor = ZuulHandlerMapping.class.getConstructors()[0]; + return enhancer.create(ctor.getParameterTypes(), new Object[] { routeLocator, zuulController }); + } + return bean; + } + } +} \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/resources/application.yml b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/resources/application.yml index 855020a40e..bd517b8a6b 100644 --- a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/main/resources/application.yml @@ -1,5 +1,8 @@ zuul: + SendErrorFilter: + post: + disable: true routes: foos: path: /foos/** - url: http://localhost:8081/spring-zuul-foos-resource/foos + url: http://localhost:8081/spring-zuul-foos-resource/foos \ No newline at end of file diff --git a/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/test/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilterLiveTest.java b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/test/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilterLiveTest.java new file mode 100644 index 0000000000..da2588966d --- /dev/null +++ b/spring-cloud/spring-cloud-zuul/spring-zuul-ui/src/test/java/com/baeldung/spring/cloud/zuul/filter/CustomZuulErrorFilterLiveTest.java @@ -0,0 +1,24 @@ +package com.baeldung.spring.cloud.zuul.filter; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import io.restassured.RestAssured; +import io.restassured.response.Response; + +public class CustomZuulErrorFilterLiveTest { + + @Test + public void whenSendRequestWithoutService_thenCustomError() { + final Response response = RestAssured.get("http://localhost:8080/foos/1"); + assertEquals(503, response.getStatusCode()); + } + + @Test + public void whenSendRequestWithoutCustomErrorFilter_thenError() { + final Response response = RestAssured.get("http://localhost:8080/foos/1"); + assertEquals(500, response.getStatusCode()); + } + +} diff --git a/spring-security-modules/spring-security-web-login/README.md b/spring-security-modules/spring-security-web-login/README.md index 9521a430c2..8b9c1583f6 100644 --- a/spring-security-modules/spring-security-web-login/README.md +++ b/spring-security-modules/spring-security-web-login/README.md @@ -1,6 +1,6 @@ ## Spring Security Login -This module contains articles about login mechanisms with Spring Security +This module contains articles about login mechanisms with Spring Security. ### The Course The "Learn Spring Security" Classes: http://github.learnspringsecurity.com @@ -17,3 +17,12 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ``` mvn clean install ``` + +### Run the Project + +- Run the application using Maven Cargo plugin. +``` +mvn cargo:run +``` +- Go to the login page at http://localhost:8082/spring-security-web-login/login.html +- Login using ```user1/user1Pass``` details. \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-login/pom.xml b/spring-security-modules/spring-security-web-login/pom.xml index ac5393c1a0..3d9947c519 100644 --- a/spring-security-modules/spring-security-web-login/pom.xml +++ b/spring-security-modules/spring-security-web-login/pom.xml @@ -137,17 +137,9 @@ org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} + cargo-maven3-plugin + ${cargo-maven3-plugin.version} - true - - jetty8x - embedded - - - - 8082 @@ -160,7 +152,7 @@ - 1.6.1 + 1.9.9 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/AppInitializer.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/AppInitializer.java index 4f38d190eb..cbdf8dc684 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/AppInitializer.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/AppInitializer.java @@ -1,9 +1,5 @@ package com.baeldung; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; - import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; @@ -11,10 +7,13 @@ import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.servlet.DispatcherServlet; +import javax.servlet.ServletContext; +import javax.servlet.ServletRegistration; + public class AppInitializer implements WebApplicationInitializer { @Override - public void onStartup(final ServletContext sc) throws ServletException { + public void onStartup(final ServletContext sc) { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); @@ -24,7 +23,7 @@ public class AppInitializer implements WebApplicationInitializer { ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(new GenericWebApplicationContext())); appServlet.setLoadOnStartup(1); appServlet.addMapping("/"); - + sc.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain")) .addMappingForUrlPatterns(null, false, "/*"); diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAccessDeniedHandler.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAccessDeniedHandler.java index 9d9fa81dc0..39355202e3 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAccessDeniedHandler.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAccessDeniedHandler.java @@ -1,25 +1,22 @@ package com.baeldung.security; -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.access.AccessDeniedHandler; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + public class CustomAccessDeniedHandler implements AccessDeniedHandler { public static final Logger LOG = LoggerFactory.getLogger(CustomAccessDeniedHandler.class); @Override - public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException, ServletException { + public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException exc) throws IOException { Authentication auth = SecurityContextHolder.getContext() .getAuthentication(); if (auth != null) { diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAuthenticationFailureHandler.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAuthenticationFailureHandler.java index 410d3f1ce9..ce3f299dac 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAuthenticationFailureHandler.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomAuthenticationFailureHandler.java @@ -13,7 +13,7 @@ import java.util.Calendar; public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override - public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { + public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException { httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); String jsonPayload = "{\"message\" : \"%s\", \"timestamp\" : \"%s\" }"; diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomLogoutSuccessHandler.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomLogoutSuccessHandler.java index 7949eee69a..ee3bd62958 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomLogoutSuccessHandler.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/CustomLogoutSuccessHandler.java @@ -12,12 +12,6 @@ import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuc public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler implements LogoutSuccessHandler { - public CustomLogoutSuccessHandler() { - super(); - } - - // API - @Override public void onLogoutSuccess(final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication) throws IOException, ServletException { final String refererUrl = request.getHeader("Referer"); diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java index 15fa06aa3e..cfdaf7a13e 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/security/config/SecSecurityConfig.java @@ -23,10 +23,6 @@ import com.baeldung.security.CustomLogoutSuccessHandler; @Profile("!https") public class SecSecurityConfig extends WebSecurityConfigurerAdapter { - public SecSecurityConfig() { - super(); - } - @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off @@ -81,7 +77,7 @@ public class SecSecurityConfig extends WebSecurityConfigurerAdapter { public AuthenticationFailureHandler authenticationFailureHandler() { return new CustomAuthenticationFailureHandler(); } - + @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/ChannelSecSecurityConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/ChannelSecSecurityConfig.java index e9a6a9e120..151df18d11 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/ChannelSecSecurityConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/ChannelSecSecurityConfig.java @@ -17,10 +17,6 @@ import com.baeldung.security.CustomLogoutSuccessHandler; @Profile("https") public class ChannelSecSecurityConfig extends WebSecurityConfigurerAdapter { - public ChannelSecSecurityConfig() { - super(); - } - @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { // @formatter:off diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/MvcConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/MvcConfig.java index 082477c98c..7b27d637be 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/MvcConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/MvcConfig.java @@ -13,12 +13,6 @@ import org.springframework.web.servlet.view.JstlView; @Configuration public class MvcConfig implements WebMvcConfigurer { - public MvcConfig() { - super(); - } - - // API - @Override public void addViewControllers(final ViewControllerRegistry registry) { diff --git a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/RedirectionSecurityConfig.java b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/RedirectionSecurityConfig.java index 3516438a6e..b27d999d56 100644 --- a/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/RedirectionSecurityConfig.java +++ b/spring-security-modules/spring-security-web-login/src/main/java/com/baeldung/spring/RedirectionSecurityConfig.java @@ -11,10 +11,6 @@ import org.springframework.security.web.authentication.SavedRequestAwareAuthenti //@Profile("!https") public class RedirectionSecurityConfig extends WebSecurityConfigurerAdapter { - public RedirectionSecurityConfig() { - super(); - } - @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfCookieEnabledIntegrationTest.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfCookieEnabledIntegrationTest.java new file mode 100644 index 0000000000..73f83f9b0c --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfCookieEnabledIntegrationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.security.csrf; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.baeldung.security.spring.SecurityWithCsrfCookieConfig; +import com.baeldung.spring.MvcConfig; +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.context.ContextConfiguration; + +@ContextConfiguration(classes = { SecurityWithCsrfCookieConfig.class, MvcConfig.class }) +public class CsrfCookieEnabledIntegrationTest extends CsrfAbstractIntegrationTest { + + @Test + public void givenNoCsrf_whenAddFoo_thenForbidden() throws Exception { + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo()) + .with(testUser())) + .andExpect(status().isForbidden()); + // @formatter:on + } + + @Test + public void givenCsrf_whenAddFoo_thenCreated() throws Exception { + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo()) + .with(testUser()) + .with(csrf())) + .andExpect(status().isCreated()); + // @formatter:on + } + +} diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfDisabledIntegrationTest.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfDisabledIntegrationTest.java index a1c8be9daf..6dc01ab2bd 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfDisabledIntegrationTest.java +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfDisabledIntegrationTest.java @@ -14,12 +14,25 @@ public class CsrfDisabledIntegrationTest extends CsrfAbstractIntegrationTest { @Test public void givenNotAuth_whenAddFoo_thenUnauthorized() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo())).andExpect(status().isUnauthorized()); + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo())) + .andExpect(status().isUnauthorized()); + // @formatter:on } @Test public void givenAuth_whenAddFoo_thenCreated() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isCreated()); + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo()) + .with(testUser())) + .andExpect(status().isCreated()); + // @formatter:on } } diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfEnabledIntegrationTest.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfEnabledIntegrationTest.java index 87e5005e17..50af9bba6f 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfEnabledIntegrationTest.java +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/csrf/CsrfEnabledIntegrationTest.java @@ -15,12 +15,27 @@ public class CsrfEnabledIntegrationTest extends CsrfAbstractIntegrationTest { @Test public void givenNoCsrf_whenAddFoo_thenForbidden() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser())).andExpect(status().isForbidden()); + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo()) + .with(testUser())) + .andExpect(status().isForbidden()); + // @formatter:on } @Test public void givenCsrf_whenAddFoo_thenCreated() throws Exception { - mvc.perform(post("/auth/foos").contentType(MediaType.APPLICATION_JSON).content(createFoo()).with(testUser()).with(csrf())).andExpect(status().isCreated()); + // @formatter:off + mvc + .perform(post("/auth/foos") + .contentType(MediaType.APPLICATION_JSON) + .content(createFoo()) + .with(testUser()) + .with(csrf())) + .andExpect(status().isCreated()); + // @formatter:on } } diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfConfig.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfConfig.java index 9b3ac50546..4ec7a50abc 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfConfig.java +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfConfig.java @@ -27,7 +27,17 @@ public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN"); + // @formatter:off + auth + .inMemoryAuthentication() + .withUser("user1") + .password("user1Pass") + .authorities("ROLE_USER") + .and() + .withUser("admin") + .password("adminPass") + .authorities("ROLE_ADMIN"); + // @formatter:on } @Override @@ -45,8 +55,7 @@ public class SecurityWithCsrfConfig extends WebSecurityConfigurerAdapter { .and() .httpBasic() .and() - .headers().cacheControl().disable() - ; + .headers().cacheControl().disable(); // @formatter:on } diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfCookieConfig.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfCookieConfig.java new file mode 100644 index 0000000000..5b58349629 --- /dev/null +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithCsrfCookieConfig.java @@ -0,0 +1,67 @@ +package com.baeldung.security.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityWithCsrfCookieConfig extends WebSecurityConfigurerAdapter { + + public SecurityWithCsrfCookieConfig() { + super(); + } + + @Bean("authenticationManager") + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off + auth + .inMemoryAuthentication() + .withUser("user1") + .password("user1Pass") + .authorities("ROLE_USER") + .and() + .withUser("admin") + .password("adminPass") + .authorities("ROLE_ADMIN"); + // @formatter:on + } + + @Override + public void configure(final WebSecurity web) throws Exception { + web.ignoring().antMatchers("/resources/**"); + } + + @Override + protected void configure(final HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .antMatchers("/auth/admin/*").hasAnyRole("ROLE_ADMIN") + .anyRequest().authenticated() + .and() + .httpBasic() + .and() + .headers().cacheControl().disable() + // Stateless API CSRF configuration + .and() + .csrf() + .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); + // @formatter:on + } + +} diff --git a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithoutCsrfConfig.java b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithoutCsrfConfig.java index 4a1263b498..bd9ca67ad5 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithoutCsrfConfig.java +++ b/spring-security-modules/spring-security-web-mvc-custom/src/test/java/com/baeldung/security/spring/SecurityWithoutCsrfConfig.java @@ -27,7 +27,17 @@ public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(final AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user1").password("user1Pass").authorities("ROLE_USER").and().withUser("admin").password("adminPass").authorities("ROLE_ADMIN"); + // @formatter:off + auth + .inMemoryAuthentication() + .withUser("user1") + .password("user1Pass") + .authorities("ROLE_USER") + .and() + .withUser("admin") + .password("adminPass") + .authorities("ROLE_ADMIN"); + // @formatter:on } @Override @@ -47,8 +57,7 @@ public class SecurityWithoutCsrfConfig extends WebSecurityConfigurerAdapter { .and() .headers().cacheControl().disable() .and() - .csrf().disable() - ; + .csrf().disable(); // @formatter:on } diff --git a/spring-sleuth/README.md b/spring-sleuth/README.md index ebaebde6c9..0740b0f6a6 100644 --- a/spring-sleuth/README.md +++ b/spring-sleuth/README.md @@ -5,3 +5,4 @@ This module contains articles about Spring Cloud Sleuth ### Relevant articles: - [Spring Cloud Sleuth in a Monolith Application](https://www.baeldung.com/spring-cloud-sleuth-single-application) +- [Get Current Trace ID in Spring Cloud Sleuth](https://www.baeldung.com/spring-cloud-sleuth-get-trace-id) diff --git a/spring-web-modules/spring-rest-testing/README.md b/spring-web-modules/spring-rest-testing/README.md index 2a77b5dded..806e67b7ec 100644 --- a/spring-web-modules/spring-rest-testing/README.md +++ b/spring-web-modules/spring-rest-testing/README.md @@ -11,7 +11,6 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Integration Testing with the Maven Cargo plugin](https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) -- [Metrics for your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) - [Testing Exceptions with Spring MockMvc](https://www.baeldung.com/spring-mvc-test-exceptions) ### Build the Project diff --git a/spring-web-modules/spring-rest-testing/pom.xml b/spring-web-modules/spring-rest-testing/pom.xml index 52c1f6418e..1390898bf9 100644 --- a/spring-web-modules/spring-rest-testing/pom.xml +++ b/spring-web-modules/spring-rest-testing/pom.xml @@ -21,19 +21,10 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.boot - spring-boot-starter-actuator - org.aspectj aspectjweaver - - org.apache.tomcat.embed - tomcat-embed-jasper - provided - org.springframework @@ -69,14 +60,6 @@ org.springframework spring-expression - - org.springframework - spring-web - - - org.springframework - spring-webmvc - org.springframework.data spring-data-commons @@ -137,17 +120,6 @@ net.bytebuddy byte-buddy - - - javax.servlet - javax.servlet-api - provided - - - javax.servlet - jstl - runtime - com.fasterxml.jackson.core diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java index c35c4d7e5e..78c9b88ddb 100644 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java +++ b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/spring/Application.java @@ -1,38 +1,19 @@ package com.baeldung.spring; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; - import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.web.context.request.RequestContextListener; /** * Main Application Class - uses Spring Boot. Just run this as a normal Java * class to run up a Jetty Server (on http://localhost:8082/spring-rest-full) * */ -@EnableScheduling @EnableAutoConfiguration @ComponentScan("com.baeldung") @SpringBootApplication -public class Application extends SpringBootServletInitializer { - - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(Application.class); - } - - @Override - public void onStartup(ServletContext sc) throws ServletException { - // Manages the lifecycle of the root application context - sc.addListener(new RequestContextListener()); - } +public class Application { public static void main(final String[] args) { SpringApplication.run(Application.class, args); diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java deleted file mode 100644 index 005f6f023b..0000000000 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/controller/RootController.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.baeldung.web.controller; - -import java.util.Map; - -import com.baeldung.web.metric.IActuatorMetricService; -import com.baeldung.web.metric.IMetricService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -@Controller -@RequestMapping(value = "/auth/") -public class RootController { - - @Autowired - private IMetricService metricService; - - @Autowired - private IActuatorMetricService actMetricService; - - public RootController() { - super(); - } - - // API - - @RequestMapping(value = "/metric", method = RequestMethod.GET) - @ResponseBody - public Map getMetric() { - return metricService.getFullMetric(); - } - - @RequestMapping(value = "/status-metric", method = RequestMethod.GET) - @ResponseBody - public Map getStatusMetric() { - return metricService.getStatusMetric(); - } - - @RequestMapping(value = "/metric-graph", method = RequestMethod.GET) - @ResponseBody - public Object[][] drawMetric() { - final Object[][] result = metricService.getGraphData(); - for (int i = 1; i < result[0].length; i++) { - result[0][i] = result[0][i].toString(); - } - return result; - } - - -} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java deleted file mode 100644 index 60bb43ee00..0000000000 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IActuatorMetricService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.web.metric; - -public interface IActuatorMetricService { - Object[][] getGraphData(); -} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java deleted file mode 100644 index 5126252e27..0000000000 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/ICustomActuatorMetricService.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.baeldung.web.metric; - -public interface ICustomActuatorMetricService { - - void increaseCount(final int status); - - Object[][] getGraphData(); -} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java deleted file mode 100644 index b8dfa60215..0000000000 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/IMetricService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.web.metric; - -import java.util.Map; - -public interface IMetricService { - - void increaseCount(final String request, final int status); - - Map getFullMetric(); - - Map getStatusMetric(); - - Object[][] getGraphData(); -} diff --git a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java b/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java deleted file mode 100644 index fd3cccab3e..0000000000 --- a/spring-web-modules/spring-rest-testing/src/main/java/com/baeldung/web/metric/MetricService.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.baeldung.web.metric; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.springframework.stereotype.Service; - -@Service -public class MetricService implements IMetricService { - - private ConcurrentMap> metricMap; - private ConcurrentMap statusMetric; - private ConcurrentMap> timeMap; - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - - public MetricService() { - super(); - metricMap = new ConcurrentHashMap>(); - statusMetric = new ConcurrentHashMap(); - timeMap = new ConcurrentHashMap>(); - } - - // API - - @Override - public void increaseCount(final String request, final int status) { - increaseMainMetric(request, status); - increaseStatusMetric(status); - updateTimeMap(status); - } - - @Override - public Map getFullMetric() { - return metricMap; - } - - @Override - public Map getStatusMetric() { - return statusMetric; - } - - @Override - public Object[][] getGraphData() { - final int colCount = statusMetric.keySet().size() + 1; - final Set allStatus = statusMetric.keySet(); - final int rowCount = timeMap.keySet().size() + 1; - - final Object[][] result = new Object[rowCount][colCount]; - result[0][0] = "Time"; - - int j = 1; - for (final int status : allStatus) { - result[0][j] = status; - j++; - } - int i = 1; - ConcurrentMap tempMap; - for (final Entry> entry : timeMap.entrySet()) { - result[i][0] = entry.getKey(); - tempMap = entry.getValue(); - for (j = 1; j < colCount; j++) { - result[i][j] = tempMap.get(result[0][j]); - if (result[i][j] == null) { - result[i][j] = 0; - } - } - i++; - } - - return result; - } - - // NON-API - - private void increaseMainMetric(final String request, final int status) { - ConcurrentHashMap statusMap = metricMap.get(request); - if (statusMap == null) { - statusMap = new ConcurrentHashMap(); - } - - Integer count = statusMap.get(status); - if (count == null) { - count = 1; - } else { - count++; - } - statusMap.put(status, count); - metricMap.put(request, statusMap); - } - - private void increaseStatusMetric(final int status) { - final Integer statusCount = statusMetric.get(status); - if (statusCount == null) { - statusMetric.put(status, 1); - } else { - statusMetric.put(status, statusCount + 1); - } - } - - private void updateTimeMap(final int status) { - final String time = dateFormat.format(new Date()); - ConcurrentHashMap statusMap = timeMap.get(time); - if (statusMap == null) { - statusMap = new ConcurrentHashMap(); - } - - Integer count = statusMap.get(status); - if (count == null) { - count = 1; - } else { - count++; - } - statusMap.put(status, count); - timeMap.put(time, statusMap); - } - -} diff --git a/spring-web-modules/spring-rest-testing/src/main/resources/application.properties b/spring-web-modules/spring-rest-testing/src/main/resources/application.properties index 52d93b4cff..cb9d72e41f 100644 --- a/spring-web-modules/spring-rest-testing/src/main/resources/application.properties +++ b/spring-web-modules/spring-rest-testing/src/main/resources/application.properties @@ -1,3 +1,2 @@ server.port=8082 server.servlet.context-path=/spring-rest-full -endpoints.metrics.enabled=true \ No newline at end of file diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 69382e5546..f794c3990f 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -134,7 +134,7 @@ - 2.8.2 + 2.17.1 2.0.9 5.0.1.RELEASE 3.0.0-M3 diff --git a/testing-modules/junit5-annotations/pom.xml b/testing-modules/junit5-annotations/pom.xml index fad5402242..a4035a23f1 100644 --- a/testing-modules/junit5-annotations/pom.xml +++ b/testing-modules/junit5-annotations/pom.xml @@ -39,7 +39,7 @@ - 2.8.2 + 2.17.1 \ No newline at end of file diff --git a/testing-modules/test-containers/pom.xml b/testing-modules/test-containers/pom.xml index 3975b6df31..bd20035eab 100644 --- a/testing-modules/test-containers/pom.xml +++ b/testing-modules/test-containers/pom.xml @@ -70,7 +70,7 @@ 1.5.0 - 2.12.0 + 2.17.1 1.11.4 42.2.6 3.141.59