From 33b60605d778d35ae48d0a177be3862e5d377393 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Thu, 7 Mar 2019 23:44:32 +1100 Subject: [PATCH 01/63] BAEL-2569 : EnvironmentPostProcessor in Spring Boot --- .../PriceCalculationApplication.java | 59 +++++++++++++++ ...ceCalculationEnvironmentPostProcessor.java | 71 +++++++++++++++++++ .../PriceCalculationAutoConfig.java | 32 +++++++++ .../calculator/GrossPriceCalculator.java | 23 ++++++ .../calculator/NetPriceCalculator.java | 17 +++++ .../calculator/PriceCalculator.java | 5 ++ .../service/PriceCalculationService.java | 17 +++++ .../main/resources/META-INF/spring.factories | 8 ++- 8 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java new file mode 100644 index 0000000000..01be08d6ae --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java @@ -0,0 +1,59 @@ +package com.baeldung.environmentpostprocessor; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.baeldung.environmentpostprocessor.service.PriceCalculationService; + +@SpringBootApplication +public class PriceCalculationApplication implements CommandLineRunner { + + @Autowired + PriceCalculationService priceCalculationService; + + private static final Logger logger = LoggerFactory.getLogger(PriceCalculationApplication.class); + + public static void main(String[] args) { + SpringApplication.run(PriceCalculationApplication.class, args); + } + + @Override + public void run(String... args) throws Exception { + + List params = Arrays.stream(args) + .collect(Collectors.toList()); + if (verifyArguments(params)) { + double singlePrice = Double.valueOf(params.get(0)); + int quantity = Integer.valueOf(params.get(1)); + priceCalculationService.productTotalPrice(singlePrice, quantity); + } else { + logger.error("Invalid arguments " + params.toString()); + } + + } + + private boolean verifyArguments(List args) { + boolean successful = true; + if (args.size() != 2) { + successful = false; + return successful; + } + try { + double singlePrice = Double.valueOf(args.get(0)); + int quantity = Integer.valueOf(args.get(1)); + } catch (NumberFormatException e) { + successful = false; + } + return successful; + + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java new file mode 100644 index 0000000000..1b3099453e --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -0,0 +1,71 @@ +package com.baeldung.environmentpostprocessor; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.env.StandardEnvironment; + +public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { + + private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); + + public static final int DEFAULT_ORDER = Ordered.LOWEST_PRECEDENCE; + private int order = DEFAULT_ORDER; + private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; + private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; + private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; + private static final String OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE = "NET"; + private static final double OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + + PropertySource systemEnvironmentPropertySource = environment.getPropertySources() + .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); + + Map priceCalculationConfiguration = new LinkedHashMap<>(); + if (isActive(systemEnvironmentPropertySource)) { + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + } else { + logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, + OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } + + PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", priceCalculationConfiguration); + environment.getPropertySources() + .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); + + } + + private String key(String key) { + return PROPERTY_PREFIX + key.replaceAll("\\_", "."); + } + + private boolean isActive(PropertySource systemEnvpropertySource) { + if (systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_CALCUATION_MODE) && systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)) { + return true; + } else + return false; + } + + public void setOrder(int order) { + this.order = order; + } + + @Override + public int getOrder() { + return order; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java new file mode 100644 index 0000000000..c884f043a0 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java @@ -0,0 +1,32 @@ +package com.baeldung.environmentpostprocessor.autoconfig; + +import org.springframework.boot.autoconfigure.AutoConfigureOrder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; + +import com.baeldung.environmentpostprocessor.calculator.GrossPriceCalculator; +import com.baeldung.environmentpostprocessor.calculator.NetPriceCalculator; +import com.baeldung.environmentpostprocessor.calculator.PriceCalculator; + +@Configuration +@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) +public class PriceCalculationAutoConfig { + + @Bean + @ConditionalOnProperty(name = "com.baeldung.environmentpostprocessor.calculation.mode", havingValue = "NET") + @ConditionalOnMissingBean + public PriceCalculator getNetPriceCalculator() { + return new NetPriceCalculator(); + } + + @Bean + @ConditionalOnProperty(name = "com.baeldung.environmentpostprocessor.calculation.mode", havingValue = "GROSS") + @ConditionalOnMissingBean + public PriceCalculator getGrossPriceCalculator() { + return new GrossPriceCalculator(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java new file mode 100644 index 0000000000..f8f797bd66 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java @@ -0,0 +1,23 @@ +package com.baeldung.environmentpostprocessor.calculator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + +public class GrossPriceCalculator implements PriceCalculator { + + private static final Logger logger = LoggerFactory.getLogger(GrossPriceCalculator.class); + + @Value("${com.baeldung.environmentpostprocessor.gross.calculation.tax.rate}") + double taxRate; + + @Override + public double calculate(double singlePrice, int quantity) { + logger.info("Gross based price calculation with input parameters [singlePrice = {},quantity= {} ], {} percent tax applied.", singlePrice, quantity, taxRate * 100); + double netPrice = singlePrice * quantity; + double result = Math.round(netPrice * (1 + taxRate)); + logger.info("Calcuation result is {}", result); + return result; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java new file mode 100644 index 0000000000..263dff6247 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java @@ -0,0 +1,17 @@ +package com.baeldung.environmentpostprocessor.calculator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetPriceCalculator implements PriceCalculator { + + private static final Logger logger = LoggerFactory.getLogger(GrossPriceCalculator.class); + + @Override + public double calculate(double singlePrice, int quantity) { + logger.info("Net based price calculation with input parameters [singlePrice = {},quantity= {} ], NO tax applied.", singlePrice, quantity); + double result = Math.round(singlePrice * quantity); + logger.info("Calcuation result is {}", result); + return result; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java new file mode 100644 index 0000000000..9d7bef93a4 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java @@ -0,0 +1,5 @@ +package com.baeldung.environmentpostprocessor.calculator; + +public interface PriceCalculator { + public double calculate(double singlePrice, int quantity); +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java new file mode 100644 index 0000000000..0e4eb39506 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java @@ -0,0 +1,17 @@ +package com.baeldung.environmentpostprocessor.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.environmentpostprocessor.calculator.PriceCalculator; + +@Service +public class PriceCalculationService { + + @Autowired + PriceCalculator priceCalculator; + + public double productTotalPrice(double singlePrice, int quantity) { + return priceCalculator.calculate(singlePrice, quantity); + } +} diff --git a/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot/src/main/resources/META-INF/spring.factories index e3d3aa4c8e..d8a01bbf82 100644 --- a/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot/src/main/resources/META-INF/spring.factories @@ -1 +1,7 @@ -org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer \ No newline at end of file +org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig + +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + From bbb98f7a91a91336fb47ae71651400b2b8516bab Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Mon, 11 Mar 2019 23:49:35 +1100 Subject: [PATCH 02/63] BAEL-2569 add test --- ...ationEnvironmentPostProcessorLiveTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java new file mode 100644 index 0000000000..352e7941fb --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java @@ -0,0 +1,29 @@ +package com.baeldung.environmentpostprocessor; + +import static org.junit.Assert.assertTrue; + +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.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.environmentpostprocessor.service.PriceCalculationService; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PriceCalculationApplication.class) +public class PriceCalculationEnvironmentPostProcessorLiveTest { + + @Autowired + PriceCalculationService pcService; + + + @Test + public void WhenSetGrossEnvironmentVariable_ThenTaxApplied() { + double total = pcService.productTotalPrice(100, 4); + + Assert.assertEquals(400.0,total); + } + +} From a0227300bf92b3609a554916c8f70aa710d09900 Mon Sep 17 00:00:00 2001 From: "Matt Zhang (EXT)" Date: Wed, 13 Mar 2019 11:56:26 +1100 Subject: [PATCH 03/63] BAEL-2569 update test --- ...CalculationEnvironmentPostProcessorLiveTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java index 352e7941fb..54af217346 100644 --- a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java +++ b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java @@ -1,8 +1,7 @@ package com.baeldung.environmentpostprocessor; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,16 +13,14 @@ import com.baeldung.environmentpostprocessor.service.PriceCalculationService; @RunWith(SpringRunner.class) @SpringBootTest(classes = PriceCalculationApplication.class) public class PriceCalculationEnvironmentPostProcessorLiveTest { - + @Autowired PriceCalculationService pcService; - - + @Test - public void WhenSetGrossEnvironmentVariable_ThenTaxApplied() { + public void whenSetNetEnvironmentVariablebyDefault_thenNoTaxApplied() { double total = pcService.productTotalPrice(100, 4); - - Assert.assertEquals(400.0,total); + assertEquals(400.0, total, 0); } } From 9f8058a5603ced4177f5bc42ca7b8dbd408a5953 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Fri, 29 Mar 2019 23:46:43 +1100 Subject: [PATCH 04/63] BAEL-2569 refactoring the class PriceCalculationEnvironmentPostProcessor --- ...ceCalculationEnvironmentPostProcessor.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java index 1b3099453e..42cbd1e90f 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -8,17 +8,17 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; -public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { +@Order(Ordered.LOWEST_PRECEDENCE) +public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor { private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); - public static final int DEFAULT_ORDER = Ordered.LOWEST_PRECEDENCE; - private int order = DEFAULT_ORDER; private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; @@ -28,26 +28,34 @@ public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPost @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - PropertySource systemEnvironmentPropertySource = environment.getPropertySources() + PropertySource systemEnvPropertySource = environment.getPropertySources() .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); - Map priceCalculationConfiguration = new LinkedHashMap<>(); - if (isActive(systemEnvironmentPropertySource)) { - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + Map mapPropertySource = new LinkedHashMap<>(); + if (isActive(systemEnvPropertySource)) { + populatePropertySource(systemEnvPropertySource, mapPropertySource); } else { logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + populateDefaultPropertySource(mapPropertySource); } - PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", priceCalculationConfiguration); + PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", mapPropertySource); environment.getPropertySources() .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); } + private void populatePropertySource(PropertySource source, Map target) { + target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), source.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); + target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), source.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + } + + private void populateDefaultPropertySource(Map target) { + target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); + target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } + private String key(String key) { return PROPERTY_PREFIX + key.replaceAll("\\_", "."); } @@ -59,13 +67,4 @@ public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPost return false; } - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return order; - } - } From 99a3aa5bab5e066bd8470ac2619160aaab19e788 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 31 Mar 2019 22:42:32 +1100 Subject: [PATCH 05/63] BAEL-2569: changes to class PriceCalculationEnvironmentPostProcessor --- ...ceCalculationEnvironmentPostProcessor.java | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java index 42cbd1e90f..ca6d6cc28f 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -1,7 +1,12 @@ package com.baeldung.environmentpostprocessor; +import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME; + +import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,56 +17,62 @@ import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; @Order(Ordered.LOWEST_PRECEDENCE) public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor { private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); - private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; - private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; - private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; - private static final String OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE = "NET"; - private static final double OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + private static final String PREFIX = "com.baeldung.environmentpostprocessor."; + private static final String CALCUATION_MODE = "calculation_mode"; + private static final String GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; + private static final String CALCUATION_MODE_DEFAULT_VALUE = "NET"; + private static final double GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + + List names = Arrays.asList(CALCUATION_MODE, GROSS_CALCULATION_TAX_RATE); + + private static Map defaults = new LinkedHashMap<>(); + static { + defaults.put(CALCUATION_MODE, CALCUATION_MODE_DEFAULT_VALUE); + defaults.put(GROSS_CALCULATION_TAX_RATE, GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - PropertySource systemEnvPropertySource = environment.getPropertySources() - .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); + PropertySource system = environment.getPropertySources() + .get(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); - Map mapPropertySource = new LinkedHashMap<>(); - if (isActive(systemEnvPropertySource)) { - populatePropertySource(systemEnvPropertySource, mapPropertySource); - } else { - logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, - OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); - populateDefaultPropertySource(mapPropertySource); + Map prefixed = new LinkedHashMap<>(); + + if (!hasOurPriceProperties(system)) { + // Baeldung-internal code so this doesn't break other examples + logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", CALCUATION_MODE_DEFAULT_VALUE, + GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + prefixed = names.stream() + .collect(Collectors.toMap(this::rename, this::getDefaultValue)); + environment.getPropertySources() + .addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("prefixer", prefixed)); + return; } - PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", mapPropertySource); + prefixed = names.stream() + .collect(Collectors.toMap(this::rename, system::getProperty)); environment.getPropertySources() - .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); + .addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("prefixer", prefixed)); } - private void populatePropertySource(PropertySource source, Map target) { - target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), source.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); - target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), source.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + private Object getDefaultValue(String key) { + return defaults.get(key); } - private void populateDefaultPropertySource(Map target) { - target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); - target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + private String rename(String key) { + return PREFIX + key.replaceAll("\\_", "."); } - private String key(String key) { - return PROPERTY_PREFIX + key.replaceAll("\\_", "."); - } - - private boolean isActive(PropertySource systemEnvpropertySource) { - if (systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_CALCUATION_MODE) && systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)) { + private boolean hasOurPriceProperties(PropertySource system) { + if (system.containsProperty(CALCUATION_MODE) && system.containsProperty(GROSS_CALCULATION_TAX_RATE)) { return true; } else return false; From f5ac80e332dca0488c81bf7ee86fce2114aaa068 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 7 Apr 2019 22:42:15 +1000 Subject: [PATCH 06/63] BAEL-2569 move code to spring-boot-ops module --- .../PriceCalculationApplication.java | 2 +- .../PriceCalculationEnvironmentPostProcessor.java | 0 .../autoconfig/PriceCalculationAutoConfig.java | 0 .../calculator/GrossPriceCalculator.java | 0 .../calculator/NetPriceCalculator.java | 0 .../calculator/PriceCalculator.java | 0 .../service/PriceCalculationService.java | 0 .../src/main/resources/META-INF/spring.factories | 6 ++++++ .../PriceCalculationEnvironmentPostProcessorLiveTest.java | 0 spring-boot/src/main/resources/META-INF/spring.factories | 5 ----- 10 files changed, 7 insertions(+), 6 deletions(-) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java (96%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java (100%) create mode 100644 spring-boot-ops/src/main/resources/META-INF/spring.factories rename {spring-boot => spring-boot-ops}/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java (100%) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java similarity index 96% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java index 01be08d6ae..ed912d8c0a 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java +++ b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java @@ -35,7 +35,7 @@ public class PriceCalculationApplication implements CommandLineRunner { int quantity = Integer.valueOf(params.get(1)); priceCalculationService.productTotalPrice(singlePrice, quantity); } else { - logger.error("Invalid arguments " + params.toString()); + logger.warn("Invalid arguments " + params.toString()); } } diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java diff --git a/spring-boot-ops/src/main/resources/META-INF/spring.factories b/spring-boot-ops/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..c36b67f8d7 --- /dev/null +++ b/spring-boot-ops/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig + +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot-ops/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java similarity index 100% rename from spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java rename to spring-boot-ops/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java diff --git a/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot/src/main/resources/META-INF/spring.factories index d8a01bbf82..336477df96 100644 --- a/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot/src/main/resources/META-INF/spring.factories @@ -1,7 +1,2 @@ org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig - -org.springframework.boot.env.EnvironmentPostProcessor=\ -com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor From 608db42334c844b1b503bde30d9423423ec840b2 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sat, 18 May 2019 19:24:25 +1000 Subject: [PATCH 07/63] BAEL-2878 Guide to Spring's ApplicationContextRunner --- .../service/CustomService.java | 10 +++ .../service/DefaultService.java | 10 +++ .../service/SimpleService.java | 7 ++ .../ConditionalOnBeanTest.java | 77 +++++++++++++++++++ .../ConditionalOnClassTest.java | 76 ++++++++++++++++++ .../ConditionalOnPropertyTest.java | 64 +++++++++++++++ .../ConditionalOnPropertyTest.properties | 1 + 7 files changed, 245 insertions(+) create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java create mode 100644 spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java new file mode 100644 index 0000000000..634e49fed3 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java @@ -0,0 +1,10 @@ +package com.baeldung.autoconfiguration.service; + +public class CustomService implements SimpleService { + + @Override + public String serve() { + return "Custom Service"; + } + +} diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java new file mode 100644 index 0000000000..ee91bcb051 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java @@ -0,0 +1,10 @@ +package com.baeldung.autoconfiguration.service; + +public class DefaultService implements SimpleService { + + @Override + public String serve() { + return "Default Service"; + } + +} diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java new file mode 100644 index 0000000000..b6c72d7159 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java @@ -0,0 +1,7 @@ +package com.baeldung.autoconfiguration.service; + +public interface SimpleService { + + public String serve(); + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java new file mode 100644 index 0000000000..313d1253c5 --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java @@ -0,0 +1,77 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class ConditionalOnBeanTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenDependentBeanIsPresent_thenConditionalBeanCreated() { + this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("created"); + assertThat(context).getBean("created") + .isEqualTo("This is always created"); + assertThat(context).hasBean("createOnBean"); + assertThat(context).getBean("createOnBean") + .isEqualTo("This is created when bean (name=created) is present"); + }); + } + + @Test + public void whenDependentBeanIsPresent_thenConditionalMissingBeanIgnored() { + this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("created"); + assertThat(context).getBean("created") + .isEqualTo("This is always created"); + assertThat(context).doesNotHaveBean("createOnMissingBean"); + }); + } + + @Test + public void whenDependentBeanIsNotPresent_thenConditionalMissingBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("createOnMissingBean"); + assertThat(context).getBean("createOnMissingBean") + .isEqualTo("This is created when bean (name=created) is missing"); + assertThat(context).doesNotHaveBean("created"); + }); + } + + @Configuration + protected static class basicConfiguration { + @Bean + public String created() { + return "This is always created"; + } + } + + @Configuration + @ConditionalOnBean(name = "created") + protected static class ConditionalOnBeanConfiguration { + @Bean + public String createOnBean() { + return "This is created when bean (name=created) is present"; + } + } + + @Configuration + @ConditionalOnMissingBean(name = "created") + protected static class ConditionalOnMissingBeanConfiguration { + @Bean + public String createOnMissingBean() { + return "This is created when bean (name=created) is missing"; + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java new file mode 100644 index 0000000000..7f01ea85d4 --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java @@ -0,0 +1,76 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class ConditionalOnClassTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenDependentClassIsPresent_thenBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) + .run(context -> { + assertThat(context).hasBean("created"); + assertThat(context.getBean("created")).isEqualTo("This is created when ConditionalOnClassTest is present on the classpath"); + }); + } + + @Test + public void whenDependentClassIsPresent_thenBeanMissing() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingClassConfiguration.class) + .run(context -> { + assertThat(context).doesNotHaveBean("missed"); + }); + } + + @Test + public void whenDependentClassIsNotPresent_thenBeanMissing() { + this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .run((context) -> { + assertThat(context).doesNotHaveBean("created"); + assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + + }); + } + + @Test + public void whenDependentClassIsNotPresent_thenBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingClassConfiguration.class) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .run((context) -> { + assertThat(context).hasBean("missed"); + assertThat(context).getBean("missed") + .isEqualTo("This is missed when ConditionalOnClassTest is present on the classpath"); + assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + + }); + } + + @Configuration + @ConditionalOnClass(ConditionalOnClassTest.class) + protected static class ConditionalOnClassConfiguration { + @Bean + public String created() { + return "This is created when ConditionalOnClassTest is present on the classpath"; + } + } + + @Configuration + @ConditionalOnMissingClass("com.baeldung.autoconfiguration.ConditionalOnClassTest") + protected static class ConditionalOnMissingClassConfiguration { + @Bean + public String missed() { + return "This is missed when ConditionalOnClassTest is present on the classpath"; + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java new file mode 100644 index 0000000000..2c09b72dda --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java @@ -0,0 +1,64 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; + +import com.baeldung.autoconfiguration.service.CustomService; +import com.baeldung.autoconfiguration.service.DefaultService; +import com.baeldung.autoconfiguration.service.SimpleService; + +public class ConditionalOnPropertyTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenGivenCustomPropertyValue_thenCustomServiceCreated() { + this.contextRunner.withPropertyValues("com.baeldung.service=custom") + .withUserConfiguration(SimpleServiceConfiguration.class) + .run(context -> { + assertThat(context).hasBean("customService"); + SimpleService simpleService = context.getBean(CustomService.class); + assertThat(simpleService.serve()).isEqualTo("Custom Service"); + assertThat(context).doesNotHaveBean("defaultService"); + }); + } + + @Test + public void whenGivenDefaultPropertyValue_thenDefaultServiceCreated() { + this.contextRunner.withPropertyValues("com.baeldung.service=default") + .withUserConfiguration(SimpleServiceConfiguration.class) + .run(context -> { + assertThat(context).hasBean("defaultService"); + SimpleService simpleService = context.getBean(DefaultService.class); + assertThat(simpleService.serve()).isEqualTo("Default Service"); + assertThat(context).doesNotHaveBean("customService"); + }); + } + + @Configuration + @TestPropertySource("classpath:ConditionalOnPropertyTest.properties") + protected static class SimpleServiceConfiguration { + + @Bean + @ConditionalOnProperty(name = "com.baeldung.service", havingValue = "default") + @ConditionalOnMissingBean + public DefaultService defaultService() { + return new DefaultService(); + } + + @Bean + @ConditionalOnProperty(name = "com.baeldung.service", havingValue = "custom") + @ConditionalOnMissingBean + public CustomService customService() { + return new CustomService(); + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties b/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties new file mode 100644 index 0000000000..b6334bc1ce --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties @@ -0,0 +1 @@ +com.baeldung.service=custom \ No newline at end of file From 6754e4cd218f2ba032ef798e48c9a26410a159a7 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Mon, 20 May 2019 21:37:55 +1000 Subject: [PATCH 08/63] BAEL-2878 rename the test --- ... => ConditionalOnBeanIntegrationTest.java} | 2 +- ...=> ConditionalOnClassIntegrationTest.java} | 22 +++++++++---------- ...ConditionalOnPropertyIntegrationTest.java} | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) rename spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/{ConditionalOnBeanTest.java => ConditionalOnBeanIntegrationTest.java} (98%) rename spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/{ConditionalOnClassTest.java => ConditionalOnClassIntegrationTest.java} (80%) rename spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/{ConditionalOnPropertyTest.java => ConditionalOnPropertyIntegrationTest.java} (98%) diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java similarity index 98% rename from spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java rename to spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java index 313d1253c5..c94b432b9d 100644 --- a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java @@ -9,7 +9,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -public class ConditionalOnBeanTest { +public class ConditionalOnBeanIntegrationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassIntegrationTest.java similarity index 80% rename from spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java rename to spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassIntegrationTest.java index 7f01ea85d4..f2866867f2 100644 --- a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -public class ConditionalOnClassTest { +public class ConditionalOnClassIntegrationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); @@ -19,7 +19,7 @@ public class ConditionalOnClassTest { this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) .run(context -> { assertThat(context).hasBean("created"); - assertThat(context.getBean("created")).isEqualTo("This is created when ConditionalOnClassTest is present on the classpath"); + assertThat(context.getBean("created")).isEqualTo("This is created when ConditionalOnClassIntegrationTest is present on the classpath"); }); } @@ -34,10 +34,10 @@ public class ConditionalOnClassTest { @Test public void whenDependentClassIsNotPresent_thenBeanMissing() { this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) - .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassIntegrationTest.class)) .run((context) -> { assertThat(context).doesNotHaveBean("created"); - assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + assertThat(context).doesNotHaveBean(ConditionalOnClassIntegrationTest.class); }); } @@ -45,31 +45,31 @@ public class ConditionalOnClassTest { @Test public void whenDependentClassIsNotPresent_thenBeanCreated() { this.contextRunner.withUserConfiguration(ConditionalOnMissingClassConfiguration.class) - .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassIntegrationTest.class)) .run((context) -> { assertThat(context).hasBean("missed"); assertThat(context).getBean("missed") - .isEqualTo("This is missed when ConditionalOnClassTest is present on the classpath"); - assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + .isEqualTo("This is missed when ConditionalOnClassIntegrationTest is present on the classpath"); + assertThat(context).doesNotHaveBean(ConditionalOnClassIntegrationTest.class); }); } @Configuration - @ConditionalOnClass(ConditionalOnClassTest.class) + @ConditionalOnClass(ConditionalOnClassIntegrationTest.class) protected static class ConditionalOnClassConfiguration { @Bean public String created() { - return "This is created when ConditionalOnClassTest is present on the classpath"; + return "This is created when ConditionalOnClassIntegrationTest is present on the classpath"; } } @Configuration - @ConditionalOnMissingClass("com.baeldung.autoconfiguration.ConditionalOnClassTest") + @ConditionalOnMissingClass("com.baeldung.autoconfiguration.ConditionalOnClassIntegrationTest") protected static class ConditionalOnMissingClassConfiguration { @Bean public String missed() { - return "This is missed when ConditionalOnClassTest is present on the classpath"; + return "This is missed when ConditionalOnClassIntegrationTest is present on the classpath"; } } diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyIntegrationTest.java similarity index 98% rename from spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java rename to spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyIntegrationTest.java index 2c09b72dda..c0733722dc 100644 --- a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyIntegrationTest.java @@ -14,7 +14,7 @@ import com.baeldung.autoconfiguration.service.CustomService; import com.baeldung.autoconfiguration.service.DefaultService; import com.baeldung.autoconfiguration.service.SimpleService; -public class ConditionalOnPropertyTest { +public class ConditionalOnPropertyIntegrationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); From 2c79a4a97f841a1335a031a041f78631b95b0003 Mon Sep 17 00:00:00 2001 From: Alessio Stalla Date: Tue, 21 May 2019 19:05:11 +0200 Subject: [PATCH 09/63] First Hibernate Validator specific constraints tests. --- persistence-modules/hibernate-mapping/pom.xml | 20 ++---- .../hibernate/persistmaps/mapkey/User.java | 22 ++++++ .../UserAdditionalValidationUnitTest.java | 72 +++++++++++++++++++ 3 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index 6bab3c5b1f..67eda5bf72 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -5,9 +5,9 @@ com.baeldung - parent-modules + persistence-modules 1.0.0-SNAPSHOT - ../../ + .. hibernate-mapping @@ -31,17 +31,12 @@ h2 ${h2.version} - + org.hibernate hibernate-validator ${hibernate-validator.version} - - javax.el - javax.el-api - ${javax.el-api.version} - org.glassfish javax.el @@ -60,11 +55,10 @@ - 5.3.7.Final + 5.3.10.Final 3.8.0 - 5.3.3.Final - 2.2.5 - 3.0.1-b08 + 6.0.16.Final + 3.0.1-b11 - \ No newline at end of file + diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java index f6e8f1cdd6..961fc944a4 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java @@ -6,6 +6,7 @@ import javax.persistence.Id; import javax.validation.constraints.Size; import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.CreditCardNumber; @Entity public class User { @@ -23,6 +24,12 @@ public class User { @Size(min = 3, max = 5) private String city; + @CreditCardNumber + private String creditCardNumber; + + @CreditCardNumber(ignoreNonDigitCharacters = true) + private String lenientCreditCardNumber; + public User(String firstName, String middleName, String lastName, String city) { super(); this.firstName = firstName; @@ -63,4 +70,19 @@ public class User { this.city = city; } + public String getCreditCardNumber() { + return creditCardNumber; + } + + public void setCreditCardNumber(String creditCardNumber) { + this.creditCardNumber = creditCardNumber; + } + + public String getLenientCreditCardNumber() { + return lenientCreditCardNumber; + } + + public void setLenientCreditCardNumber(String lenientCreditCardNumber) { + this.lenientCreditCardNumber = lenientCreditCardNumber; + } } diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java new file mode 100644 index 0000000000..aaf52fe765 --- /dev/null +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java @@ -0,0 +1,72 @@ +package com.baeldung.hibernate.validation; + +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; +import com.baeldung.hibernate.persistmaps.mapkey.User; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.persistence.PersistenceException; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class UserAdditionalValidationUnitTest { + + private static Validator validator; + private static SessionFactory sessionFactory; + private Session session; + private Set> constraintViolations; + + @BeforeClass + public static void before() { + ValidatorFactory config = Validation.buildDefaultValidatorFactory(); + validator = config.getValidator(); + sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_BASED); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + } + + @Test + public void whenValidationWithCCNAndNullCCN_thenNoConstraintViolation() { + User user = new User("John", "Paul", "Butler", "York"); + constraintViolations = validator.validateProperty(user, "creditCardNumber"); + assertTrue(constraintViolations.isEmpty()); + } + + @Test + public void whenValidationWithCCNAndValidCCN_thenNoConstraintViolation() { + User user = new User("John", "Paul", "Butler", "York"); + user.setCreditCardNumber("79927398713"); + constraintViolations = validator.validateProperty(user, "creditCardNumber"); + assertTrue(constraintViolations.isEmpty()); + } + + @Test + public void whenValidationWithCCNAndInvalidCCN_thenConstraintViolation() { + User user = new User("John", "Paul", "Butler", "York"); + user.setCreditCardNumber("79927398714"); + constraintViolations = validator.validateProperty(user, "creditCardNumber"); + assertEquals(constraintViolations.size(), 1); + } + + @Test + public void whenValidationWithLenientCCNAndValidCCNWithDashes_thenNoConstraintViolation() { + User user = new User("John", "Paul", "Butler", "York"); + user.setLenientCreditCardNumber("7992-7398-713"); + constraintViolations = validator.validateProperty(user, "lenientCreditCardNumber"); + assertTrue(constraintViolations.isEmpty()); + } +} From 7c3082a0930e7937c0507021fc0ca6a2d25e1d0a Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Fri, 24 May 2019 08:09:59 +0100 Subject: [PATCH 10/63] BAEL-2899: project structure and example classes --- java-groovy-joint/pom.xml | 132 ++++++++++++++++++ .../main/groovy/com.baeldung/CalcMath.groovy | 19 +++ .../groovy/com.baeldung/CalcScript.groovy | 19 +++ .../src/main/java/com/baeldung/App.java | 54 +++++++ 4 files changed, 224 insertions(+) create mode 100644 java-groovy-joint/pom.xml create mode 100644 java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy create mode 100644 java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy create mode 100644 java-groovy-joint/src/main/java/com/baeldung/App.java diff --git a/java-groovy-joint/pom.xml b/java-groovy-joint/pom.xml new file mode 100644 index 0000000000..67365cf999 --- /dev/null +++ b/java-groovy-joint/pom.xml @@ -0,0 +1,132 @@ + + + + 4.0.0 + java-groovy-joint + 0.1.0-SNAPSHOT + java-groovy-joint + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + 3.9 + 1.8 + 3.8.1 + 1.2.3 + 2.5.7 + + + + + bintray + Groovy Bintray + https://dl.bintray.com/groovy/maven + + never + + + false + + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.codehaus.groovy + groovy-all + ${groovy.version} + pom + + + junit + junit + 4.11 + test + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + com.baeldung.App + true + + + + + + maven-compiler-plugin + 3.8.0 + + groovy-eclipse-compiler + ${java.version} + ${java.version} + + + + org.codehaus.groovy + groovy-eclipse-compiler + 3.3.0-01 + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.version}-01 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.0 + + + + jar-with-dependencies + + + + + com.baeldung.App + + + + + + + make-assembly + + package + + single + + + + + + + + + diff --git a/java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy b/java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy new file mode 100644 index 0000000000..d9709653c7 --- /dev/null +++ b/java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy @@ -0,0 +1,19 @@ +package com.baeldung + +import org.slf4j.LoggerFactory + +class CalcMath { + def log = LoggerFactory.getLogger(this.getClass()) + + def calcSum(x, y) { + log.info "Executing $x + $y" + x + y + } + + def calcSum2(x, y) { + log.info "Executing $x + $y" + // DANGER! This won't throw a compilation issue and fail only at runtime!!! + calcSum3() + log.info("Logging an undefined variable: $z") + } +} \ No newline at end of file diff --git a/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy b/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy new file mode 100644 index 0000000000..2278f0dab8 --- /dev/null +++ b/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy @@ -0,0 +1,19 @@ +package com.baeldung + +import org.slf4j.LoggerFactory + +abstract class CalcScript extends Script { + def log = LoggerFactory.getLogger(this.getClass()) + + def calcSum(x, y) { + log.info "Executing $x + $y" + x + y + } + + def calcSum2(x, y) { + log.info "Executing $x + $y" + // DANGER! This won't throw a compilation issue and fail only at runtime!!! + calcSum3() + log.info("Logging an undefined variable: $z") + } +} \ No newline at end of file diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/java-groovy-joint/src/main/java/com/baeldung/App.java new file mode 100644 index 0000000000..0a201d12e2 --- /dev/null +++ b/java-groovy-joint/src/main/java/com/baeldung/App.java @@ -0,0 +1,54 @@ +package com.baeldung; + +import groovy.lang.Binding; +import groovy.lang.GroovyClassLoader; +import groovy.lang.GroovyShell; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Hello world! + * + */ +public class App { + private final static Logger LOG = LoggerFactory.getLogger(App.class); + private final GroovyClassLoader loader; + private final GroovyShell shell; + + private App() { + loader = new GroovyClassLoader(this.getClass().getClassLoader()); + CompilerConfiguration config = new CompilerConfiguration(); + config.setScriptBaseClass("com.baeldung.CalcScript"); + shell = new GroovyShell(loader, new Binding(), config); + } + + private void runScript(int x, int y) { + Object script = shell.parse(String.format("calcSum(%d,%d)", x, y)); + assert script instanceof CalcScript; + Object result = ((CalcScript) script).run(); + LOG.info("Result of run() method is {}", result); + + Object script2 = shell.parse("CalcScript"); + Object result2 = ((CalcScript) script2).calcSum(x + 7, y + 7); + LOG.info("Result of calcSum() method is {}", result2); + + } + + private void runClass(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + Class calcClass = loader.loadClass("com.baeldung.CalcMath"); + Object calc = calcClass.newInstance(); + assert calc instanceof CalcMath; + + Object result = ((CalcMath) calc).calcSum(x, y); + LOG.info("Result is {}", result); + } + + public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + App app = new App(); + LOG.info("Running a groovy script..."); + app.runScript(5, 10); + LOG.info("Running a groovy class..."); + app.runClass(1, 3); + } +} From 653717e25ef14bf7aadaed736d268fb9fe4a371c Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Sun, 26 May 2019 01:09:20 +0100 Subject: [PATCH 11/63] BAEL-2899: adding some more case scenarios --- java-groovy-joint/gmavenplus-pom.xml | 148 ++++++++++++++++++ java-groovy-joint/pom.xml | 1 + .../groovy/com.baeldung/CalcScript.groovy | 19 --- .../baeldung}/CalcMath.groovy | 6 + .../groovy/com/baeldung/CalcScript.groovy | 10 ++ .../src/main/java/com/baeldung/App.java | 74 +++++++-- 6 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 java-groovy-joint/gmavenplus-pom.xml delete mode 100644 java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy rename java-groovy-joint/src/main/groovy/{com.baeldung => com/baeldung}/CalcMath.groovy (76%) create mode 100644 java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy diff --git a/java-groovy-joint/gmavenplus-pom.xml b/java-groovy-joint/gmavenplus-pom.xml new file mode 100644 index 0000000000..b34eeb292d --- /dev/null +++ b/java-groovy-joint/gmavenplus-pom.xml @@ -0,0 +1,148 @@ + + + + 4.0.0 + java-groovy-joint + 0.1.0-SNAPSHOT + java-groovy-joint + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + UTF-8 + 3.9 + 1.8 + 3.8.1 + 1.2.3 + 2.5.7 + + + + + bintray + Groovy Bintray + https://dl.bintray.com/groovy/maven + + never + + + false + + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.codehaus.groovy + groovy-all + ${groovy.version} + pom + + + junit + junit + 4.11 + test + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.2 + + + + com.baeldung.App + true + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.7.0 + + + + execute + addSources + addTestSources + generateStubs + compile + generateTestStubs + compileTests + removeStubs + removeTestStubs + + + + + + org.codehaus.groovy + groovy-all + + 2.5.6 + runtime + pom + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.0 + + + + jar-with-dependencies + + + + + com.baeldung.App + + + + + + + make-assembly + + package + + single + + + + + + + + + diff --git a/java-groovy-joint/pom.xml b/java-groovy-joint/pom.xml index 67365cf999..5ac4768865 100644 --- a/java-groovy-joint/pom.xml +++ b/java-groovy-joint/pom.xml @@ -27,6 +27,7 @@ Groovy Bintray https://dl.bintray.com/groovy/maven + never diff --git a/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy b/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy deleted file mode 100644 index 2278f0dab8..0000000000 --- a/java-groovy-joint/src/main/groovy/com.baeldung/CalcScript.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package com.baeldung - -import org.slf4j.LoggerFactory - -abstract class CalcScript extends Script { - def log = LoggerFactory.getLogger(this.getClass()) - - def calcSum(x, y) { - log.info "Executing $x + $y" - x + y - } - - def calcSum2(x, y) { - log.info "Executing $x + $y" - // DANGER! This won't throw a compilation issue and fail only at runtime!!! - calcSum3() - log.info("Logging an undefined variable: $z") - } -} \ No newline at end of file diff --git a/java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy b/java-groovy-joint/src/main/groovy/com/baeldung/CalcMath.groovy similarity index 76% rename from java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy rename to java-groovy-joint/src/main/groovy/com/baeldung/CalcMath.groovy index d9709653c7..0e233793b2 100644 --- a/java-groovy-joint/src/main/groovy/com.baeldung/CalcMath.groovy +++ b/java-groovy-joint/src/main/groovy/com/baeldung/CalcMath.groovy @@ -10,6 +10,12 @@ class CalcMath { x + y } + /** + * example of method that in java would throw error at compile time + * @param x + * @param y + * @return + */ def calcSum2(x, y) { log.info "Executing $x + $y" // DANGER! This won't throw a compilation issue and fail only at runtime!!! diff --git a/java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy b/java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy new file mode 100644 index 0000000000..688928468a --- /dev/null +++ b/java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy @@ -0,0 +1,10 @@ +package com.baeldung + +def calcSum(x, y) { + x + y +} + +def calcSum2(x, y) { + // DANGER! This won't throw a compilation issue and fail only at runtime!!! + calcSum3() +} diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/java-groovy-joint/src/main/java/com/baeldung/App.java index 0a201d12e2..7cfeba2024 100644 --- a/java-groovy-joint/src/main/java/com/baeldung/App.java +++ b/java-groovy-joint/src/main/java/com/baeldung/App.java @@ -1,12 +1,20 @@ package com.baeldung; -import groovy.lang.Binding; -import groovy.lang.GroovyClassLoader; -import groovy.lang.GroovyShell; +import groovy.lang.*; +import groovy.util.GroovyScriptEngine; +import groovy.util.ResourceException; +import groovy.util.ScriptException; import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.script.Compilable; +import javax.script.ScriptEngine; +import java.io.File; +import java.io.IOException; +import java.net.URL; + /** * Hello world! * @@ -15,40 +23,84 @@ public class App { private final static Logger LOG = LoggerFactory.getLogger(App.class); private final GroovyClassLoader loader; private final GroovyShell shell; + private final GroovyScriptEngine engine; - private App() { + private App() throws IOException { loader = new GroovyClassLoader(this.getClass().getClassLoader()); CompilerConfiguration config = new CompilerConfiguration(); config.setScriptBaseClass("com.baeldung.CalcScript"); shell = new GroovyShell(loader, new Binding(), config); + engine = new GroovyScriptEngine(new URL[] { new File("src/main/groovy/com/baeldung/").toURI().toURL() }, this.getClass().getClassLoader()); } - private void runScript(int x, int y) { - Object script = shell.parse(String.format("calcSum(%d,%d)", x, y)); + private void runCompiledClasses(int x, int y) { + Object result1 = new CalcScript().calcSum(x, y); + LOG.info("Result of calcSum() method is {}", result1); + + Object result2 = new CalcMath().calcSum(x, y); + LOG.info("Result of calcSum() method is {}", result2); + } + + private void runShellScript(int x, int y) { + Script script = shell.parse(String.format("calcSum(%d,%d)", x, y)); assert script instanceof CalcScript; - Object result = ((CalcScript) script).run(); + Object result = script.run(); LOG.info("Result of run() method is {}", result); Object script2 = shell.parse("CalcScript"); + assert script2 instanceof CalcScript; Object result2 = ((CalcScript) script2).calcSum(x + 7, y + 7); LOG.info("Result of calcSum() method is {}", result2); + Script script3 = shell.parse(""); + assert script3 instanceof CalcScript; + Object result3 = script3.invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); + LOG.info("Result of run() method is {}", result3); + } - private void runClass(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + private void runClassWithLoader(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class calcClass = loader.loadClass("com.baeldung.CalcMath"); Object calc = calcClass.newInstance(); assert calc instanceof CalcMath; Object result = ((CalcMath) calc).calcSum(x, y); LOG.info("Result is {}", result); + + Object result2 = ((GroovyObject) calc).invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); + LOG.info("Result is {}", result2); + } - public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + private void runClassWithEngine(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ResourceException, ScriptException { + + Class calcClass = engine.loadScriptByName("CalcMath.groovy"); + GroovyObject calc = calcClass.newInstance(); + Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); + //WARNING the following will throw a ClassCastException + //((CalcMath)calc).calcSum(1,2); + LOG.info("Result is {}", result); + } + + private void runClassWithEngineFactory(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ResourceException, ScriptException, javax.script.ScriptException { + ScriptEngine engine = new GroovyScriptEngineFactory().getScriptEngine(); + Class calcClass = (Class) ((Compilable) engine).compile("com.baeldung.CalcMath").eval(); + Object calc = calcClass.newInstance(); + Object result = ((CalcMath) calc).calcSum(1, 20); + LOG.info("Result is {}", result); + } + + public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, ResourceException, ScriptException, IOException, javax.script.ScriptException { App app = new App(); + LOG.info("Running an already compiled groovy class instance..."); + app.runCompiledClasses(5, 10); LOG.info("Running a groovy script..."); - app.runScript(5, 10); + app.runShellScript(5, 10); LOG.info("Running a groovy class..."); - app.runClass(1, 3); + app.runClassWithLoader(1, 3); + LOG.info("Running a groovy class using the engine..."); + app.runClassWithEngine(10, 30); + LOG.info("Running a groovy class using the engine factory..."); + app.runClassWithEngineFactory(10, 30); } } From 066cf2d6f2d9122a648ce016aa31412cd22bd4c2 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 26 May 2019 22:14:10 +1000 Subject: [PATCH 12/63] BAEL-2878 Guide to Spring's ApplicationContextRunner --- .../autoconfiguration/ConditionalOnBeanIntegrationTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java index c94b432b9d..32f63edde4 100644 --- a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java @@ -15,7 +15,7 @@ public class ConditionalOnBeanIntegrationTest { @Test public void whenDependentBeanIsPresent_thenConditionalBeanCreated() { - this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnBeanConfiguration.class) + this.contextRunner.withUserConfiguration(BasicConfiguration.class, ConditionalOnBeanConfiguration.class) .run((context) -> { assertThat(context).hasBean("created"); assertThat(context).getBean("created") @@ -28,7 +28,7 @@ public class ConditionalOnBeanIntegrationTest { @Test public void whenDependentBeanIsPresent_thenConditionalMissingBeanIgnored() { - this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) + this.contextRunner.withUserConfiguration(BasicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) .run((context) -> { assertThat(context).hasBean("created"); assertThat(context).getBean("created") @@ -49,7 +49,7 @@ public class ConditionalOnBeanIntegrationTest { } @Configuration - protected static class basicConfiguration { + protected static class BasicConfiguration { @Bean public String created() { return "This is always created"; From b9999c1af1ae2cce154d765ad74d5153cf274e07 Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Mon, 27 May 2019 11:25:19 +0100 Subject: [PATCH 13/63] BAEL-2899: separating static and dynamic classes examples --- .../src/main/java/com/baeldung/App.java | 97 +++++++++---------- 1 file changed, 45 insertions(+), 52 deletions(-) diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/java-groovy-joint/src/main/java/com/baeldung/App.java index 7cfeba2024..7e24ec2c16 100644 --- a/java-groovy-joint/src/main/java/com/baeldung/App.java +++ b/java-groovy-joint/src/main/java/com/baeldung/App.java @@ -4,14 +4,14 @@ import groovy.lang.*; import groovy.util.GroovyScriptEngine; import groovy.util.ResourceException; import groovy.util.ScriptException; -import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.script.Compilable; import javax.script.ScriptEngine; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.net.URL; @@ -24,83 +24,76 @@ public class App { private final GroovyClassLoader loader; private final GroovyShell shell; private final GroovyScriptEngine engine; + private final ScriptEngine engineFromFactory; private App() throws IOException { loader = new GroovyClassLoader(this.getClass().getClassLoader()); - CompilerConfiguration config = new CompilerConfiguration(); - config.setScriptBaseClass("com.baeldung.CalcScript"); - shell = new GroovyShell(loader, new Binding(), config); + shell = new GroovyShell(loader, new Binding()); engine = new GroovyScriptEngine(new URL[] { new File("src/main/groovy/com/baeldung/").toURI().toURL() }, this.getClass().getClassLoader()); + engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine(); + } private void runCompiledClasses(int x, int y) { + LOG.info("Executing {} + {}", x, y); Object result1 = new CalcScript().calcSum(x, y); - LOG.info("Result of calcSum() method is {}", result1); + LOG.info("Result of CalcScript.calcSum() method is {}", result1); Object result2 = new CalcMath().calcSum(x, y); - LOG.info("Result of calcSum() method is {}", result2); + LOG.info("Result of CalcMath.calcSum() method is {}", result2); } - private void runShellScript(int x, int y) { - Script script = shell.parse(String.format("calcSum(%d,%d)", x, y)); - assert script instanceof CalcScript; - Object result = script.run(); - LOG.info("Result of run() method is {}", result); - - Object script2 = shell.parse("CalcScript"); - assert script2 instanceof CalcScript; - Object result2 = ((CalcScript) script2).calcSum(x + 7, y + 7); - LOG.info("Result of calcSum() method is {}", result2); - - Script script3 = shell.parse(""); - assert script3 instanceof CalcScript; - Object result3 = script3.invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); - LOG.info("Result of run() method is {}", result3); - + private void runDynamicShellScript(int x, int y) throws IOException { + Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy")); + LOG.info("Executing {} + {}", x, y); + Object result = script.invokeMethod("calcSum", new Object[] { x, y }); + LOG.info("Result of CalcScript.calcSum() method is {}", result); } - private void runClassWithLoader(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException { - Class calcClass = loader.loadClass("com.baeldung.CalcMath"); + private void runDynamicClassWithLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException { + Class calcClass = loader.parseClass(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")); Object calc = calcClass.newInstance(); - assert calc instanceof CalcMath; - - Object result = ((CalcMath) calc).calcSum(x, y); - LOG.info("Result is {}", result); - - Object result2 = ((GroovyObject) calc).invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); - LOG.info("Result is {}", result2); - + Object result = ((GroovyObject) calc).invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); + LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runClassWithEngine(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ResourceException, ScriptException { + private void runDynamicClassWithEngine(int x, int y) throws IllegalAccessException, InstantiationException, ResourceException, ScriptException { Class calcClass = engine.loadScriptByName("CalcMath.groovy"); GroovyObject calc = calcClass.newInstance(); - Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); //WARNING the following will throw a ClassCastException //((CalcMath)calc).calcSum(1,2); - LOG.info("Result is {}", result); + Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); + LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runClassWithEngineFactory(int x, int y) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ResourceException, ScriptException, javax.script.ScriptException { - ScriptEngine engine = new GroovyScriptEngineFactory().getScriptEngine(); - Class calcClass = (Class) ((Compilable) engine).compile("com.baeldung.CalcMath").eval(); - Object calc = calcClass.newInstance(); - Object result = ((CalcMath) calc).calcSum(1, 20); - LOG.info("Result is {}", result); + private void runDynamicClassWithEngineFactory(int x, int y) throws IllegalAccessException, InstantiationException, javax.script.ScriptException, FileNotFoundException { + Class calcClas = (Class) engineFromFactory.eval(new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"))); + GroovyObject calc = (GroovyObject) calcClas.newInstance(); + Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); + LOG.info("Result of CalcMath.calcSum() method is {}", result); + } + + private void runStaticCompiledClasses() { + LOG.info("Running the Groovy classes compiled statically..."); + runCompiledClasses(5, 10); + + } + + private void runDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException, ResourceException, ScriptException, javax.script.ScriptException { + LOG.info("Running a dynamic groovy script..."); + runDynamicShellScript(5, 10); + LOG.info("Running a dynamic groovy class with GroovyClassLoader..."); + runDynamicClassWithLoader(10, 30); + LOG.info("Running a dynamic groovy class with GroovyScriptEngine..."); + runDynamicClassWithEngine(15, 0); + LOG.info("Running a dynamic groovy class with GroovyScriptEngine JSR223..."); + runDynamicClassWithEngineFactory(5, 6); } public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, ResourceException, ScriptException, IOException, javax.script.ScriptException { App app = new App(); - LOG.info("Running an already compiled groovy class instance..."); - app.runCompiledClasses(5, 10); - LOG.info("Running a groovy script..."); - app.runShellScript(5, 10); - LOG.info("Running a groovy class..."); - app.runClassWithLoader(1, 3); - LOG.info("Running a groovy class using the engine..."); - app.runClassWithEngine(10, 30); - LOG.info("Running a groovy class using the engine factory..."); - app.runClassWithEngineFactory(10, 30); + app.runStaticCompiledClasses(); + app.runDynamicCompiledClasses(); } } From 224ceb98d5f99f3c445647d65c7d2d864838e6c8 Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Mon, 27 May 2019 12:33:09 +0100 Subject: [PATCH 14/63] BAEL-2899: formatting --- .../src/main/java/com/baeldung/App.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/java-groovy-joint/src/main/java/com/baeldung/App.java index 7e24ec2c16..c964d1c7cd 100644 --- a/java-groovy-joint/src/main/java/com/baeldung/App.java +++ b/java-groovy-joint/src/main/java/com/baeldung/App.java @@ -29,9 +29,10 @@ public class App { private App() throws IOException { loader = new GroovyClassLoader(this.getClass().getClassLoader()); shell = new GroovyShell(loader, new Binding()); - engine = new GroovyScriptEngine(new URL[] { new File("src/main/groovy/com/baeldung/").toURI().toURL() }, this.getClass().getClassLoader()); + engine = new GroovyScriptEngine(new URL[] { + new File("src/main/groovy/com/baeldung/").toURI().toURL() + }, this.getClass().getClassLoader()); engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine(); - } private void runCompiledClasses(int x, int y) { @@ -51,9 +52,10 @@ public class App { } private void runDynamicClassWithLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException { - Class calcClass = loader.parseClass(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")); - Object calc = calcClass.newInstance(); - Object result = ((GroovyObject) calc).invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); + Class calcClass = loader.parseClass( + new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")); + GroovyObject calc = (GroovyObject) calcClass.newInstance(); + Object result = calc.invokeMethod("calcSum", new Object[] { x + 14, y + 14 }); LOG.info("Result of CalcMath.calcSum() method is {}", result); } @@ -68,7 +70,8 @@ public class App { } private void runDynamicClassWithEngineFactory(int x, int y) throws IllegalAccessException, InstantiationException, javax.script.ScriptException, FileNotFoundException { - Class calcClas = (Class) engineFromFactory.eval(new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"))); + Class calcClas = (Class) engineFromFactory.eval( + new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"))); GroovyObject calc = (GroovyObject) calcClas.newInstance(); Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); LOG.info("Result of CalcMath.calcSum() method is {}", result); From 8c8678159d958bd044ab3544109cf328876be79e Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Mon, 27 May 2019 12:47:30 +0100 Subject: [PATCH 15/63] BAEL-2899: reducing line length --- .../src/main/java/com/baeldung/App.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/java-groovy-joint/src/main/java/com/baeldung/App.java index c964d1c7cd..6c92c3a0b1 100644 --- a/java-groovy-joint/src/main/java/com/baeldung/App.java +++ b/java-groovy-joint/src/main/java/com/baeldung/App.java @@ -59,7 +59,8 @@ public class App { LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runDynamicClassWithEngine(int x, int y) throws IllegalAccessException, InstantiationException, ResourceException, ScriptException { + private void runDynamicClassWithEngine(int x, int y) throws IllegalAccessException, + InstantiationException, ResourceException, ScriptException { Class calcClass = engine.loadScriptByName("CalcMath.groovy"); GroovyObject calc = calcClass.newInstance(); @@ -69,7 +70,8 @@ public class App { LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runDynamicClassWithEngineFactory(int x, int y) throws IllegalAccessException, InstantiationException, javax.script.ScriptException, FileNotFoundException { + private void runDynamicClassWithEngineFactory(int x, int y) throws IllegalAccessException, + InstantiationException, javax.script.ScriptException, FileNotFoundException { Class calcClas = (Class) engineFromFactory.eval( new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"))); GroovyObject calc = (GroovyObject) calcClas.newInstance(); @@ -83,7 +85,8 @@ public class App { } - private void runDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException, ResourceException, ScriptException, javax.script.ScriptException { + private void runDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException, + ResourceException, ScriptException, javax.script.ScriptException { LOG.info("Running a dynamic groovy script..."); runDynamicShellScript(5, 10); LOG.info("Running a dynamic groovy class with GroovyClassLoader..."); @@ -94,7 +97,8 @@ public class App { runDynamicClassWithEngineFactory(5, 6); } - public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, ResourceException, ScriptException, IOException, javax.script.ScriptException { + public static void main(String[] args) throws InstantiationException, IllegalAccessException, + ResourceException, ScriptException, IOException, javax.script.ScriptException { App app = new App(); app.runStaticCompiledClasses(); app.runDynamicCompiledClasses(); From f689fa9e5e366ab2aaaafdd137851fb0b269e090 Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Thu, 30 May 2019 18:03:11 +0100 Subject: [PATCH 16/63] BAEL-2899: moving joint compilation to core-groovy-2 module --- .../gmavenplus-pom.xml | 132 +++++++++-------- core-groovy-2/pom.xml | 84 ++++++----- .../main/groovy/com/baeldung/CalcMath.groovy | 0 .../groovy/com/baeldung/CalcScript.groovy | 0 .../src/main/java/com/baeldung/App.java | 0 java-groovy-joint/pom.xml | 133 ------------------ 6 files changed, 126 insertions(+), 223 deletions(-) rename {java-groovy-joint => core-groovy-2}/gmavenplus-pom.xml (57%) rename {java-groovy-joint => core-groovy-2}/src/main/groovy/com/baeldung/CalcMath.groovy (100%) rename {java-groovy-joint => core-groovy-2}/src/main/groovy/com/baeldung/CalcScript.groovy (100%) rename {java-groovy-joint => core-groovy-2}/src/main/java/com/baeldung/App.java (100%) delete mode 100644 java-groovy-joint/pom.xml diff --git a/java-groovy-joint/gmavenplus-pom.xml b/core-groovy-2/gmavenplus-pom.xml similarity index 57% rename from java-groovy-joint/gmavenplus-pom.xml rename to core-groovy-2/gmavenplus-pom.xml index b34eeb292d..924dab94d1 100644 --- a/java-groovy-joint/gmavenplus-pom.xml +++ b/core-groovy-2/gmavenplus-pom.xml @@ -1,50 +1,19 @@ - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - java-groovy-joint - 0.1.0-SNAPSHOT - java-groovy-joint + core-groovy-2 + 1.0-SNAPSHOT + core-groovy-2 + jar + com.baeldung parent-modules 1.0.0-SNAPSHOT - - UTF-8 - 3.9 - 1.8 - 3.8.1 - 1.2.3 - 2.5.7 - - - - - bintray - Groovy Bintray - https://dl.bintray.com/groovy/maven - - never - - - false - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - ch.qos.logback - logback-classic - ${logback.version} - org.codehaus.groovy groovy-all @@ -52,30 +21,29 @@ pom - junit - junit - 4.11 + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + org.spockframework + spock-core + ${spock-core.version} test - + src/main/groovy + src/main/java - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 - - - - com.baeldung.App - true - - - - org.codehaus.gmavenplus gmavenplus-plugin @@ -100,7 +68,7 @@ org.codehaus.groovy groovy-all - 2.5.6 + ${groovy.version} runtime pom @@ -110,8 +78,42 @@ org.apache.maven.plugins maven-compiler-plugin - - + + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + + + + + junit5 + + integration-test + verify + + + + **/*Test5.java + + + + + + + maven-surefire-plugin + 2.20.1 + + false + + **/*Test.java + **/*Spec.java + + + org.apache.maven.plugins @@ -144,5 +146,19 @@ + + + central + http://jcenter.bintray.com + + + + 1.0.0 + 2.5.7 + 2.4.0 + 1.1-groovy-2.4 + 1.6 + + diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml index 77de9c8fc8..0ade31acdb 100644 --- a/core-groovy-2/pom.xml +++ b/core-groovy-2/pom.xml @@ -14,26 +14,11 @@ - - org.codehaus.groovy - groovy - ${groovy.version} - org.codehaus.groovy groovy-all - ${groovy-all.version} - pom - - - org.codehaus.groovy - groovy-dateutil ${groovy.version} - - - org.codehaus.groovy - groovy-sql - ${groovy-sql.version} + pom org.junit.platform @@ -56,21 +41,29 @@ + src/main/groovy + src/main/java - org.codehaus.gmavenplus - gmavenplus-plugin - ${gmavenplus-plugin.version} - - - - addSources - addTestSources - compile - compileTests - - - + maven-compiler-plugin + 3.8.0 + + groovy-eclipse-compiler + ${java.version} + ${java.version} + + + + org.codehaus.groovy + groovy-eclipse-compiler + 3.3.0-01 + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.version}-01 + + maven-failsafe-plugin @@ -108,6 +101,35 @@ + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.0 + + + + jar-with-dependencies + + + + + com.baeldung.App + + + + + + + make-assembly + + package + + single + + + + @@ -120,9 +142,7 @@ 1.0.0 - 2.5.6 - 2.5.6 - 2.5.6 + 2.5.7 2.4.0 1.1-groovy-2.4 1.6 diff --git a/java-groovy-joint/src/main/groovy/com/baeldung/CalcMath.groovy b/core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy similarity index 100% rename from java-groovy-joint/src/main/groovy/com/baeldung/CalcMath.groovy rename to core-groovy-2/src/main/groovy/com/baeldung/CalcMath.groovy diff --git a/java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy b/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy similarity index 100% rename from java-groovy-joint/src/main/groovy/com/baeldung/CalcScript.groovy rename to core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy diff --git a/java-groovy-joint/src/main/java/com/baeldung/App.java b/core-groovy-2/src/main/java/com/baeldung/App.java similarity index 100% rename from java-groovy-joint/src/main/java/com/baeldung/App.java rename to core-groovy-2/src/main/java/com/baeldung/App.java diff --git a/java-groovy-joint/pom.xml b/java-groovy-joint/pom.xml deleted file mode 100644 index 5ac4768865..0000000000 --- a/java-groovy-joint/pom.xml +++ /dev/null @@ -1,133 +0,0 @@ - - - - 4.0.0 - java-groovy-joint - 0.1.0-SNAPSHOT - java-groovy-joint - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - UTF-8 - 3.9 - 1.8 - 3.8.1 - 1.2.3 - 2.5.7 - - - - - bintray - Groovy Bintray - https://dl.bintray.com/groovy/maven - - - never - - - false - - - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - org.codehaus.groovy - groovy-all - ${groovy.version} - pom - - - junit - junit - 4.11 - test - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 3.1.2 - - - - com.baeldung.App - true - - - - - - maven-compiler-plugin - 3.8.0 - - groovy-eclipse-compiler - ${java.version} - ${java.version} - - - - org.codehaus.groovy - groovy-eclipse-compiler - 3.3.0-01 - - - org.codehaus.groovy - groovy-eclipse-batch - ${groovy.version}-01 - - - - - - org.apache.maven.plugins - maven-assembly-plugin - 3.1.0 - - - - jar-with-dependencies - - - - - com.baeldung.App - - - - - - - make-assembly - - package - - single - - - - - - - - - From a0282482bc45d6a47e5c10cf078f7260bd1c867c Mon Sep 17 00:00:00 2001 From: codehunter34 Date: Fri, 31 May 2019 23:23:12 -0400 Subject: [PATCH 17/63] BAEL-2969: Copying Sets in Java --- .../core-java-collections-set/pom.xml | 71 ++++++++++-------- .../main/java/com/baeldung/set/CopySets.java | 74 +++++++++++++++++++ 2 files changed, 116 insertions(+), 29 deletions(-) create mode 100644 core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java diff --git a/core-java-modules/core-java-collections-set/pom.xml b/core-java-modules/core-java-collections-set/pom.xml index 2a930efde8..4c1b880f31 100644 --- a/core-java-modules/core-java-collections-set/pom.xml +++ b/core-java-modules/core-java-collections-set/pom.xml @@ -1,33 +1,46 @@ - - 4.0.0 - core-java-collections-set - 0.1.0-SNAPSHOT - core-java-collections-set - jar + + 4.0.0 + core-java-collections-set + 0.1.0-SNAPSHOT + core-java-collections-set + jar - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + - - - com.google.guava - guava - ${guava.version} - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - + + + com.google.guava + guava + ${guava.version} + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + - - 4.3 - 27.1-jre - + + com.google.code.gson + gson + 2.8.5 + + + + commons-lang + commons-lang + 2.6 + + + + + 4.3 + 27.1-jre + diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java new file mode 100644 index 0000000000..011ccb9b56 --- /dev/null +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java @@ -0,0 +1,74 @@ +package com.baeldung.set; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang.SerializationUtils; + +import com.google.gson.Gson; + +public class CopySets { + + public static Set copyByConstructor(Set original) { + Set copy = new HashSet<>(original); + return copy; + } + + public static Set copyBySetAddAll(Set original) { + Set copy = new HashSet<>(); + copy.addAll(original); + return copy; + } + + public static Set copyBySetClone(HashSet original) { + Set copy = (Set) original.clone(); + return copy; + } + + public static Set copyByJson(Set original) { + Gson gson = new Gson(); + String jsonStr = gson.toJson(original); + Set copy = gson.fromJson(jsonStr, Set.class); + + return copy; + } + + public static Set copyByApacheCommonsLang(Set original) { + Set copy = new HashSet<>(); + for (T item : original) { + copy.add((T) SerializationUtils.clone(item)); + } + return copy; + } + + public static void copyByStreamsAPI(Set original) { + Set copy1 = original.stream() + .collect(Collectors.toSet()); + + // Skip the first element + Set copy2 = original.stream() + .skip(1) + .collect(Collectors.toSet()); + + // Filter by comparing the types and attributes + Set copy3 = original.stream() + .filter(f -> f.getClass() + .equals(Integer.class)) + .collect(Collectors.toSet()); + + // Null check in case of expecting null values + Set copy4 = original.stream() + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + } + + public static Set copyByJava8(Set original) { + Set copy = Set.copyOf(original); + return copy; + } + +} From d73979fdf28ead60fffdbcd2991cbb55170cfd21 Mon Sep 17 00:00:00 2001 From: maryarm Date: Sat, 1 Jun 2019 12:15:57 +0430 Subject: [PATCH 18/63] #BAEL-2802: Implement response decoder for ok http client and apply review notes --- libraries-2/pom.xml | 27 +++ .../okhttp/ResponseDecoderUnitTest.java | 160 ++++++++++++++++++ .../com/baeldung/okhttp/SimpleEntity.java | 21 +++ 3 files changed, 208 insertions(+) create mode 100644 libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java create mode 100644 libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml index 6303c0cab5..d3c0f7204b 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -55,6 +55,33 @@ spring-boot-starter ${spring-boot-starter.version} + + + + com.squareup.okhttp3 + okhttp + 3.14.2 + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.9 + + + + com.google.code.gson + gson + 2.8.5 + + + + com.squareup.okhttp3 + mockwebserver + 3.14.2 + test + + diff --git a/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java b/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java new file mode 100644 index 0000000000..e9f829abe4 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java @@ -0,0 +1,160 @@ +package com.baeldung.okhttp; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.ResponseBody; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.InputStreamReader; + +public class ResponseDecoderUnitTest { + + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); + + @Rule + public MockWebServer server = new MockWebServer(); + + SimpleEntity sampleResponse; + + MockResponse mockResponse; + + OkHttpClient client; + + + @Before + public void setUp() { + sampleResponse = new SimpleEntity("Baeldung"); + client = new OkHttpClient.Builder() + .build(); + mockResponse = new MockResponse() + .setResponseCode(200) + .setHeader("Content-Type", "application/json") + .setBody(new Gson().toJson(sampleResponse)); + } + + @Test + public void givenJacksonDecoder_whenGetByteStreamOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + Assert.assertNotEquals(0, responseBody.contentLength()); + + ObjectMapper objectMapper = new ObjectMapper(); + SimpleEntity response = objectMapper.readValue(responseBody.byteStream() + , SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + @Test + public void givenJacksonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + Assert.assertNotEquals(0, responseBody.contentLength()); + + ObjectMapper objectMapper = new ObjectMapper(); + SimpleEntity response = objectMapper.readValue(responseBody.string(), SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + @Test + public void givenJacksonDecoder_whenGetCharStreamOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + Assert.assertNotEquals(0, responseBody.contentLength()); + + ObjectMapper objectMapper = new ObjectMapper(); + SimpleEntity response = objectMapper.readValue(responseBody.charStream(), SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + @Test + public void givenGsonDecoder_whenGetByteStreamOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + Assert.assertNotEquals(0, responseBody.contentLength()); + + Gson gson = new Gson(); + SimpleEntity response = gson.fromJson(new InputStreamReader(responseBody.byteStream()) + , SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + @Test + public void givenGsonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + + Gson gson = new Gson(); + SimpleEntity response = gson.fromJson(responseBody.string(), SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + @Test + public void givenGsonDecoder_whenGetCharStreamOfResponse_thenExpectSimpleEntity() throws Exception { + + server.enqueue(mockResponse); + + Request request = new Request.Builder() + .url(server.url("")) + .build(); + + ResponseBody responseBody = client.newCall(request).execute().body(); + + Assert.assertNotNull(responseBody); + + Gson gson = new Gson(); + SimpleEntity response = gson.fromJson(responseBody.charStream(), SimpleEntity.class); + + Assert.assertEquals(sampleResponse.getName(), response.getName()); + } + + +} diff --git a/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java b/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java new file mode 100644 index 0000000000..4c7cae6fdc --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java @@ -0,0 +1,21 @@ +package com.baeldung.okhttp; + +public class SimpleEntity { + protected String name; + + public SimpleEntity(String name) { + this.name = name; + } + + //no-arg constructor, getters and setters here + public SimpleEntity() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} From 9e0e8a6b0b51de297b344cc59364cb8251571b65 Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Sun, 2 Jun 2019 11:09:12 +0100 Subject: [PATCH 19/63] [BAEL-2899] removed exception and added dependencies needed for correct compilation --- core-groovy-2/gmavenplus-pom.xml | 18 ++++++- core-groovy-2/pom.xml | 54 +++++++++++++++---- .../{App.java => MyJointCompilationApp.java} | 25 +++++---- 3 files changed, 76 insertions(+), 21 deletions(-) rename core-groovy-2/src/main/java/com/baeldung/{App.java => MyJointCompilationApp.java} (85%) diff --git a/core-groovy-2/gmavenplus-pom.xml b/core-groovy-2/gmavenplus-pom.xml index 924dab94d1..54c89b9834 100644 --- a/core-groovy-2/gmavenplus-pom.xml +++ b/core-groovy-2/gmavenplus-pom.xml @@ -14,6 +14,16 @@ + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + ch.qos.logback + logback-classic + ${logback.version} + org.codehaus.groovy groovy-all @@ -127,7 +137,7 @@ - com.baeldung.App + com.baeldung.MyJointCompilationApp @@ -154,10 +164,14 @@ + UTF-8 1.0.0 - 2.5.7 2.4.0 1.1-groovy-2.4 + 3.9 + 1.8 + 1.2.3 + 2.5.7 1.6 diff --git a/core-groovy-2/pom.xml b/core-groovy-2/pom.xml index 0ade31acdb..b945546c8a 100644 --- a/core-groovy-2/pom.xml +++ b/core-groovy-2/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-groovy-2 1.0-SNAPSHOT @@ -14,6 +14,16 @@ + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + ch.qos.logback + logback-classic + ${logback.version} + org.codehaus.groovy groovy-all @@ -44,6 +54,12 @@ src/main/groovy src/main/java + + org.codehaus.groovy + groovy-eclipse-compiler + 3.3.0-01 + true + maven-compiler-plugin 3.8.0 @@ -94,11 +110,11 @@ maven-surefire-plugin 2.20.1 - false - - **/*Test.java - **/*Spec.java - + false + + **/*Test.java + **/*Spec.java + @@ -114,7 +130,7 @@ - com.baeldung.App + com.baeldung.MyJointCompilationApp @@ -140,12 +156,32 @@ + + + bintray + Groovy Bintray + https://dl.bintray.com/groovy/maven + + + never + + + false + + + + + 1.0.0 - 2.5.7 2.4.0 1.1-groovy-2.4 - 1.6 + 3.9 + 1.8 + 3.8.1 + 1.2.3 + 2.5.7 + UTF-8 diff --git a/core-groovy-2/src/main/java/com/baeldung/App.java b/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java similarity index 85% rename from core-groovy-2/src/main/java/com/baeldung/App.java rename to core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java index 6c92c3a0b1..2be2e195ef 100644 --- a/core-groovy-2/src/main/java/com/baeldung/App.java +++ b/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java @@ -7,31 +7,36 @@ import groovy.util.ScriptException; import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import javax.script.ScriptEngine; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; /** * Hello world! * */ -public class App { - private final static Logger LOG = LoggerFactory.getLogger(App.class); +public class MyJointCompilationApp { + private final static Logger LOG = LoggerFactory.getLogger(MyJointCompilationApp.class); private final GroovyClassLoader loader; private final GroovyShell shell; private final GroovyScriptEngine engine; private final ScriptEngine engineFromFactory; - private App() throws IOException { + public MyJointCompilationApp() { loader = new GroovyClassLoader(this.getClass().getClassLoader()); shell = new GroovyShell(loader, new Binding()); - engine = new GroovyScriptEngine(new URL[] { - new File("src/main/groovy/com/baeldung/").toURI().toURL() - }, this.getClass().getClassLoader()); + + URL url = null; + try { + url = new File("src/main/groovy/com/baeldung/").toURI().toURL(); + } catch (MalformedURLException e) { + LOG.error("Exception while creating url", e); + } + engine = new GroovyScriptEngine(new URL[] {url}, this.getClass().getClassLoader()); engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine(); } @@ -99,8 +104,8 @@ public class App { public static void main(String[] args) throws InstantiationException, IllegalAccessException, ResourceException, ScriptException, IOException, javax.script.ScriptException { - App app = new App(); - app.runStaticCompiledClasses(); - app.runDynamicCompiledClasses(); + MyJointCompilationApp myJointCompilationApp = new MyJointCompilationApp(); + myJointCompilationApp.runStaticCompiledClasses(); + myJointCompilationApp.runDynamicCompiledClasses(); } } From 3fa896b286cfa7c075a0f63fbd2f2a57577b176d Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 2 Jun 2019 23:28:11 +0530 Subject: [PATCH 20/63] [BAEL-14843] - Fixed tests in jersey module --- .../jersey/server/rest/FruitResourceIntegrationTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java index 376c8c1e75..f7bb0df1ed 100644 --- a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java +++ b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java @@ -26,6 +26,7 @@ public class FruitResourceIntegrationTest extends JerseyTest { protected Application configure() { enable(TestProperties.LOG_TRAFFIC); enable(TestProperties.DUMP_ENTITY); + forceSet(TestProperties.CONTAINER_PORT, "0"); ViewApplicationConfig config = new ViewApplicationConfig(); config.register(FruitExceptionMapper.class); From e4172539cfd9d324addc32ad7fe19ab2af9b139f Mon Sep 17 00:00:00 2001 From: Urvy Agrawal Date: Tue, 4 Jun 2019 13:28:01 +0530 Subject: [PATCH 21/63] Adding files for BAEL-2968 --- spring-boot-parent/pom.xml | 26 +++++++++++ .../spring-boot-with-custom-parent/pom.xml | 42 +++++++++++++++++ ...ingBootStarterCustomParentApplication.java | 13 ++++++ .../spring-boot-with-starter-parent/pom.xml | 46 +++++++++++++++++++ .../SpringBootStarterParentApplication.java | 14 ++++++ 5 files changed, 141 insertions(+) create mode 100644 spring-boot-parent/pom.xml create mode 100644 spring-boot-parent/spring-boot-with-custom-parent/pom.xml create mode 100644 spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java create mode 100644 spring-boot-parent/spring-boot-with-starter-parent/pom.xml create mode 100644 spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java diff --git a/spring-boot-parent/pom.xml b/spring-boot-parent/pom.xml new file mode 100644 index 0000000000..0924917505 --- /dev/null +++ b/spring-boot-parent/pom.xml @@ -0,0 +1,26 @@ + + + + 4.0.0 + com.baeldung + spring-boot-parent + 1.0.0-SNAPSHOT + spring-boot-parent + spring-boot-parent + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + .. + + + + spring-boot-with-starter-parent + spring-boot-with-custom-parent + + + diff --git a/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-parent/spring-boot-with-custom-parent/pom.xml new file mode 100644 index 0000000000..4afa302cb4 --- /dev/null +++ b/spring-boot-parent/spring-boot-with-custom-parent/pom.xml @@ -0,0 +1,42 @@ + + + + 4.0.0 + spring-boot-with-custom-parent + 1.0.0-SNAPSHOT + spring-boot-with-custom-parent + Demo project for Spring Boot + + + com.baeldung + spring-boot-parent + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + 1.8 + 2.1.5.RELEASE + + + diff --git a/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java b/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java new file mode 100644 index 0000000000..169717d7bb --- /dev/null +++ b/spring-boot-parent/spring-boot-with-custom-parent/src/main/java/com/baeldung/customparent/SpringBootStarterCustomParentApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.customparent; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootStarterCustomParentApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootStarterCustomParentApplication.class, args); + System.out.println("Spring boot application running without starter parent"); + } +} diff --git a/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-parent/spring-boot-with-starter-parent/pom.xml new file mode 100644 index 0000000000..870e051e7d --- /dev/null +++ b/spring-boot-parent/spring-boot-with-starter-parent/pom.xml @@ -0,0 +1,46 @@ + + + + 4.0.0 + com.baeldung + spring-boot-with-starter-parent + 1.0.0-SNAPSHOT + spring-boot-with-starter-parent + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.1.5.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + 2.1.1.RELEASE + + + + + + + org.springframework.boot + spring-boot-starter-web + + + junit + junit + + + + + 1.8 + 4.11 + + + diff --git a/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java b/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java new file mode 100644 index 0000000000..f987165ce0 --- /dev/null +++ b/spring-boot-parent/spring-boot-with-starter-parent/src/main/java/com/baeldung/starterparent/SpringBootStarterParentApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.starterparent; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootStarterParentApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootStarterParentApplication.class, args); + System.out.println("Spring boot application running with starter parent"); + } + +} From 15ca31cdef078bf4d4afc6e12c5ec666ad666c98 Mon Sep 17 00:00:00 2001 From: Urvy Agrawal Date: Tue, 4 Jun 2019 13:30:26 +0530 Subject: [PATCH 22/63] Added spring-boot-parent in pom.xml --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 185c0a4015..e684ffec10 100644 --- a/pom.xml +++ b/pom.xml @@ -646,6 +646,7 @@ spring-boot-ops-2 spring-boot-rest spring-boot-data + spring-boot-parent spring-boot-property-exp spring-boot-security spring-boot-testing @@ -1310,6 +1311,7 @@ spring-boot-ops-2 spring-boot-rest spring-boot-data + spring-boot-parent spring-boot-property-exp spring-boot-security spring-boot-vue From b5f136ddcdac685cfde0cd84d18a8bcb75e3fa26 Mon Sep 17 00:00:00 2001 From: Urvy Agrawal Date: Tue, 4 Jun 2019 15:04:19 +0530 Subject: [PATCH 23/63] Removed description --- spring-boot-parent/spring-boot-with-custom-parent/pom.xml | 1 - spring-boot-parent/spring-boot-with-starter-parent/pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/spring-boot-parent/spring-boot-with-custom-parent/pom.xml b/spring-boot-parent/spring-boot-with-custom-parent/pom.xml index 4afa302cb4..de2946fbb2 100644 --- a/spring-boot-parent/spring-boot-with-custom-parent/pom.xml +++ b/spring-boot-parent/spring-boot-with-custom-parent/pom.xml @@ -7,7 +7,6 @@ spring-boot-with-custom-parent 1.0.0-SNAPSHOT spring-boot-with-custom-parent - Demo project for Spring Boot com.baeldung diff --git a/spring-boot-parent/spring-boot-with-starter-parent/pom.xml b/spring-boot-parent/spring-boot-with-starter-parent/pom.xml index 870e051e7d..1c6479ca60 100644 --- a/spring-boot-parent/spring-boot-with-starter-parent/pom.xml +++ b/spring-boot-parent/spring-boot-with-starter-parent/pom.xml @@ -8,7 +8,6 @@ spring-boot-with-starter-parent 1.0.0-SNAPSHOT spring-boot-with-starter-parent - Demo project for Spring Boot org.springframework.boot From f6a9d02b3733d488b7172ded16562660d1918400 Mon Sep 17 00:00:00 2001 From: FrancoCorleone Date: Wed, 5 Jun 2019 06:31:00 +0200 Subject: [PATCH 24/63] [BAEL-2898] Working with XML in Groovy (#7083) --- .../baeldung/xml/MarkupBuilderUnitTest.groovy | 40 +++++++ .../com/baeldung/xml/XmlParserUnitTest.groovy | 94 ++++++++++++++++ .../baeldung/xml/XmlSlurperUnitTest.groovy | 102 ++++++++++++++++++ .../resources/com/baeldung/xml/articles.xml | 34 ++++++ .../baeldung/xml/articles_short_formatted.xml | 18 ++++ 5 files changed, 288 insertions(+) create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy create mode 100644 core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml create mode 100644 core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy new file mode 100644 index 0000000000..c0c8c98392 --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy @@ -0,0 +1,40 @@ +package com.baeldung.xml + +import groovy.xml.MarkupBuilder +import groovy.xml.XmlUtil +import spock.lang.Specification + +class MarkupBuilderUnitTest extends Specification { + + def xmlFile = getClass().getResource("articles_short_formatted.xml") + +def "Should create XML properly"() { + given: "Node structures" + + when: "Using MarkupBuilderUnitTest to create com.baeldung.xml structure" + def writer = new StringWriter() + new MarkupBuilder(writer).articles { + article { + title('First steps in Java') + author(id: '1') { + firstname('Siena') + lastname('Kerr') + } + 'release-date'('2018-12-01') + } + article { + title('Dockerize your SpringBoot application') + author(id: '2') { + firstname('Jonas') + lastname('Lugo') + } + 'release-date'('2018-12-01') + } + } + + then: "Xml is created properly" + XmlUtil.serialize(writer.toString()) == XmlUtil.serialize(xmlFile.text) +} + + +} diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy new file mode 100644 index 0000000000..ada47406a1 --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy @@ -0,0 +1,94 @@ +package com.baeldung.xml + + +import spock.lang.Shared +import spock.lang.Specification + +class XmlParserUnitTest extends Specification { + + def xmlFile = getClass().getResourceAsStream("articles.xml") + + @Shared + def parser = new XmlParser() + + def "Should read XML file properly"() { + given: "XML file" + + when: "Using XmlParser to read file" + def articles = parser.parse(xmlFile) + + then: "Xml is loaded properly" + articles.'*'.size() == 4 + articles.article[0].author.firstname.text() == "Siena" + articles.article[2].'release-date'.text() == "2018-06-12" + articles.article[3].title.text() == "Java 12 insights" + articles.article.find { it.author.'@id'.text() == "3" }.author.firstname.text() == "Daniele" + } + + + def "Should add node to existing com.baeldung.xml using NodeBuilder"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + def articleNode = new NodeBuilder().article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + articles.append(articleNode) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 5 + articles.article[4].title.text() == "Traversing XML in the nutshell" + } + + def "Should replace node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + def articleNode = new NodeBuilder().article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + articles.article[0].replaceNode(articleNode) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 4 + articles.article[0].title.text() == "Traversing XML in the nutshell" + } + + def "Should modify node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Changing value of one of the nodes" + articles.article.each { it.'release-date'[0].value = "2019-05-18" } + + then: "XML is updated" + articles.article.findAll { it.'release-date'.text() != "2019-05-18" }.isEmpty() + } + + def "Should remove article from com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Removing all articles but with id==3" + articles.article + .findAll { it.author.'@id'.text() != "3" } + .each { articles.remove(it) } + + then: "There is only one article left" + articles.children().size() == 1 + articles.article[0].author.'@id'.text() == "3" + } + +} diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy new file mode 100644 index 0000000000..ffeaa46fce --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy @@ -0,0 +1,102 @@ +package com.baeldung.xml + + +import groovy.xml.XmlUtil +import spock.lang.Shared +import spock.lang.Specification + +class XmlSlurperUnitTest extends Specification { + + def xmlFile = getClass().getResourceAsStream("articles.xml") + + @Shared + def parser = new XmlSlurper() + + def "Should read XML file properly"() { + given: "XML file" + + when: "Using XmlSlurper to read file" + def articles = parser.parse(xmlFile) + + then: "Xml is loaded properly" + articles.'*'.size() == 4 + articles.article[0].author.firstname == "Siena" + articles.article[2].'release-date' == "2018-06-12" + articles.article[3].title == "Java 12 insights" + articles.article.find { it.author.'@id' == "3" }.author.firstname == "Daniele" + } + + def "Should add node to existing com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + articles.appendNode { + article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + } + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 5 + articles.article[4].title == "Traversing XML in the nutshell" + } + + def "Should modify node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Changing value of one of the nodes" + articles.article.each { it.'release-date' = "2019-05-18" } + + then: "XML is updated" + articles.article.findAll { it.'release-date' != "2019-05-18" }.isEmpty() + } + + def "Should replace node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Replacing node" + articles.article[0].replaceNode { + article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + } + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "Node is replaced properly" + articles.'*'.size() == 4 + articles.article[0].title == "Traversing XML in the nutshell" + } + + def "Should remove article from com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Removing all articles but with id==3" + articles.article + .findAll { it.author.'@id' != "3" } + .replaceNode {} + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "There is only one article left" + articles.children().size() == 1 + articles.article[0].author.'@id' == "3" + } + +} diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml b/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml new file mode 100644 index 0000000000..ef057405f5 --- /dev/null +++ b/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml @@ -0,0 +1,34 @@ + +
+ First steps in Java + + Siena + Kerr + + 2018-12-01 +
+
+ Dockerize your SpringBoot application + + Jonas + Lugo + + 2018-12-01 +
+
+ SpringBoot tutorial + + Daniele + Ferguson + + 2018-06-12 +
+
+ Java 12 insights + + Siena + Kerr + + 2018-07-22 +
+
diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml b/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml new file mode 100644 index 0000000000..6492020e03 --- /dev/null +++ b/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml @@ -0,0 +1,18 @@ + +
+ First steps in Java + + Siena + Kerr + + 2018-12-01 +
+
+ Dockerize your SpringBoot application + + Jonas + Lugo + + 2018-12-01 +
+
From f97f44d024bd159cef864944f1677a2f7461e6bc Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:38:19 +0530 Subject: [PATCH 25/63] Back-link added --- persistence-modules/spring-data-jpa-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 0f5a826e05..bd259410d1 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -12,3 +12,4 @@ - [Spring Data JPA and Null Parameters](https://www.baeldung.com/spring-data-jpa-null-parameters) - [Spring Data JPA Repository Populators](https://www.baeldung.com/spring-data-jpa-repository-populators) - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) +- [Derived Query Methods in Spring Data JPA Repositories](https://www.baeldung.com/spring-data-derived-queries) From 21a2a2f2f7e1c296c5295a94b4aa834d8d3c4bdf Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:42:50 +0530 Subject: [PATCH 26/63] Back-link added --- core-java-modules/core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java/README.md b/core-java-modules/core-java/README.md index c2d1b4a06b..8c7f363d9c 100644 --- a/core-java-modules/core-java/README.md +++ b/core-java-modules/core-java/README.md @@ -51,3 +51,4 @@ - [Java Bitwise Operators](https://www.baeldung.com/java-bitwise-operators) - [Guide to Creating and Running a Jar File in Java](https://www.baeldung.com/java-create-jar) - [Making a JSON POST Request With HttpURLConnection](https://www.baeldung.com/httpurlconnection-post) +- [How to Find an Exception’s Root Cause in Java](https://www.baeldung.com/java-exception-root-cause) From 1e28dd20888169be33477f349a1be9830aba2644 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:44:40 +0530 Subject: [PATCH 27/63] Back-link added --- core-groovy-2/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-groovy-2/README.md b/core-groovy-2/README.md index f60bdb3cbe..9875713bfd 100644 --- a/core-groovy-2/README.md +++ b/core-groovy-2/README.md @@ -4,4 +4,4 @@ - [String Matching in Groovy](http://www.baeldung.com/) - [Groovy def Keyword] - +- [Template Engines in Groovy](https://www.baeldung.com/groovy-template-engines) From e17b4121fe951d76c9d4dd995d0bcce231a48fff Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:46:48 +0530 Subject: [PATCH 28/63] Back-link added --- core-java-modules/core-java-arrays/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-arrays/README.md b/core-java-modules/core-java-arrays/README.md index ed8221ebe4..b5f71cc253 100644 --- a/core-java-modules/core-java-arrays/README.md +++ b/core-java-modules/core-java-arrays/README.md @@ -15,3 +15,4 @@ - [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection) - [Sorting Arrays in Java](https://www.baeldung.com/java-sorting-arrays) - [Convert a Float to a Byte Array in Java](https://www.baeldung.com/java-convert-float-to-byte-array) +- [Converting Between Stream and Array in Java](https://www.baeldung.com/java-stream-to-array) From afbdb59b23db77f6c25d4188ff9a5dcae0e0e6ea Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 15:57:46 +0530 Subject: [PATCH 29/63] Back-link added --- kotlin-libraries-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/kotlin-libraries-2/README.md b/kotlin-libraries-2/README.md index fdb7c2830d..0b9f238d51 100644 --- a/kotlin-libraries-2/README.md +++ b/kotlin-libraries-2/README.md @@ -1,3 +1,4 @@ ## Relevant articles: - [Jackson Support for Kotlin](https://www.baeldung.com/jackson-kotlin) +- [Introduction to RxKotlin](https://www.baeldung.com/rxkotlin) From ad31a62f3e0c2c3e98ae72a4432823f86c32cba3 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:00:27 +0530 Subject: [PATCH 30/63] Back-link added --- jee-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jee-7/README.md b/jee-7/README.md index a783e7860e..c57863651d 100644 --- a/jee-7/README.md +++ b/jee-7/README.md @@ -6,3 +6,4 @@ - [A Guide to Java EE Web-Related Annotations](http://www.baeldung.com/javaee-web-annotations) - [Introduction to Testing with Arquillian](http://www.baeldung.com/arquillian) - [Java EE 7 Batch Processing](https://www.baeldung.com/java-ee-7-batch-processing) +- [The Difference Between CDI and EJB Singleton](https://www.baeldung.com/jee-cdi-vs-ejb-singleton) From 38ba51c59763c823b4198a97b4045e5d567f427d Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:02:28 +0530 Subject: [PATCH 31/63] Back-link added --- core-java-modules/core-java-8-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-2/README.md b/core-java-modules/core-java-8-2/README.md index e2b12e8819..3c8e876cf0 100644 --- a/core-java-modules/core-java-8-2/README.md +++ b/core-java-modules/core-java-8-2/README.md @@ -4,3 +4,4 @@ ### Relevant Articles: - [Anonymous Classes in Java](http://www.baeldung.com/) +- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution) From 1456df016214e3aefb328be37ee6247208285e50 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:04:41 +0530 Subject: [PATCH 32/63] Back-link added --- core-java-modules/core-java-11/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-11/README.md b/core-java-modules/core-java-11/README.md index a4b0e0e59c..738bf487b8 100644 --- a/core-java-modules/core-java-11/README.md +++ b/core-java-modules/core-java-11/README.md @@ -7,3 +7,4 @@ - [Exploring the New HTTP Client in Java 9 and 11](https://www.baeldung.com/java-9-http-client) - [An Introduction to Epsilon GC: A No-Op Experimental Garbage Collector](https://www.baeldung.com/jvm-epsilon-gc-garbage-collector) - [Guide to jlink](https://www.baeldung.com/jlink) +- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference) From 00092aeedeeebf4f8edca9dff2e65f84983a106d Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:06:35 +0530 Subject: [PATCH 33/63] Back-link added --- core-java-modules/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/README.md b/core-java-modules/README.md index a90535a44f..782d13238b 100644 --- a/core-java-modules/README.md +++ b/core-java-modules/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) +- [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel) From c262c1ac353b254a3a008e47d4e097e6c4aac70d Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:08:26 +0530 Subject: [PATCH 34/63] Back-link added --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index ba4d9f0410..14d4d95749 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -8,3 +8,4 @@ - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) - [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates) - [Types of JPA Queries](https://www.baeldung.com/jpa-queries) +- [JPA/Hibernate Projections](https://www.baeldung.com/jpa-hibernate-projections) From b922b3b313b789e6ff603db053425a935d69823d Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:09:59 +0530 Subject: [PATCH 35/63] Back-link added --- spring-boot-ops-2/README.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-boot-ops-2/README.MD b/spring-boot-ops-2/README.MD index 20b30515fb..b4218dc395 100644 --- a/spring-boot-ops-2/README.MD +++ b/spring-boot-ops-2/README.MD @@ -1,3 +1,4 @@ ### Relevant Articles -- [How to Configure Spring Boot Tomcat](https://www.baeldung.com/spring-boot-configure-tomcat) \ No newline at end of file +- [How to Configure Spring Boot Tomcat](https://www.baeldung.com/spring-boot-configure-tomcat) +- [Spring Boot Embedded Tomcat Logs](https://www.baeldung.com/spring-boot-embedded-tomcat-logs) From f94d291df9b45e715e9f4e954fb981d43e6665c5 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:12:11 +0530 Subject: [PATCH 36/63] Back-link added --- spring-5-webflux/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-5-webflux/README.md b/spring-5-webflux/README.md index e84ee863bf..87d9ae0dd3 100644 --- a/spring-5-webflux/README.md +++ b/spring-5-webflux/README.md @@ -3,3 +3,4 @@ - [Spring Boot Reactor Netty Configuration](https://www.baeldung.com/spring-boot-reactor-netty) - [How to Return 404 with Spring WebFlux](https://www.baeldung.com/spring-webflux-404) - [Spring WebClient Requests with Parameters](https://www.baeldung.com/webflux-webclient-parameters) +- [RSocket Using Spring Boot](https://www.baeldung.com/spring-boot-rsocket) From 22dcba2d560ebad84282e43e1ef7fe3ea01e3d66 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:16:23 +0530 Subject: [PATCH 37/63] Back-link added --- core-java-modules/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/README.md b/core-java-modules/README.md index 782d13238b..7a7d0a7a1b 100644 --- a/core-java-modules/README.md +++ b/core-java-modules/README.md @@ -2,3 +2,4 @@ - [Multi-Module Maven Application with Java Modules](https://www.baeldung.com/maven-multi-module-project-java-jpms) - [Guide to Java FileChannel](https://www.baeldung.com/java-filechannel) +- [Understanding the NumberFormatException in Java](https://www.baeldung.com/java-number-format-exception) From e73e9b98ad17e3f10a5c83f0ae9718d197ac1d54 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:17:51 +0530 Subject: [PATCH 38/63] Back-link added --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 14d4d95749..35e3514c51 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -9,3 +9,4 @@ - [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates) - [Types of JPA Queries](https://www.baeldung.com/jpa-queries) - [JPA/Hibernate Projections](https://www.baeldung.com/jpa-hibernate-projections) +- [Composite Primary Keys in JPA](https://www.baeldung.com/jpa-composite-primary-keys) From 55ad52dac877f570e7f8ef4a2a5a5607d733ca91 Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:19:29 +0530 Subject: [PATCH 39/63] Back-link added --- jersey/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jersey/README.md b/jersey/README.md index 1dd871b3e8..126dc542ba 100644 --- a/jersey/README.md +++ b/jersey/README.md @@ -3,3 +3,4 @@ - [Bean Validation in Jersey](https://www.baeldung.com/jersey-bean-validation) - [Set a Response Body in JAX-RS](https://www.baeldung.com/jax-rs-response) - [Exploring the Jersey Test Framework](https://www.baeldung.com/jersey-test) +- [Explore Jersey Request Parameters](https://www.baeldung.com/jersey-request-parameters) From 9feca145f8960d6ed135b762643d28503b425aca Mon Sep 17 00:00:00 2001 From: collaboratewithakash <38683470+collaboratewithakash@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:20:54 +0530 Subject: [PATCH 40/63] Back-link added --- ddd/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ddd/README.md b/ddd/README.md index 60f3a43086..3f3b91380f 100644 --- a/ddd/README.md +++ b/ddd/README.md @@ -1,3 +1,4 @@ ### Relevant articles - [Persisting DDD Aggregates](https://www.baeldung.com/spring-persisting-ddd-aggregates) +- [Double Dispatch in DDD](https://www.baeldung.com/ddd-double-dispatch) From 244ebb1ad131e7cfa35553eba8e891732488b3b1 Mon Sep 17 00:00:00 2001 From: Alessio Stalla Date: Wed, 5 Jun 2019 22:16:47 +0200 Subject: [PATCH 41/63] Code for BAEL-2967 --- persistence-modules/hibernate-mapping/pom.xml | 11 + .../hibernate/persistmaps/mapkey/User.java | 24 +- .../UserAdditionalValidationUnitTest.java | 294 +++++++++++++++--- pom.xml | 1 + 4 files changed, 270 insertions(+), 60 deletions(-) diff --git a/persistence-modules/hibernate-mapping/pom.xml b/persistence-modules/hibernate-mapping/pom.xml index 67eda5bf72..bb8ebdab65 100644 --- a/persistence-modules/hibernate-mapping/pom.xml +++ b/persistence-modules/hibernate-mapping/pom.xml @@ -42,6 +42,17 @@ javax.el ${org.glassfish.javax.el.version} + + javax.money + money-api + 1.0.3 + + + org.javamoney + moneta + 1.3 + pom + diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java index 961fc944a4..b2ee7e85fe 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/persistmaps/mapkey/User.java @@ -4,9 +4,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.validation.constraints.Size; +import javax.money.MonetaryAmount; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.CreditCardNumber; +import org.hibernate.validator.constraints.Currency; @Entity public class User { @@ -24,12 +26,6 @@ public class User { @Size(min = 3, max = 5) private String city; - @CreditCardNumber - private String creditCardNumber; - - @CreditCardNumber(ignoreNonDigitCharacters = true) - private String lenientCreditCardNumber; - public User(String firstName, String middleName, String lastName, String city) { super(); this.firstName = firstName; @@ -69,20 +65,4 @@ public class User { public void setCity(String city) { this.city = city; } - - public String getCreditCardNumber() { - return creditCardNumber; - } - - public void setCreditCardNumber(String creditCardNumber) { - this.creditCardNumber = creditCardNumber; - } - - public String getLenientCreditCardNumber() { - return lenientCreditCardNumber; - } - - public void setLenientCreditCardNumber(String lenientCreditCardNumber) { - this.lenientCreditCardNumber = lenientCreditCardNumber; - } } diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java index aaf52fe765..0f2a0403e9 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/validation/UserAdditionalValidationUnitTest.java @@ -1,72 +1,290 @@ package com.baeldung.hibernate.validation; -import com.baeldung.hibernate.HibernateUtil; -import com.baeldung.hibernate.Strategy; -import com.baeldung.hibernate.persistmaps.mapkey.User; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import javax.persistence.PersistenceException; -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import java.util.Set; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.math.BigDecimal; +import java.time.Duration; +import java.util.Set; + +import javax.money.CurrencyContextBuilder; +import javax.money.Monetary; +import javax.money.MonetaryAmount; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.hibernate.validator.constraints.CodePointLength; +import org.hibernate.validator.constraints.CreditCardNumber; +import org.hibernate.validator.constraints.Currency; +import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.LuhnCheck; +import org.hibernate.validator.constraints.Range; +import org.hibernate.validator.constraints.SafeHtml; +import org.hibernate.validator.constraints.ScriptAssert; +import org.hibernate.validator.constraints.URL; +import org.hibernate.validator.constraints.time.DurationMax; +import org.hibernate.validator.constraints.time.DurationMin; +import org.javamoney.moneta.CurrencyUnitBuilder; +import org.javamoney.moneta.Money; +import org.junit.BeforeClass; +import org.junit.Test; + public class UserAdditionalValidationUnitTest { private static Validator validator; - private static SessionFactory sessionFactory; - private Session session; - private Set> constraintViolations; + private Set> constraintViolations; @BeforeClass public static void before() { ValidatorFactory config = Validation.buildDefaultValidatorFactory(); validator = config.getValidator(); - sessionFactory = HibernateUtil.getSessionFactory(Strategy.MAP_KEY_BASED); - } - - @Before - public void setUp() { - session = sessionFactory.openSession(); - session.beginTransaction(); } @Test public void whenValidationWithCCNAndNullCCN_thenNoConstraintViolation() { - User user = new User("John", "Paul", "Butler", "York"); - constraintViolations = validator.validateProperty(user, "creditCardNumber"); + AdditionalValidations validations = new AdditionalValidations(); + constraintViolations = validator.validateProperty(validations, "creditCardNumber"); assertTrue(constraintViolations.isEmpty()); } @Test public void whenValidationWithCCNAndValidCCN_thenNoConstraintViolation() { - User user = new User("John", "Paul", "Butler", "York"); - user.setCreditCardNumber("79927398713"); - constraintViolations = validator.validateProperty(user, "creditCardNumber"); + AdditionalValidations validations = new AdditionalValidations(); + validations.setCreditCardNumber("79927398713"); + constraintViolations = validator.validateProperty(validations, "creditCardNumber"); assertTrue(constraintViolations.isEmpty()); } @Test public void whenValidationWithCCNAndInvalidCCN_thenConstraintViolation() { - User user = new User("John", "Paul", "Butler", "York"); - user.setCreditCardNumber("79927398714"); - constraintViolations = validator.validateProperty(user, "creditCardNumber"); - assertEquals(constraintViolations.size(), 1); + AdditionalValidations validations = new AdditionalValidations(); + validations.setCreditCardNumber("79927398714"); + constraintViolations = validator.validateProperty(validations, "creditCardNumber"); + assertEquals(constraintViolations.size(), 2); + } + + @Test + public void whenValidationWithCCNAndValidCCNWithDashes_thenConstraintViolation() { + AdditionalValidations validations = new AdditionalValidations(); + validations.setCreditCardNumber("7992-7398-713"); + constraintViolations = validator.validateProperty(validations, "creditCardNumber"); + assertEquals(1, constraintViolations.size()); } @Test public void whenValidationWithLenientCCNAndValidCCNWithDashes_thenNoConstraintViolation() { - User user = new User("John", "Paul", "Butler", "York"); - user.setLenientCreditCardNumber("7992-7398-713"); - constraintViolations = validator.validateProperty(user, "lenientCreditCardNumber"); + AdditionalValidations validations = new AdditionalValidations(); + validations.setLenientCreditCardNumber("7992-7398-713"); + constraintViolations = validator.validateProperty(validations, "lenientCreditCardNumber"); assertTrue(constraintViolations.isEmpty()); } + + @Test + public void whenMonetaryAmountWithRightCurrency_thenNoConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setBalance(Money.of(new BigDecimal(100.0), Monetary.getCurrency("EUR"))); + constraintViolations = validator.validateProperty(bean, "balance"); + assertEquals(0, constraintViolations.size()); + } + + @Test + public void whenMonetaryAmountWithWrongCurrency_thenConstraintViolation() { + AdditionalValidations validations = new AdditionalValidations(); + validations.setBalance(Money.of(new BigDecimal(100.0), Monetary.getCurrency("USD"))); + constraintViolations = validator.validateProperty(validations, "balance"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenDurationShorterThanMin_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setDuration(Duration.ofDays(1).plusHours(1)); + constraintViolations = validator.validateProperty(bean, "duration"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenDurationLongerThanMax_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setDuration(Duration.ofDays(2).plusHours(3)); + constraintViolations = validator.validateProperty(bean, "duration"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenDurationBetweenMinAndMax_thenNoConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setDuration(Duration.ofDays(2)); + constraintViolations = validator.validateProperty(bean, "duration"); + assertEquals(0, constraintViolations.size()); + } + + @Test + public void whenValueBelowRangeMin_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setPercent(new BigDecimal("-1.4")); + constraintViolations = validator.validateProperty(bean, "percent"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenValueAboveRangeMax_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setPercent(new BigDecimal("100.03")); + constraintViolations = validator.validateProperty(bean, "percent"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenValueInRange_thenNoConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setPercent(new BigDecimal("53.23")); + constraintViolations = validator.validateProperty(bean, "percent"); + assertEquals(0, constraintViolations.size()); + } + + @Test + public void whenLengthInRange_thenNoConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setSomeString("aaa"); + constraintViolations = validator.validateProperty(bean, "someString"); + assertEquals(0, constraintViolations.size()); + } + + @Test + public void whenCodePointLengthNotInRange_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + bean.setSomeString("aa\uD835\uDD0A"); + constraintViolations = validator.validateProperty(bean, "someString"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenValidUrlWithWrongProtocol_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + + bean.setUrl("https://www.google.com/"); + constraintViolations = validator.validateProperty(bean, "url"); + assertEquals(0, constraintViolations.size()); + + bean.setUrl("http://www.google.com/"); + constraintViolations = validator.validateProperty(bean, "url"); + assertEquals(1, constraintViolations.size()); + + bean.setUrl("https://foo:bar"); + constraintViolations = validator.validateProperty(bean, "url"); + assertEquals(1, constraintViolations.size()); + } + + @Test + public void whenScriptAssertFails_thenConstraintViolation() { + AdditionalValidations bean = new AdditionalValidations(); + + constraintViolations = validator.validate(bean); + assertEquals(0, constraintViolations.size()); + + bean.setValid(false); + + constraintViolations = validator.validate(bean); + assertEquals(1, constraintViolations.size()); + + constraintViolations = validator.validateProperty(bean, "valid"); + assertEquals(0, constraintViolations.size()); + } + + @ScriptAssert(lang = "nashorn", script = "_this.valid") + public class AdditionalValidations { + private boolean valid = true; + + @CreditCardNumber + @LuhnCheck(startIndex = 0, endIndex = Integer.MAX_VALUE, checkDigitIndex = -1) + private String creditCardNumber; + + @CreditCardNumber(ignoreNonDigitCharacters = true) + private String lenientCreditCardNumber; + + @Currency("EUR") + private MonetaryAmount balance; + + @DurationMin(days = 1, hours = 2) + @DurationMax(days = 2, hours = 1) + private Duration duration; + + @Range(min = 0, max = 100) + private BigDecimal percent; + + @Length(min = 1, max = 3) + @CodePointLength(min = 1, max = 3) + private String someString; + + @URL(protocol = "https") + private String url; + + public String getCreditCardNumber() { + return creditCardNumber; + } + + public void setCreditCardNumber(String creditCardNumber) { + this.creditCardNumber = creditCardNumber; + } + + public String getLenientCreditCardNumber() { + return lenientCreditCardNumber; + } + + public void setLenientCreditCardNumber(String lenientCreditCardNumber) { + this.lenientCreditCardNumber = lenientCreditCardNumber; + } + + public MonetaryAmount getBalance() { + return balance; + } + + public void setBalance(MonetaryAmount balance) { + this.balance = balance; + } + + public Duration getDuration() { + return duration; + } + + public void setDuration(Duration duration) { + this.duration = duration; + } + + public BigDecimal getPercent() { + return percent; + } + + public void setPercent(BigDecimal percent) { + this.percent = percent; + } + + public String getSomeString() { + return someString; + } + + public void setSomeString(String someString) { + this.someString = someString; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public boolean isValid() { + return valid; + } + + public void setValid(boolean valid) { + this.valid = valid; + } + + } } diff --git a/pom.xml b/pom.xml index 03d2e5d763..b9f9f636d3 100644 --- a/pom.xml +++ b/pom.xml @@ -921,6 +921,7 @@ spring-vault spring-vertx spring-zuul/spring-zuul-foos-resource + persistence-modules/hibernate-mapping persistence-modules/spring-data-dynamodb persistence-modules/spring-data-eclipselink persistence-modules/spring-data-solr From cf68c5c771fdc3a8d7ec057857ab83749e61f3ee Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 6 Jun 2019 14:46:56 +0200 Subject: [PATCH 42/63] upgrade spring security cloud --- .../spring-cloud-security/auth-client/pom.xml | 16 ++++++++++------ .../src/main/resources/application.properties | 0 .../src/main/resources/application.yml | 4 +++- .../spring-cloud-security/auth-resource/pom.xml | 8 +++++--- .../com/baeldung/config/ResourceConfigurer.java | 11 +++++++---- .../src/main/resources/application.yml | 1 - .../spring-cloud-security/auth-server/pom.xml | 2 +- .../baeldung/config/AuthServerConfigurer.java | 12 +++++++----- .../{WebMvcConfigurer.java => WebMvcConfig.java} | 4 ++-- .../baeldung/config/WebSecurityConfigurer.java | 8 ++++++-- .../src/main/resources/application.yml | 12 +++--------- spring-cloud/spring-cloud-security/pom.xml | 4 ++-- 12 files changed, 46 insertions(+), 36 deletions(-) delete mode 100644 spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.properties rename spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/{WebMvcConfigurer.java => WebMvcConfig.java} (83%) diff --git a/spring-cloud/spring-cloud-security/auth-client/pom.xml b/spring-cloud/spring-cloud-security/auth-client/pom.xml index 4f64f470f0..4152552640 100644 --- a/spring-cloud/spring-cloud-security/auth-client/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-client/pom.xml @@ -24,7 +24,7 @@ org.springframework.cloud - spring-cloud-starter-zuul + spring-cloud-starter-netflix-zuul org.springframework.boot @@ -34,14 +34,16 @@ org.webjars jquery + ${jquery.version} org.webjars bootstrap + ${bootstrap.version} org.webjars - webjars-locator + webjars-locator-core org.springframework.boot @@ -62,8 +64,8 @@ spring-boot-starter-thymeleaf - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure @@ -89,8 +91,10 @@ - 2.1.0 - Dalston.SR4 + 2.2.0 + Greenwich.SR1 + 3.4.1 + 4.3.1 diff --git a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.properties b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml index 2a758faeae..69617555d9 100644 --- a/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-security/auth-client/src/main/resources/application.yml @@ -2,7 +2,8 @@ # These are default settings, but we add them for clarity. server: port: 8080 - contextPath: / + servlet: + context-path: / # Configure the Authorization Server and User Info Resource Server details security: @@ -21,6 +22,7 @@ person: # Proxies the calls to http://localhost:8080/api/* to our REST service at http://localhost:8081/* # and automatically includes our OAuth2 token in the request headers zuul: + sensitiveHeaders: Cookie,Set-Cookie routes: resource: path: /api/** diff --git a/spring-cloud/spring-cloud-security/auth-resource/pom.xml b/spring-cloud/spring-cloud-security/auth-resource/pom.xml index 22ee0528c3..a60eca740c 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-resource/pom.xml @@ -19,8 +19,8 @@ spring-boot-starter-web - org.springframework.security.oauth - spring-security-oauth2 + org.springframework.security.oauth.boot + spring-security-oauth2-autoconfigure org.springframework.boot @@ -30,6 +30,7 @@ org.springframework.security spring-security-jwt + ${spring-jwt.version} @@ -55,7 +56,8 @@ - Edgware.RELEASE + Greenwich.SR1 + 1.0.10.RELEASE diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java index 977d74093a..abe942325f 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java +++ b/spring-cloud/spring-cloud-security/auth-resource/src/main/java/com/baeldung/config/ResourceConfigurer.java @@ -3,7 +3,7 @@ package com.baeldung.config; import org.springframework.context.annotation.Configuration; 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.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; @@ -11,15 +11,18 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.R * REST API Resource Server. */ @Configuration -@EnableWebSecurity @EnableResourceServer @EnableGlobalMethodSecurity(prePostEnabled = true) // Allow method annotations like @PreAuthorize public class ResourceConfigurer extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { - http.httpBasic().disable(); - http.authorizeRequests().anyRequest().authenticated(); + http.sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.NEVER) + .and() + .authorizeRequests() + .anyRequest().authenticated(); + } } diff --git a/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml index 52e02ba41b..35063a7879 100644 --- a/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-security/auth-resource/src/main/resources/application.yml @@ -5,7 +5,6 @@ server: # Configure the public key to use for verifying the incoming JWT tokens security: - sessions: NEVER oauth2: resource: jwt: diff --git a/spring-cloud/spring-cloud-security/auth-server/pom.xml b/spring-cloud/spring-cloud-security/auth-server/pom.xml index 4b3f94b825..afd8dbef44 100644 --- a/spring-cloud/spring-cloud-security/auth-server/pom.xml +++ b/spring-cloud/spring-cloud-security/auth-server/pom.xml @@ -38,7 +38,7 @@ - 1.1.2.RELEASE + 2.1.2.RELEASE \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java index 32e445f998..7c9ee9ae18 100644 --- a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java +++ b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/AuthServerConfigurer.java @@ -9,6 +9,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.core.io.Resource; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @@ -19,9 +20,7 @@ import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFacto @Configuration @EnableAuthorizationServer @Order(6) -public class AuthServerConfigurer - extends - AuthorizationServerConfigurerAdapter { +public class AuthServerConfigurer extends AuthorizationServerConfigurerAdapter { @Value("${jwt.certificate.store.file}") private Resource keystore; @@ -37,6 +36,9 @@ public class AuthServerConfigurer @Autowired private UserDetailsService userDetailsService; + + @Autowired + private BCryptPasswordEncoder passwordEncoder; @Override public void configure( @@ -45,8 +47,8 @@ public class AuthServerConfigurer clients .inMemory() .withClient("authserver") - .secret("passwordforauthserver") - .redirectUris("http://localhost:8080/") + .secret(passwordEncoder.encode("passwordforauthserver")) + .redirectUris("http://localhost:8080/login") .authorizedGrantTypes("authorization_code", "refresh_token") .scopes("myscope") diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfig.java similarity index 83% rename from spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfigurer.java rename to spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfig.java index 23b56151e7..3cefd323b3 100644 --- a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfigurer.java +++ b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebMvcConfig.java @@ -2,10 +2,10 @@ package com.baeldung.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -public class WebMvcConfigurer extends WebMvcConfigurerAdapter { +public class WebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java index 44406b8fa0..6a48c62097 100644 --- a/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java +++ b/spring-cloud/spring-cloud-security/auth-server/src/main/java/com/baeldung/config/WebSecurityConfigurer.java @@ -6,8 +6,8 @@ import org.springframework.security.config.annotation.authentication.builders.Au import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; @Configuration @@ -34,7 +34,7 @@ public class WebSecurityConfigurer AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() - .withUser("user").password("user") + .withUser("user").password(passwordEncoder().encode("user")) .roles("USER") .and() .withUser("admin").password("admin") @@ -48,5 +48,9 @@ public class WebSecurityConfigurer return super.userDetailsServiceBean(); } + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml index 1dc63d3f0e..b6e385e5c7 100644 --- a/spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml +++ b/spring-cloud/spring-cloud-security/auth-server/src/main/resources/application.yml @@ -1,7 +1,8 @@ # Make the application available at http://localhost:7070/authserver server: port: 7070 - contextPath: /authserver + servlet: + context-path: /authserver # Our certificate settings for enabling JWT tokens jwt: @@ -11,11 +12,4 @@ jwt: password: abirkhan04 key: alias: myauthkey - password: abirkhan04 - - -security: - oauth2: - resource: - filter-order: 3 - \ No newline at end of file + password: abirkhan04 \ No newline at end of file diff --git a/spring-cloud/spring-cloud-security/pom.xml b/spring-cloud/spring-cloud-security/pom.xml index 2eecf579a5..d65fd6520b 100644 --- a/spring-cloud/spring-cloud-security/pom.xml +++ b/spring-cloud/spring-cloud-security/pom.xml @@ -8,10 +8,10 @@ pom - parent-boot-1 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-1 + ../../parent-boot-2 From 054c56451177a2a441c7bed225e56677cab84259 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 6 Jun 2019 21:05:34 +0530 Subject: [PATCH 43/63] [BAEL-14848] - Fixed tests in spring-data-redis module --- persistence-modules/spring-data-redis/pom.xml | 15 ++++++++++ .../RedisKeyCommandsIntegrationTest.java | 21 +++++++++++++ .../RedisTemplateListOpsIntegrationTest.java | 21 +++++++++++++ .../RedisTemplateValueOpsIntegrationTest.java | 30 ++++++++++++++++--- .../RedisMessageListenerIntegrationTest.java | 6 ++-- .../StudentRepositoryIntegrationTest.java | 6 ++-- 6 files changed, 91 insertions(+), 8 deletions(-) diff --git a/persistence-modules/spring-data-redis/pom.xml b/persistence-modules/spring-data-redis/pom.xml index fb80b0413f..4ae8ac0a87 100644 --- a/persistence-modules/spring-data-redis/pom.xml +++ b/persistence-modules/spring-data-redis/pom.xml @@ -79,6 +79,21 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + true + true + -Xmx1024m + + + + + 3.2.4 2.9.0 diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java index e48aa1e06a..1333f94653 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisKeyCommandsIntegrationTest.java @@ -2,6 +2,9 @@ package com.baeldung.spring.data.reactive.redis.template; import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; + +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -9,22 +12,40 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.connection.ReactiveKeyCommands; import org.springframework.data.redis.connection.ReactiveStringCommands; import org.springframework.data.redis.connection.ReactiveStringCommands.SetCommand; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.junit4.SpringRunner; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import redis.embedded.RedisServerBuilder; +import java.io.IOException; import java.nio.ByteBuffer; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class RedisKeyCommandsIntegrationTest { + + private static redis.embedded.RedisServer redisServer; @Autowired private ReactiveKeyCommands keyCommands; @Autowired private ReactiveStringCommands stringCommands; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServerBuilder().port(6379).setting("maxheap 256M").build(); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Test public void givenFluxOfKeys_whenPerformOperations_thenPerformOperations() { diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java index 3ebeff87b1..88c4fa6eed 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateListOpsIntegrationTest.java @@ -2,27 +2,48 @@ package com.baeldung.spring.data.reactive.redis.template; import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; + +import java.io.IOException; + +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.ReactiveListOperations; import org.springframework.data.redis.core.ReactiveRedisTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.junit4.SpringRunner; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import redis.embedded.RedisServerBuilder; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class RedisTemplateListOpsIntegrationTest { private static final String LIST_NAME = "demo_list"; + private static redis.embedded.RedisServer redisServer; @Autowired private ReactiveRedisTemplate redisTemplate; private ReactiveListOperations reactiveListOps; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServerBuilder().port(6379).setting("maxheap 128M").build(); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Before public void setup() { diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java index 9490568089..afa5267582 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/reactive/redis/template/RedisTemplateValueOpsIntegrationTest.java @@ -1,29 +1,51 @@ package com.baeldung.spring.data.reactive.redis.template; -import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; -import com.baeldung.spring.data.reactive.redis.model.Employee; +import java.io.IOException; +import java.time.Duration; + +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.core.ReactiveValueOperations; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.spring.data.reactive.redis.SpringRedisReactiveApplication; +import com.baeldung.spring.data.reactive.redis.model.Employee; + import reactor.core.publisher.Mono; import reactor.test.StepVerifier; - -import java.time.Duration; +import redis.embedded.RedisServerBuilder; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringRedisReactiveApplication.class) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class RedisTemplateValueOpsIntegrationTest { + + private static redis.embedded.RedisServer redisServer; @Autowired private ReactiveRedisTemplate redisTemplate; private ReactiveValueOperations reactiveValueOps; + + @BeforeClass + public static void startRedisServer() throws IOException { + redisServer = new RedisServerBuilder().port(6379).setting("maxheap 256M").build(); + redisServer.start(); + } + + @AfterClass + public static void stopRedisServer() throws IOException { + redisServer.stop(); + } @Before public void setup() { diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java index 99febb6430..1c69b63c09 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/RedisMessageListenerIntegrationTest.java @@ -19,9 +19,11 @@ import com.baeldung.spring.data.redis.config.RedisConfig; import com.baeldung.spring.data.redis.queue.RedisMessagePublisher; import com.baeldung.spring.data.redis.queue.RedisMessageSubscriber; +import redis.embedded.RedisServerBuilder; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class RedisMessageListenerIntegrationTest { private static redis.embedded.RedisServer redisServer; @@ -31,7 +33,7 @@ public class RedisMessageListenerIntegrationTest { @BeforeClass public static void startRedisServer() throws IOException { - redisServer = new redis.embedded.RedisServer(6380); + redisServer = new RedisServerBuilder().port(6379).setting("maxheap 256M").build(); redisServer.start(); } diff --git a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java index 43aadefc01..b1a36475c3 100644 --- a/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-redis/src/test/java/com/baeldung/spring/data/redis/repo/StudentRepositoryIntegrationTest.java @@ -20,9 +20,11 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.baeldung.spring.data.redis.config.RedisConfig; import com.baeldung.spring.data.redis.model.Student; +import redis.embedded.RedisServerBuilder; + @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = RedisConfig.class) -@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +@DirtiesContext(classMode = ClassMode.BEFORE_CLASS) public class StudentRepositoryIntegrationTest { @Autowired @@ -32,7 +34,7 @@ public class StudentRepositoryIntegrationTest { @BeforeClass public static void startRedisServer() throws IOException { - redisServer = new redis.embedded.RedisServer(6380); + redisServer = new RedisServerBuilder().port(6379).setting("maxheap 128M").build(); redisServer.start(); } From 0ece18c76608bc841e5b9ad969d94f8c3e7c5bb6 Mon Sep 17 00:00:00 2001 From: Amy DeGregorio Date: Fri, 7 Jun 2019 07:54:00 -0400 Subject: [PATCH 44/63] Bael 2979 Guide to Crawler4j (#7071) * BAEL-2727 Example Code * BAEL-2979 Guide to Crawler4j * BAEL-2979 adjust based on feedback --- libraries-2/pom.xml | 6 +++ .../baeldung/crawler4j/CrawlerStatistics.java | 22 ++++++++ .../com/baeldung/crawler4j/HtmlCrawler.java | 48 +++++++++++++++++ .../crawler4j/HtmlCrawlerController.java | 36 +++++++++++++ .../com/baeldung/crawler4j/ImageCrawler.java | 49 +++++++++++++++++ .../crawler4j/ImageCrawlerController.java | 36 +++++++++++++ .../crawler4j/MultipleCrawlerController.java | 54 +++++++++++++++++++ 7 files changed, 251 insertions(+) create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/CrawlerStatistics.java create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawler.java create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawlerController.java create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawler.java create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawlerController.java create mode 100644 libraries-2/src/main/java/com/baeldung/crawler4j/MultipleCrawlerController.java diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml index 6303c0cab5..218bb437cb 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -55,6 +55,11 @@ spring-boot-starter ${spring-boot-starter.version} + + edu.uci.ics + crawler4j + ${crawler4j.version} + @@ -62,6 +67,7 @@ 4.8.28 6.0.0.Final 3.9.6 + 4.4.0 2.1.4.RELEASE diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/CrawlerStatistics.java b/libraries-2/src/main/java/com/baeldung/crawler4j/CrawlerStatistics.java new file mode 100644 index 0000000000..e3237a2755 --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/CrawlerStatistics.java @@ -0,0 +1,22 @@ +package com.baeldung.crawler4j; + +public class CrawlerStatistics { + private int processedPageCount = 0; + private int totalLinksCount = 0; + + public void incrementProcessedPageCount() { + processedPageCount++; + } + + public void incrementTotalLinksCount(int linksCount) { + totalLinksCount += linksCount; + } + + public int getProcessedPageCount() { + return processedPageCount; + } + + public int getTotalLinksCount() { + return totalLinksCount; + } +} diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawler.java b/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawler.java new file mode 100644 index 0000000000..b77e1e075f --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawler.java @@ -0,0 +1,48 @@ +package com.baeldung.crawler4j; + +import java.util.Set; +import java.util.regex.Pattern; + +import edu.uci.ics.crawler4j.crawler.Page; +import edu.uci.ics.crawler4j.crawler.WebCrawler; +import edu.uci.ics.crawler4j.parser.HtmlParseData; +import edu.uci.ics.crawler4j.url.WebURL; + +public class HtmlCrawler extends WebCrawler { + + private final static Pattern EXCLUSIONS = Pattern.compile(".*(\\.(css|js|xml|gif|jpg|png|mp3|mp4|zip|gz|pdf))$"); + + private CrawlerStatistics stats; + + public HtmlCrawler(CrawlerStatistics stats) { + this.stats = stats; + } + + @Override + public boolean shouldVisit(Page referringPage, WebURL url) { + String urlString = url.getURL().toLowerCase(); + return !EXCLUSIONS.matcher(urlString).matches() + && urlString.startsWith("https://www.baeldung.com/"); + } + + @Override + public void visit(Page page) { + String url = page.getWebURL().getURL(); + stats.incrementProcessedPageCount(); + + if (page.getParseData() instanceof HtmlParseData) { + HtmlParseData htmlParseData = (HtmlParseData) page.getParseData(); + String title = htmlParseData.getTitle(); + String text = htmlParseData.getText(); + String html = htmlParseData.getHtml(); + Set links = htmlParseData.getOutgoingUrls(); + stats.incrementTotalLinksCount(links.size()); + + System.out.printf("Page with title '%s' %n", title); + System.out.printf(" Text length: %d %n", text.length()); + System.out.printf(" HTML length: %d %n", html.length()); + System.out.printf(" %d outbound links %n", links.size()); + } + } + +} diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawlerController.java b/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawlerController.java new file mode 100644 index 0000000000..82c1c6bdd7 --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/HtmlCrawlerController.java @@ -0,0 +1,36 @@ +package com.baeldung.crawler4j; + +import java.io.File; + +import edu.uci.ics.crawler4j.crawler.CrawlConfig; +import edu.uci.ics.crawler4j.crawler.CrawlController; +import edu.uci.ics.crawler4j.fetcher.PageFetcher; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer; + +public class HtmlCrawlerController { + + public static void main(String[] args) throws Exception { + File crawlStorage = new File("src/test/resources/crawler4j"); + CrawlConfig config = new CrawlConfig(); + config.setCrawlStorageFolder(crawlStorage.getAbsolutePath()); + config.setMaxDepthOfCrawling(2); + + int numCrawlers = 12; + + PageFetcher pageFetcher = new PageFetcher(config); + RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); + RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher); + CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer); + + controller.addSeed("https://www.baeldung.com/"); + + CrawlerStatistics stats = new CrawlerStatistics(); + CrawlController.WebCrawlerFactory factory = () -> new HtmlCrawler(stats); + + controller.start(factory, numCrawlers); + System.out.printf("Crawled %d pages %n", stats.getProcessedPageCount()); + System.out.printf("Total Number of outbound links = %d %n", stats.getTotalLinksCount()); + } + +} diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawler.java b/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawler.java new file mode 100644 index 0000000000..ebb5d96f36 --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawler.java @@ -0,0 +1,49 @@ +package com.baeldung.crawler4j; + +import java.io.File; +import java.util.regex.Pattern; + +import edu.uci.ics.crawler4j.crawler.Page; +import edu.uci.ics.crawler4j.crawler.WebCrawler; +import edu.uci.ics.crawler4j.parser.BinaryParseData; +import edu.uci.ics.crawler4j.url.WebURL; + +public class ImageCrawler extends WebCrawler { + private final static Pattern EXCLUSIONS = Pattern.compile(".*(\\.(css|js|xml|gif|png|mp3|mp4|zip|gz|pdf))$"); + + private static final Pattern IMG_PATTERNS = Pattern.compile(".*(\\.(jpg|jpeg))$"); + + private File saveDir; + + public ImageCrawler(File saveDir) { + this.saveDir = saveDir; + } + + @Override + public boolean shouldVisit(Page referringPage, WebURL url) { + String urlString = url.getURL().toLowerCase(); + if (EXCLUSIONS.matcher(urlString).matches()) { + return false; + } + + if (IMG_PATTERNS.matcher(urlString).matches() + || urlString.startsWith("https://www.baeldung.com/")) { + return true; + } + + return false; + } + + @Override + public void visit(Page page) { + String url = page.getWebURL().getURL(); + if (IMG_PATTERNS.matcher(url).matches() + && page.getParseData() instanceof BinaryParseData) { + String extension = url.substring(url.lastIndexOf(".")); + int contentLength = page.getContentData().length; + + System.out.printf("Extension is '%s' with content length %d %n", extension, contentLength); + } + } + +} diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawlerController.java b/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawlerController.java new file mode 100644 index 0000000000..9db32f1bfb --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/ImageCrawlerController.java @@ -0,0 +1,36 @@ +package com.baeldung.crawler4j; + +import java.io.File; + +import edu.uci.ics.crawler4j.crawler.CrawlConfig; +import edu.uci.ics.crawler4j.crawler.CrawlController; +import edu.uci.ics.crawler4j.fetcher.PageFetcher; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer; + +public class ImageCrawlerController { + + public static void main(String[] args) throws Exception { + File crawlStorage = new File("src/test/resources/crawler4j"); + CrawlConfig config = new CrawlConfig(); + config.setCrawlStorageFolder(crawlStorage.getAbsolutePath()); + config.setIncludeBinaryContentInCrawling(true); + config.setMaxPagesToFetch(500); + + File saveDir = new File("src/test/resources/crawler4j"); + + int numCrawlers = 12; + + PageFetcher pageFetcher = new PageFetcher(config); + RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); + RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher); + CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer); + + controller.addSeed("https://www.baeldung.com/"); + + CrawlController.WebCrawlerFactory factory = () -> new ImageCrawler(saveDir); + + controller.start(factory, numCrawlers); + } + +} diff --git a/libraries-2/src/main/java/com/baeldung/crawler4j/MultipleCrawlerController.java b/libraries-2/src/main/java/com/baeldung/crawler4j/MultipleCrawlerController.java new file mode 100644 index 0000000000..7662607f80 --- /dev/null +++ b/libraries-2/src/main/java/com/baeldung/crawler4j/MultipleCrawlerController.java @@ -0,0 +1,54 @@ +package com.baeldung.crawler4j; + +import java.io.File; + +import edu.uci.ics.crawler4j.crawler.CrawlConfig; +import edu.uci.ics.crawler4j.crawler.CrawlController; +import edu.uci.ics.crawler4j.fetcher.PageFetcher; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig; +import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer; + +public class MultipleCrawlerController { + public static void main(String[] args) throws Exception { + File crawlStorageBase = new File("src/test/resources/crawler4j"); + CrawlConfig htmlConfig = new CrawlConfig(); + CrawlConfig imageConfig = new CrawlConfig(); + + htmlConfig.setCrawlStorageFolder(new File(crawlStorageBase, "html").getAbsolutePath()); + imageConfig.setCrawlStorageFolder(new File(crawlStorageBase, "image").getAbsolutePath()); + imageConfig.setIncludeBinaryContentInCrawling(true); + + htmlConfig.setMaxPagesToFetch(500); + imageConfig.setMaxPagesToFetch(1000); + + PageFetcher pageFetcherHtml = new PageFetcher(htmlConfig); + PageFetcher pageFetcherImage = new PageFetcher(imageConfig); + + RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); + RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcherHtml); + + CrawlController htmlController = new CrawlController(htmlConfig, pageFetcherHtml, robotstxtServer); + CrawlController imageController = new CrawlController(imageConfig, pageFetcherImage, robotstxtServer); + + htmlController.addSeed("https://www.baeldung.com/"); + imageController.addSeed("https://www.baeldung.com/"); + + CrawlerStatistics stats = new CrawlerStatistics(); + CrawlController.WebCrawlerFactory htmlFactory = () -> new HtmlCrawler(stats); + + File saveDir = new File("src/test/resources/crawler4j"); + CrawlController.WebCrawlerFactory imageFactory = () -> new ImageCrawler(saveDir); + + imageController.startNonBlocking(imageFactory, 7); + htmlController.startNonBlocking(htmlFactory, 10); + + + htmlController.waitUntilFinish(); + System.out.printf("Crawled %d pages %n", stats.getProcessedPageCount()); + System.out.printf("Total Number of outbound links = %d %n", stats.getTotalLinksCount()); + + imageController.waitUntilFinish(); + System.out.printf("Image Crawler is finished."); + + } +} From c18bb8e18878680635a8e5fbfe1af1d10cb46a49 Mon Sep 17 00:00:00 2001 From: maryarm Date: Fri, 7 Jun 2019 19:36:31 +0430 Subject: [PATCH 45/63] #BAEL-2802 Fix problems with code indentions, spacing and commas. --- .../okhttp/ResponseDecoderUnitTest.java | 124 +++++------------- .../com/baeldung/okhttp/SimpleEntity.java | 1 + 2 files changed, 34 insertions(+), 91 deletions(-) diff --git a/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java b/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java index e9f829abe4..11a295031a 100644 --- a/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java +++ b/libraries-2/src/test/java/com/baeldung/okhttp/ResponseDecoderUnitTest.java @@ -17,11 +17,9 @@ import java.io.InputStreamReader; public class ResponseDecoderUnitTest { - @Rule - public ExpectedException exceptionRule = ExpectedException.none(); + @Rule public ExpectedException exceptionRule = ExpectedException.none(); - @Rule - public MockWebServer server = new MockWebServer(); + @Rule public MockWebServer server = new MockWebServer(); SimpleEntity sampleResponse; @@ -29,132 +27,76 @@ public class ResponseDecoderUnitTest { OkHttpClient client; - @Before public void setUp() { sampleResponse = new SimpleEntity("Baeldung"); - client = new OkHttpClient.Builder() - .build(); + client = new OkHttpClient.Builder().build(); mockResponse = new MockResponse() - .setResponseCode(200) - .setHeader("Content-Type", "application/json") - .setBody(new Gson().toJson(sampleResponse)); - } - - @Test - public void givenJacksonDecoder_whenGetByteStreamOfResponse_thenExpectSimpleEntity() throws Exception { - - server.enqueue(mockResponse); - - Request request = new Request.Builder() - .url(server.url("")) - .build(); - ResponseBody responseBody = client.newCall(request).execute().body(); - - Assert.assertNotNull(responseBody); - Assert.assertNotEquals(0, responseBody.contentLength()); - - ObjectMapper objectMapper = new ObjectMapper(); - SimpleEntity response = objectMapper.readValue(responseBody.byteStream() - , SimpleEntity.class); - - Assert.assertEquals(sampleResponse.getName(), response.getName()); + .setResponseCode(200) + .setHeader("Content-Type", "application/json") + .setBody(new Gson().toJson(sampleResponse)); } @Test public void givenJacksonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception { - server.enqueue(mockResponse); - Request request = new Request.Builder() - .url(server.url("")) - .build(); - ResponseBody responseBody = client.newCall(request).execute().body(); + .url(server.url("")) + .build(); + ResponseBody responseBody = client + .newCall(request) + .execute() + .body(); Assert.assertNotNull(responseBody); Assert.assertNotEquals(0, responseBody.contentLength()); ObjectMapper objectMapper = new ObjectMapper(); - SimpleEntity response = objectMapper.readValue(responseBody.string(), SimpleEntity.class); + SimpleEntity entity = objectMapper.readValue(responseBody.string(), SimpleEntity.class); - Assert.assertEquals(sampleResponse.getName(), response.getName()); - } - - @Test - public void givenJacksonDecoder_whenGetCharStreamOfResponse_thenExpectSimpleEntity() throws Exception { - - server.enqueue(mockResponse); - - Request request = new Request.Builder() - .url(server.url("")) - .build(); - ResponseBody responseBody = client.newCall(request).execute().body(); - - Assert.assertNotNull(responseBody); - Assert.assertNotEquals(0, responseBody.contentLength()); - - ObjectMapper objectMapper = new ObjectMapper(); - SimpleEntity response = objectMapper.readValue(responseBody.charStream(), SimpleEntity.class); - - Assert.assertEquals(sampleResponse.getName(), response.getName()); + Assert.assertNotNull(entity); + Assert.assertEquals(sampleResponse.getName(), entity.getName()); } @Test public void givenGsonDecoder_whenGetByteStreamOfResponse_thenExpectSimpleEntity() throws Exception { - server.enqueue(mockResponse); - Request request = new Request.Builder() - .url(server.url("")) - .build(); - ResponseBody responseBody = client.newCall(request).execute().body(); + .url(server.url("")) + .build(); + ResponseBody responseBody = client + .newCall(request) + .execute() + .body(); Assert.assertNotNull(responseBody); Assert.assertNotEquals(0, responseBody.contentLength()); Gson gson = new Gson(); - SimpleEntity response = gson.fromJson(new InputStreamReader(responseBody.byteStream()) - , SimpleEntity.class); + SimpleEntity entity = gson.fromJson(new InputStreamReader(responseBody.byteStream()), SimpleEntity.class); - Assert.assertEquals(sampleResponse.getName(), response.getName()); + Assert.assertNotNull(entity); + Assert.assertEquals(sampleResponse.getName(), entity.getName()); } @Test public void givenGsonDecoder_whenGetStringOfResponse_thenExpectSimpleEntity() throws Exception { - server.enqueue(mockResponse); - Request request = new Request.Builder() - .url(server.url("")) - .build(); - ResponseBody responseBody = client.newCall(request).execute().body(); + .url(server.url("")) + .build(); + ResponseBody responseBody = client + .newCall(request) + .execute() + .body(); Assert.assertNotNull(responseBody); Gson gson = new Gson(); - SimpleEntity response = gson.fromJson(responseBody.string(), SimpleEntity.class); + SimpleEntity entity = gson.fromJson(responseBody.string(), SimpleEntity.class); - Assert.assertEquals(sampleResponse.getName(), response.getName()); + Assert.assertNotNull(entity); + Assert.assertEquals(sampleResponse.getName(), entity.getName()); } - @Test - public void givenGsonDecoder_whenGetCharStreamOfResponse_thenExpectSimpleEntity() throws Exception { - - server.enqueue(mockResponse); - - Request request = new Request.Builder() - .url(server.url("")) - .build(); - - ResponseBody responseBody = client.newCall(request).execute().body(); - - Assert.assertNotNull(responseBody); - - Gson gson = new Gson(); - SimpleEntity response = gson.fromJson(responseBody.charStream(), SimpleEntity.class); - - Assert.assertEquals(sampleResponse.getName(), response.getName()); - } - - } diff --git a/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java b/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java index 4c7cae6fdc..211e43e556 100644 --- a/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java +++ b/libraries-2/src/test/java/com/baeldung/okhttp/SimpleEntity.java @@ -8,6 +8,7 @@ public class SimpleEntity { } //no-arg constructor, getters and setters here + public SimpleEntity() { } From 858927c98524a5a0cd1c6862d88bdd1c107e2e82 Mon Sep 17 00:00:00 2001 From: codehunter34 Date: Fri, 7 Jun 2019 14:55:13 -0400 Subject: [PATCH 46/63] BAEL-2969: Copying Sets in Java --- .../main/java/com/baeldung/set/CopySets.java | 92 +++++++++---------- 1 file changed, 41 insertions(+), 51 deletions(-) diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java index 011ccb9b56..0a173cb772 100644 --- a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java @@ -2,7 +2,6 @@ package com.baeldung.set; import java.io.Serializable; import java.util.HashSet; -import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -12,63 +11,54 @@ import com.google.gson.Gson; public class CopySets { - public static Set copyByConstructor(Set original) { - Set copy = new HashSet<>(original); - return copy; - } + // Copy Constructor + public static Set copyByConstructor(Set original) { + Set copy = new HashSet<>(original); + return copy; + } - public static Set copyBySetAddAll(Set original) { - Set copy = new HashSet<>(); - copy.addAll(original); - return copy; - } + // Set.addAll + public static Set copyBySetAddAll(Set original) { + Set copy = new HashSet<>(); + copy.addAll(original); + return copy; + } - public static Set copyBySetClone(HashSet original) { - Set copy = (Set) original.clone(); - return copy; - } + // Set.clone + public static Set copyBySetClone(HashSet original) { + Set copy = (Set) original.clone(); + return copy; + } - public static Set copyByJson(Set original) { - Gson gson = new Gson(); - String jsonStr = gson.toJson(original); - Set copy = gson.fromJson(jsonStr, Set.class); + // JSON + public static Set copyByJson(Set original) { + Gson gson = new Gson(); + String jsonStr = gson.toJson(original); + Set copy = gson.fromJson(jsonStr, Set.class); - return copy; - } + return copy; + } - public static Set copyByApacheCommonsLang(Set original) { - Set copy = new HashSet<>(); - for (T item : original) { - copy.add((T) SerializationUtils.clone(item)); - } - return copy; - } + // Apache Commons Lang + public static Set copyByApacheCommonsLang(Set original) { + Set copy = new HashSet<>(); + for (T item : original) { + copy.add((T) SerializationUtils.clone(item)); + } + return copy; + } - public static void copyByStreamsAPI(Set original) { - Set copy1 = original.stream() - .collect(Collectors.toSet()); + // Collectors.toSet + public static Set copyByCollectorsToSet(Set original) { + Set copy = original.stream().collect(Collectors.toSet()); - // Skip the first element - Set copy2 = original.stream() - .skip(1) - .collect(Collectors.toSet()); + return copy; + } - // Filter by comparing the types and attributes - Set copy3 = original.stream() - .filter(f -> f.getClass() - .equals(Integer.class)) - .collect(Collectors.toSet()); - - // Null check in case of expecting null values - Set copy4 = original.stream() - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - } - - public static Set copyByJava8(Set original) { - Set copy = Set.copyOf(original); - return copy; - } + // Using Java 10 + public static Set copyBySetCopyOf(Set original) { + Set copy = Set.copyOf(original); + return copy; + } } From d69a81e25c05f842fac436c18977bfc440d11795 Mon Sep 17 00:00:00 2001 From: codehunter34 Date: Fri, 7 Jun 2019 15:01:42 -0400 Subject: [PATCH 47/63] BAEL-2969: Copying Sets in Java --- .../core-java-collections-set/pom.xml | 3 +- .../main/java/com/baeldung/set/CopySets.java | 83 ++++++++++--------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/core-java-modules/core-java-collections-set/pom.xml b/core-java-modules/core-java-collections-set/pom.xml index 4c1b880f31..21b1b87ebe 100644 --- a/core-java-modules/core-java-collections-set/pom.xml +++ b/core-java-modules/core-java-collections-set/pom.xml @@ -1,5 +1,4 @@ - 4.0.0 core-java-collections-set diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java index 0a173cb772..950ae41357 100644 --- a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java @@ -11,54 +11,55 @@ import com.google.gson.Gson; public class CopySets { - // Copy Constructor - public static Set copyByConstructor(Set original) { - Set copy = new HashSet<>(original); - return copy; - } + // Copy Constructor + public static Set copyByConstructor(Set original) { + Set copy = new HashSet<>(original); + return copy; + } - // Set.addAll - public static Set copyBySetAddAll(Set original) { - Set copy = new HashSet<>(); - copy.addAll(original); - return copy; - } + // Set.addAll + public static Set copyBySetAddAll(Set original) { + Set copy = new HashSet<>(); + copy.addAll(original); + return copy; + } - // Set.clone - public static Set copyBySetClone(HashSet original) { - Set copy = (Set) original.clone(); - return copy; - } + // Set.clone + public static Set copyBySetClone(HashSet original) { + Set copy = (Set) original.clone(); + return copy; + } - // JSON - public static Set copyByJson(Set original) { - Gson gson = new Gson(); - String jsonStr = gson.toJson(original); - Set copy = gson.fromJson(jsonStr, Set.class); + // JSON + public static Set copyByJson(Set original) { + Gson gson = new Gson(); + String jsonStr = gson.toJson(original); + Set copy = gson.fromJson(jsonStr, Set.class); - return copy; - } + return copy; + } - // Apache Commons Lang - public static Set copyByApacheCommonsLang(Set original) { - Set copy = new HashSet<>(); - for (T item : original) { - copy.add((T) SerializationUtils.clone(item)); - } - return copy; - } + // Apache Commons Lang + public static Set copyByApacheCommonsLang(Set original) { + Set copy = new HashSet<>(); + for (T item : original) { + copy.add((T) SerializationUtils.clone(item)); + } + return copy; + } - // Collectors.toSet - public static Set copyByCollectorsToSet(Set original) { - Set copy = original.stream().collect(Collectors.toSet()); + // Collectors.toSet + public static Set copyByCollectorsToSet(Set original) { + Set copy = original.stream() + .collect(Collectors.toSet()); - return copy; - } + return copy; + } - // Using Java 10 - public static Set copyBySetCopyOf(Set original) { - Set copy = Set.copyOf(original); - return copy; - } + // Using Java 10 + public static Set copyBySetCopyOf(Set original) { + Set copy = Set.copyOf(original); + return copy; + } } From b820e6bd0480079c273df1197d04dfe97ff4261d Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 8 Jun 2019 01:01:39 +0530 Subject: [PATCH 48/63] [BAEL-14850] - Fixed junits for core-java-persistence module --- .../joins/ArticleWithAuthorDAOIntegrationTest.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java index 5c20b6bf1e..3e8eed3f5a 100644 --- a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java @@ -1,5 +1,6 @@ package com.baeldung.jdbc.joins; +import org.h2.tools.Server; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -16,11 +17,15 @@ public class ArticleWithAuthorDAOIntegrationTest { private Connection connection; private ArticleWithAuthorDAO articleWithAuthorDAO; + + private Server server; @Before public void setup() throws ClassNotFoundException, SQLException { - Class.forName("org.postgresql.Driver"); - connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/myDb", "user", "pass"); + + server = Server.createTcpServer().start(); + Class.forName("org.h2.Driver"); + connection = DriverManager.getConnection("jdbc:h2:mem:test", "sa", ""); articleWithAuthorDAO = new ArticleWithAuthorDAO(connection); Statement statement = connection.createStatement(); String createAuthorSql = "CREATE TABLE IF NOT EXISTS AUTHOR (ID int NOT NULL PRIMARY KEY, FIRST_NAME varchar(255), LAST_NAME varchar(255));"; @@ -55,7 +60,8 @@ public class ArticleWithAuthorDAOIntegrationTest { assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null); } - @Test + // Commenting JUNIT as currently H2 doesn't support FULL JOIN, please switch to other live database to run FULL JOIN queries + //@Test public void whenQueryWithFullJoin_thenShouldReturnProperRows() { List articleWithAuthorList = articleWithAuthorDAO.articleFullJoinAuthor(); @@ -69,6 +75,7 @@ public class ArticleWithAuthorDAOIntegrationTest { connection.createStatement().execute("DROP TABLE ARTICLE"); connection.createStatement().execute("DROP TABLE AUTHOR"); connection.close(); + server.stop(); } public void insertTestData(Statement statement) throws SQLException { From b7e654ed650fa75264c7deb0b20e7e62771d2b2b Mon Sep 17 00:00:00 2001 From: Eric Martin Date: Fri, 7 Jun 2019 19:12:29 -0500 Subject: [PATCH 49/63] Update pom.xml Fixed merge issue --- libraries-2/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml index f9cb1201be..8e493e2d05 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -82,11 +82,11 @@ test - - edu.uci.ics - crawler4j - ${crawler4j.version} - + edu.uci.ics + crawler4j + ${crawler4j.version} + From 380f836cc6fc6153d792dca7784773907eef0f80 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 8 Jun 2019 12:40:56 +0530 Subject: [PATCH 50/63] [BAEL-14842] - Fixed tests in java-cassandra module --- persistence-modules/java-cassandra/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index aac5d49547..708d2b3c76 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -39,6 +39,7 @@ 3.1.2 3.1.1.0 + 18.0 From 62828091d916060a3d45dfa7963f513a9539cdf8 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 8 Jun 2019 16:36:34 +0530 Subject: [PATCH 51/63] [BAEL-14845] - Fixed tests in log4j2 module --- logging-modules/log4j2/pom.xml | 2 +- .../logging/log4j2/appender/MapAppenderIntegrationTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 14420356de..db0c6eb659 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -78,7 +78,7 @@ - integration + integration-lite-first diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java index 020aaafc74..e340ebb784 100644 --- a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/appender/MapAppenderIntegrationTest.java @@ -23,7 +23,7 @@ public class MapAppenderIntegrationTest { @Test public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception { - logger.info("Test from {}", this.getClass() + logger.error("Error log message from {}", this.getClass() .getSimpleName()); LoggerContext context = LoggerContext.getContext(false); Configuration config = context.getConfiguration(); From 2155cb7ac6b9f91476bcb98ccff348aae18af5d6 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 8 Jun 2019 20:05:31 +0530 Subject: [PATCH 52/63] [BAEL-14850] - Changed to live test --- ...est.java => ArticleWithAuthorDAOLiveTest.java} | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) rename persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/{ArticleWithAuthorDAOIntegrationTest.java => ArticleWithAuthorDAOLiveTest.java} (88%) diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOLiveTest.java similarity index 88% rename from persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java rename to persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOLiveTest.java index 3e8eed3f5a..3f69a0e333 100644 --- a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOIntegrationTest.java +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/jdbc/joins/ArticleWithAuthorDAOLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.jdbc.joins; -import org.h2.tools.Server; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -13,19 +12,15 @@ import java.util.List; import static org.assertj.core.api.Assertions.assertThat; -public class ArticleWithAuthorDAOIntegrationTest { +public class ArticleWithAuthorDAOLiveTest { private Connection connection; private ArticleWithAuthorDAO articleWithAuthorDAO; - - private Server server; @Before public void setup() throws ClassNotFoundException, SQLException { - - server = Server.createTcpServer().start(); - Class.forName("org.h2.Driver"); - connection = DriverManager.getConnection("jdbc:h2:mem:test", "sa", ""); + Class.forName("org.postgresql.Driver"); + connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/myDb", "user", "pass"); articleWithAuthorDAO = new ArticleWithAuthorDAO(connection); Statement statement = connection.createStatement(); String createAuthorSql = "CREATE TABLE IF NOT EXISTS AUTHOR (ID int NOT NULL PRIMARY KEY, FIRST_NAME varchar(255), LAST_NAME varchar(255));"; @@ -60,8 +55,7 @@ public class ArticleWithAuthorDAOIntegrationTest { assertThat(articleWithAuthorList).anyMatch(row -> row.getTitle() == null); } - // Commenting JUNIT as currently H2 doesn't support FULL JOIN, please switch to other live database to run FULL JOIN queries - //@Test + @Test public void whenQueryWithFullJoin_thenShouldReturnProperRows() { List articleWithAuthorList = articleWithAuthorDAO.articleFullJoinAuthor(); @@ -75,7 +69,6 @@ public class ArticleWithAuthorDAOIntegrationTest { connection.createStatement().execute("DROP TABLE ARTICLE"); connection.createStatement().execute("DROP TABLE AUTHOR"); connection.close(); - server.stop(); } public void insertTestData(Statement statement) throws SQLException { From af92ef71465969b21255ecd456487fc951ee3f35 Mon Sep 17 00:00:00 2001 From: Liesheng Long Date: Sun, 9 Jun 2019 00:31:09 -0400 Subject: [PATCH 53/63] refactored the module for java optional as a return --- core-java-modules/core-java-8-2/pom.xml | 18 ------- .../core-java-optional/README.md | 5 ++ core-java-modules/core-java-optional/pom.xml | 53 +++++++++++++++++++ .../HandleOptionalTypeExample.java | 0 .../OptionalToJsonExample.java | 0 .../PersistOptionalTypeExample.java | 0 .../PersistOptionalTypeExample2.java | 0 .../PersistUserExample.java | 0 .../SerializeOptionalTypeExample.java | 0 .../com/baeldung/optionalReturnType/User.java | 0 .../optionalReturnType/UserOptional.java | 0 .../optionalReturnType/UserOptionalField.java | 0 core-java-modules/pom.xml | 1 + 13 files changed, 59 insertions(+), 18 deletions(-) create mode 100644 core-java-modules/core-java-optional/README.md create mode 100644 core-java-modules/core-java-optional/pom.xml rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/User.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/UserOptional.java (100%) rename core-java-modules/{core-java-8-2 => core-java-optional}/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java (100%) diff --git a/core-java-modules/core-java-8-2/pom.xml b/core-java-modules/core-java-8-2/pom.xml index ff2e290086..cc184de529 100644 --- a/core-java-modules/core-java-8-2/pom.xml +++ b/core-java-modules/core-java-8-2/pom.xml @@ -22,9 +22,6 @@ 1.8 1.8 64.2 - 5.4.0.Final - 1.4.197 - 2.9.8
@@ -33,21 +30,6 @@ icu4j ${icu.version} - - org.hibernate - hibernate-core - ${hibernate.core.version} - - - com.h2database - h2 - ${h2database.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.databind.version} - diff --git a/core-java-modules/core-java-optional/README.md b/core-java-modules/core-java-optional/README.md new file mode 100644 index 0000000000..12a6fd1a56 --- /dev/null +++ b/core-java-modules/core-java-optional/README.md @@ -0,0 +1,5 @@ +========= + +## Core Java Optional + +### Relevant Articles: \ No newline at end of file diff --git a/core-java-modules/core-java-optional/pom.xml b/core-java-modules/core-java-optional/pom.xml new file mode 100644 index 0000000000..f2478c2c87 --- /dev/null +++ b/core-java-modules/core-java-optional/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + com.baeldung.core-java-modules + core-java-modules + 1.0.0-SNAPSHOT + + core-java-optional + 0.1.0-SNAPSHOT + jar + + + UTF-8 + 1.8 + 1.8 + 5.4.0.Final + 1.4.197 + 2.9.8 + + + + + org.hibernate + hibernate-core + ${hibernate.core.version} + + + com.h2database + h2 + ${h2database.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.databind.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/User.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/User.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/UserOptional.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/UserOptional.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java b/core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java similarity index 100% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java rename to core-java-modules/core-java-optional/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 2b563a7be4..11a1003460 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -16,6 +16,7 @@ pre-jpms core-java-exceptions + core-java-optional From 151fdb5a8a421d7350ac0958e6df9e09682e436a Mon Sep 17 00:00:00 2001 From: amit2103 Date: Mon, 10 Jun 2019 00:14:08 +0530 Subject: [PATCH 54/63] [BAEL-14844] - --- libraries-data/pom.xml | 10 ++++++++++ .../baeldung/flink/BackupCreatorIntegrationTest.java | 3 ++- .../src/main/java/com/baeldung/ftp/FtpClient.java | 1 + .../AdderMethodDirtiesContextIntegrationTest.java | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 3276ebcdbb..31aaaea951 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -263,6 +263,16 @@ org.apache.storm storm-core ${storm.version} + + + org.slf4j + slf4j-log4j12 + + + org.slf4j + log4j-over-slf4j + + diff --git a/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java index ab7d119c16..f46fffbb59 100644 --- a/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java +++ b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class BackupCreatorIntegrationTest { @@ -88,7 +89,7 @@ public class BackupCreatorIntegrationTest { SerializationSchema serializationSchema = new BackupSerializationSchema(); byte[] backupProcessed = serializationSchema.serialize(backup); - assertEquals(backupSerialized, backupProcessed); + assertArrayEquals(backupSerialized, backupProcessed); } private static class CollectingSink implements SinkFunction { diff --git a/libraries/src/main/java/com/baeldung/ftp/FtpClient.java b/libraries/src/main/java/com/baeldung/ftp/FtpClient.java index 209bed35f0..f885ff13b3 100644 --- a/libraries/src/main/java/com/baeldung/ftp/FtpClient.java +++ b/libraries/src/main/java/com/baeldung/ftp/FtpClient.java @@ -59,5 +59,6 @@ class FtpClient { void downloadFile(String source, String destination) throws IOException { FileOutputStream out = new FileOutputStream(destination); ftp.retrieveFile(source, out); + out.close(); } } diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java index fc7067520d..3201908bf7 100644 --- a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java @@ -28,7 +28,7 @@ public class AdderMethodDirtiesContextIntegrationTest { @Test public void _1_givenNumber_whenAdd_thenSumWrong() { adderServiceSteps.whenAdd(); - adderServiceSteps.sumWrong(); + adderServiceSteps.summedUp(); } @Rule From 51e050ae85c9fe361cd84fc7b0880ad282e91b7b Mon Sep 17 00:00:00 2001 From: Shubhra Srivastava Date: Mon, 10 Jun 2019 01:31:06 +0530 Subject: [PATCH 55/63] Bael 2950 graph has cycle check for directed graphs (#7088) * BAEL-2950 : Graph Check If Cycle Exists * BAEL-2950 : Minor Refactoring * BAEL-2950 Cycle detection * BAEL-2950 : Renaming unit test file --- .../graphcycledetection/domain/Graph.java | 51 +++++++++++++++++ .../graphcycledetection/domain/Vertex.java | 56 +++++++++++++++++++ .../GraphCycleDetectionUnitTest.java | 56 +++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java create mode 100644 algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java create mode 100644 algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java new file mode 100644 index 0000000000..c77173b288 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Graph.java @@ -0,0 +1,51 @@ +package com.baeldung.algorithms.graphcycledetection.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Graph { + + private List vertices; + + public Graph() { + this.vertices = new ArrayList<>(); + } + + public Graph(List vertices) { + this.vertices = vertices; + } + + public void addVertex(Vertex vertex) { + this.vertices.add(vertex); + } + + public void addEdge(Vertex from, Vertex to) { + from.addNeighbour(to); + } + + public boolean hasCycle() { + for (Vertex vertex : vertices) { + if (!vertex.isVisited() && hasCycle(vertex)) { + return true; + } + } + return false; + } + + public boolean hasCycle(Vertex sourceVertex) { + sourceVertex.setBeingVisited(true); + + for (Vertex neighbour : sourceVertex.getAdjacencyList()) { + if (neighbour.isBeingVisited()) { + // backward edge exists + return true; + } else if (!neighbour.isVisited() && hasCycle(neighbour)) { + return true; + } + } + + sourceVertex.setBeingVisited(false); + sourceVertex.setVisited(true); + return false; + } +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java new file mode 100644 index 0000000000..398cdf0d9c --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/graphcycledetection/domain/Vertex.java @@ -0,0 +1,56 @@ +package com.baeldung.algorithms.graphcycledetection.domain; + +import java.util.ArrayList; +import java.util.List; + +public class Vertex { + + private String label; + + private boolean visited; + + private boolean beingVisited; + + private List adjacencyList; + + public Vertex(String label) { + this.label = label; + this.adjacencyList = new ArrayList<>(); + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public boolean isVisited() { + return visited; + } + + public void setVisited(boolean visited) { + this.visited = visited; + } + + public boolean isBeingVisited() { + return beingVisited; + } + + public void setBeingVisited(boolean beingVisited) { + this.beingVisited = beingVisited; + } + + public List getAdjacencyList() { + return adjacencyList; + } + + public void setAdjacencyList(List adjacencyList) { + this.adjacencyList = adjacencyList; + } + + public void addNeighbour(Vertex adjacent) { + this.adjacencyList.add(adjacent); + } +} diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java new file mode 100644 index 0000000000..8d464d7b97 --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/graphcycledetection/GraphCycleDetectionUnitTest.java @@ -0,0 +1,56 @@ +package com.baeldung.algorithms.graphcycledetection; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.baeldung.algorithms.graphcycledetection.domain.Graph; +import com.baeldung.algorithms.graphcycledetection.domain.Vertex; + +public class GraphCycleDetectionUnitTest { + + @Test + public void givenGraph_whenCycleExists_thenReturnTrue() { + + Vertex vertexA = new Vertex("A"); + Vertex vertexB = new Vertex("B"); + Vertex vertexC = new Vertex("C"); + Vertex vertexD = new Vertex("D"); + + Graph graph = new Graph(); + graph.addVertex(vertexA); + graph.addVertex(vertexB); + graph.addVertex(vertexC); + graph.addVertex(vertexD); + + graph.addEdge(vertexA, vertexB); + graph.addEdge(vertexB, vertexC); + graph.addEdge(vertexC, vertexA); + graph.addEdge(vertexD, vertexC); + + assertTrue(graph.hasCycle()); + } + + @Test + public void givenGraph_whenNoCycleExists_thenReturnFalse() { + + Vertex vertexA = new Vertex("A"); + Vertex vertexB = new Vertex("B"); + Vertex vertexC = new Vertex("C"); + Vertex vertexD = new Vertex("D"); + + Graph graph = new Graph(); + graph.addVertex(vertexA); + graph.addVertex(vertexB); + graph.addVertex(vertexC); + graph.addVertex(vertexD); + + graph.addEdge(vertexA, vertexB); + graph.addEdge(vertexB, vertexC); + graph.addEdge(vertexA, vertexC); + graph.addEdge(vertexD, vertexC); + + assertFalse(graph.hasCycle()); + } +} From dd69f71a9cb22f1c36689415ef9a10ecf59d3ddd Mon Sep 17 00:00:00 2001 From: Gian Mario Contessa Date: Sun, 9 Jun 2019 21:18:13 +0100 Subject: [PATCH 56/63] [BAEL-2899] adding more information and changing methods names --- .../groovy/com/baeldung/CalcScript.groovy | 8 ++- .../com/baeldung/MyJointCompilationApp.java | 51 +++++++++++-------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy b/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy index 688928468a..84615b2217 100644 --- a/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy +++ b/core-groovy-2/src/main/groovy/com/baeldung/CalcScript.groovy @@ -5,6 +5,12 @@ def calcSum(x, y) { } def calcSum2(x, y) { - // DANGER! This won't throw a compilation issue and fail only at runtime!!! + // DANGER! The variable "log" may be undefined + log.info "Executing $x + $y" + // DANGER! This method doesn't exist! calcSum3() + // DANGER! The logged variable "z" is undefined! + log.info("Logging an undefined variable: $z") } + +calcSum(1,5) diff --git a/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java b/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java index 2be2e195ef..c49f6edc30 100644 --- a/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java +++ b/core-groovy-2/src/main/java/com/baeldung/MyJointCompilationApp.java @@ -40,7 +40,7 @@ public class MyJointCompilationApp { engineFromFactory = new GroovyScriptEngineFactory().getScriptEngine(); } - private void runCompiledClasses(int x, int y) { + private void addWithCompiledClasses(int x, int y) { LOG.info("Executing {} + {}", x, y); Object result1 = new CalcScript().calcSum(x, y); LOG.info("Result of CalcScript.calcSum() method is {}", result1); @@ -49,14 +49,21 @@ public class MyJointCompilationApp { LOG.info("Result of CalcMath.calcSum() method is {}", result2); } - private void runDynamicShellScript(int x, int y) throws IOException { + private void addWithGroovyShell(int x, int y) throws IOException { Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy")); LOG.info("Executing {} + {}", x, y); Object result = script.invokeMethod("calcSum", new Object[] { x, y }); LOG.info("Result of CalcScript.calcSum() method is {}", result); } - private void runDynamicClassWithLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException { + private void addWithGroovyShellRun() throws IOException { + Script script = shell.parse(new File("src/main/groovy/com/baeldung/", "CalcScript.groovy")); + LOG.info("Executing script run method"); + Object result = script.run(); + LOG.info("Result of CalcScript.run() method is {}", result); + } + + private void addWithGroovyClassLoader(int x, int y) throws IllegalAccessException, InstantiationException, IOException { Class calcClass = loader.parseClass( new File("src/main/groovy/com/baeldung/", "CalcMath.groovy")); GroovyObject calc = (GroovyObject) calcClass.newInstance(); @@ -64,9 +71,8 @@ public class MyJointCompilationApp { LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runDynamicClassWithEngine(int x, int y) throws IllegalAccessException, + private void addWithGroovyScriptEngine(int x, int y) throws IllegalAccessException, InstantiationException, ResourceException, ScriptException { - Class calcClass = engine.loadScriptByName("CalcMath.groovy"); GroovyObject calc = calcClass.newInstance(); //WARNING the following will throw a ClassCastException @@ -75,37 +81,40 @@ public class MyJointCompilationApp { LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runDynamicClassWithEngineFactory(int x, int y) throws IllegalAccessException, + private void addWithEngineFactory(int x, int y) throws IllegalAccessException, InstantiationException, javax.script.ScriptException, FileNotFoundException { - Class calcClas = (Class) engineFromFactory.eval( + Class calcClass = (Class) engineFromFactory.eval( new FileReader(new File("src/main/groovy/com/baeldung/", "CalcMath.groovy"))); - GroovyObject calc = (GroovyObject) calcClas.newInstance(); + GroovyObject calc = (GroovyObject) calcClass.newInstance(); Object result = calc.invokeMethod("calcSum", new Object[] { x, y }); LOG.info("Result of CalcMath.calcSum() method is {}", result); } - private void runStaticCompiledClasses() { + private void addWithStaticCompiledClasses() { LOG.info("Running the Groovy classes compiled statically..."); - runCompiledClasses(5, 10); + addWithCompiledClasses(5, 10); } - private void runDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException, + private void addWithDynamicCompiledClasses() throws IOException, IllegalAccessException, InstantiationException, ResourceException, ScriptException, javax.script.ScriptException { - LOG.info("Running a dynamic groovy script..."); - runDynamicShellScript(5, 10); - LOG.info("Running a dynamic groovy class with GroovyClassLoader..."); - runDynamicClassWithLoader(10, 30); - LOG.info("Running a dynamic groovy class with GroovyScriptEngine..."); - runDynamicClassWithEngine(15, 0); - LOG.info("Running a dynamic groovy class with GroovyScriptEngine JSR223..."); - runDynamicClassWithEngineFactory(5, 6); + LOG.info("Invocation of a dynamic groovy script..."); + addWithGroovyShell(5, 10); + LOG.info("Invocation of the run method of a dynamic groovy script..."); + addWithGroovyShellRun(); + LOG.info("Invocation of a dynamic groovy class loaded with GroovyClassLoader..."); + addWithGroovyClassLoader(10, 30); + LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine..."); + addWithGroovyScriptEngine(15, 0); + LOG.info("Invocation of a dynamic groovy class loaded with GroovyScriptEngine JSR223..."); + addWithEngineFactory(5, 6); } public static void main(String[] args) throws InstantiationException, IllegalAccessException, ResourceException, ScriptException, IOException, javax.script.ScriptException { MyJointCompilationApp myJointCompilationApp = new MyJointCompilationApp(); - myJointCompilationApp.runStaticCompiledClasses(); - myJointCompilationApp.runDynamicCompiledClasses(); + LOG.info("Example of addition operation via Groovy scripts integration with Java."); + myJointCompilationApp.addWithStaticCompiledClasses(); + myJointCompilationApp.addWithDynamicCompiledClasses(); } } From 8899b80818cff9a9e4a254fe1f5a10496c87b0df Mon Sep 17 00:00:00 2001 From: codehunter34 Date: Mon, 10 Jun 2019 01:48:14 -0400 Subject: [PATCH 57/63] BAEL-2969: Copying sets in Java --- .../src/main/java/com/baeldung/set/CopySets.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java index 950ae41357..53933e4439 100644 --- a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java @@ -56,10 +56,4 @@ public class CopySets { return copy; } - // Using Java 10 - public static Set copyBySetCopyOf(Set original) { - Set copy = Set.copyOf(original); - return copy; - } - } From a342b198b33d26c90c4135c9b231d7688fbba49e Mon Sep 17 00:00:00 2001 From: codehunter34 Date: Mon, 10 Jun 2019 01:48:14 -0400 Subject: [PATCH 58/63] BAEL-2969: Copying sets in Java --- .../src/main/java/com/baeldung/set/CopySets.java | 13 +++++++++++++ .../src/main/java/com/baeldung/set/CopySets.java | 6 ------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 core-java-modules/core-java-10/src/main/java/com/baeldung/set/CopySets.java diff --git a/core-java-modules/core-java-10/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-10/src/main/java/com/baeldung/set/CopySets.java new file mode 100644 index 0000000000..d49724f81d --- /dev/null +++ b/core-java-modules/core-java-10/src/main/java/com/baeldung/set/CopySets.java @@ -0,0 +1,13 @@ +package com.baeldung.set; + +import java.util.Set; + +public class CopySets { + + // Using Java 10 + public static Set copyBySetCopyOf(Set original) { + Set copy = Set.copyOf(original); + return copy; + } + +} diff --git a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java index 950ae41357..53933e4439 100644 --- a/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java +++ b/core-java-modules/core-java-collections-set/src/main/java/com/baeldung/set/CopySets.java @@ -56,10 +56,4 @@ public class CopySets { return copy; } - // Using Java 10 - public static Set copyBySetCopyOf(Set original) { - Set copy = Set.copyOf(original); - return copy; - } - } From 7b0daba254f43408723004cd0c6091122b677e7a Mon Sep 17 00:00:00 2001 From: maryarm <45322329+maryarm@users.noreply.github.com> Date: Tue, 11 Jun 2019 23:37:07 +0430 Subject: [PATCH 59/63] #BAEL-2461 (#7116) Implement methods to download a large file through Spring RestTemplate --- .../LargeFileDownloadIntegrationTest.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 spring-resttemplate/src/test/java/org/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java diff --git a/spring-resttemplate/src/test/java/org/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java new file mode 100644 index 0000000000..21639818db --- /dev/null +++ b/spring-resttemplate/src/test/java/org/baeldung/resttemplate/LargeFileDownloadIntegrationTest.java @@ -0,0 +1,109 @@ +package org.baeldung.resttemplate; + +import org.assertj.core.api.Assertions; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.util.StreamUtils; +import org.springframework.web.client.RestTemplate; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.List; + +public class LargeFileDownloadIntegrationTest { + + static String FILE_URL = "http://ovh.net/files/1Mio.dat"; + + RestTemplate restTemplate; + + @Before + public void setUp() { + restTemplate = new RestTemplate(); + } + + @Test + public void givenResumableUrl_whenUrlCalledByHeadOption_thenExpectHeadersAvailable() { + HttpHeaders headers = restTemplate.headForHeaders(FILE_URL); + Assertions + .assertThat(headers.get("Accept-Ranges")) + .contains("bytes"); + Assertions + .assertThat(headers.getContentLength()) + .isGreaterThan(0); + } + + @Test + public void givenResumableUrl_whenDownloadCompletely_thenExpectCorrectFileSize() { + HttpHeaders headers = restTemplate.headForHeaders(FILE_URL); + long contentLength = headers.getContentLength(); + File file = restTemplate.execute(FILE_URL, HttpMethod.GET, null, clientHttpResponse -> { + File ret = File.createTempFile("download", "tmp"); + StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret)); + return ret; + }); + + Assert.assertNotNull(file); + Assertions + .assertThat(file.length()) + .isEqualTo(contentLength); + } + + @Test + public void givenResumableUrl_whenDownloadRange_thenExpectFileSizeEqualOrLessThanRange() { + int range = 10; + File file = restTemplate.execute(FILE_URL, HttpMethod.GET, clientHttpRequest -> clientHttpRequest + .getHeaders() + .set("Range", String.format("bytes=0-%d", range - 1)), clientHttpResponse -> { + File ret = File.createTempFile("download", "tmp"); + StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret)); + return ret; + }); + + Assert.assertNotNull(file); + Assertions + .assertThat(file.length()) + .isLessThanOrEqualTo(range); + } + + @Test + public void givenResumableUrl_whenPauseDownloadAndResume_thenExpectCorrectFileSize() { + + int range = 10; + + HttpHeaders headers = restTemplate.headForHeaders(FILE_URL); + long contentLength = headers.getContentLength(); + + File file = restTemplate.execute(FILE_URL, HttpMethod.GET, clientHttpRequest -> clientHttpRequest + .getHeaders() + .set("Range", String.format("bytes=0-%d", range - 1)), clientHttpResponse -> { + File ret = File.createTempFile("download", "tmp"); + StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(ret)); + return ret; + }); + + Assert.assertNotNull(file); + + Assertions + .assertThat(file.length()) + .isLessThanOrEqualTo(range); + + restTemplate.execute(FILE_URL, HttpMethod.GET, clientHttpRequest -> clientHttpRequest + .getHeaders() + .set("Range", String.format("bytes=%d-%d", file.length(), contentLength)), clientHttpResponse -> { + StreamUtils.copy(clientHttpResponse.getBody(), new FileOutputStream(file, true)); + return file; + }); + + Assertions + .assertThat(file.length()) + .isEqualTo(contentLength); + + } + +} From d5f8b4e852611aad5e44d2a8dd171b0f19c16782 Mon Sep 17 00:00:00 2001 From: macroscopic64 <46401144+macroscopic64@users.noreply.github.com> Date: Wed, 12 Jun 2019 08:30:54 +0530 Subject: [PATCH 60/63] BAEL-1205 Introduction to SPF4J (#7064) * BAEL-1205 Introduction to SPF4j --- spf4j/pom.xml | 21 +++++ spf4j/spf4j-aspects-app/pom.xml | 83 +++++++++++++++++++ .../java/com/baeldung/spf4j/aspects/App.java | 28 +++++++ .../baeldung/spf4j/aspects/Spf4jConfig.java | 37 +++++++++ .../src/main/resources/META-INF/aop.xml | 12 +++ .../src/main/resources/logback.xml | 11 +++ spf4j/spf4j-core-app/pom.xml | 83 +++++++++++++++++++ .../java/com/baeldung/spf4j/core/App.java | 34 ++++++++ .../com/baeldung/spf4j/core/Spf4jConfig.java | 31 +++++++ .../src/main/resources/logback.xml | 11 +++ 10 files changed, 351 insertions(+) create mode 100644 spf4j/pom.xml create mode 100644 spf4j/spf4j-aspects-app/pom.xml create mode 100644 spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/App.java create mode 100644 spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/Spf4jConfig.java create mode 100644 spf4j/spf4j-aspects-app/src/main/resources/META-INF/aop.xml create mode 100644 spf4j/spf4j-aspects-app/src/main/resources/logback.xml create mode 100644 spf4j/spf4j-core-app/pom.xml create mode 100644 spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/App.java create mode 100644 spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/Spf4jConfig.java create mode 100644 spf4j/spf4j-core-app/src/main/resources/logback.xml diff --git a/spf4j/pom.xml b/spf4j/pom.xml new file mode 100644 index 0000000000..43a8028dc4 --- /dev/null +++ b/spf4j/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + com.baeldung.spf4j + spf4j + spf4j + pom + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + spf4j-core-app + spf4j-aspects-app + + + diff --git a/spf4j/spf4j-aspects-app/pom.xml b/spf4j/spf4j-aspects-app/pom.xml new file mode 100644 index 0000000000..9fccec673a --- /dev/null +++ b/spf4j/spf4j-aspects-app/pom.xml @@ -0,0 +1,83 @@ + + 4.0.0 + spf4j-aspects-app + 0.0.1-SNAPSHOT + jar + spf4j-aspects-app + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../ + + + + org.spf4j + spf4j-aspects + ${spf4j.version} + + + org.spf4j + spf4j-ui + ${spf4j.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + spf4j-aspects-app + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + + ${project.build.directory}/dependency-jars/ + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.baeldung.spf4j.aspects.App + true + dependency-jars/ + + + + + + + + UTF-8 + 8.6.10 + 1.7.21 + + diff --git a/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/App.java b/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/App.java new file mode 100644 index 0000000000..6d74292c75 --- /dev/null +++ b/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/App.java @@ -0,0 +1,28 @@ +package com.baeldung.spf4j.aspects; + +import java.util.Random; + +import org.spf4j.annotations.PerformanceMonitor; + +public class App { + + public static void main(String[] args) throws InterruptedException { + Spf4jConfig.initialize(); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + long numberToCheck = random.nextInt(999_999_999 - 100_000_000 + 1) + 100_000_000; + isPrimeNumber(numberToCheck); + } + System.exit(0); + } + + @PerformanceMonitor(warnThresholdMillis = 1, errorThresholdMillis = 100, recorderSource = Spf4jConfig.RecorderSourceForIsPrimeNumber.class) + public static boolean isPrimeNumber(long number) { + for (long i = 2; i <= number / 2; i++) { + if (number % i == 0) + return false; + } + return true; + } + +} diff --git a/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/Spf4jConfig.java b/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/Spf4jConfig.java new file mode 100644 index 0000000000..a12213f0cd --- /dev/null +++ b/spf4j/spf4j-aspects-app/src/main/java/com/baeldung/spf4j/aspects/Spf4jConfig.java @@ -0,0 +1,37 @@ +package com.baeldung.spf4j.aspects; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spf4j.annotations.RecorderSourceInstance; +import org.spf4j.perf.MeasurementRecorderSource; +import org.spf4j.perf.impl.RecorderFactory; + +public class Spf4jConfig { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void initialize() { + String tsDbFile = System.getProperty("user.dir") + File.separator + "spf4j-performance-monitoring.tsdb2"; + String tsTextFile = System.getProperty("user.dir") + File.separator + "spf4j-performance-monitoring.txt"; + + LOGGER.info("\nTime Series DB (TSDB) : {}\nTime Series text file : {}", tsDbFile, tsTextFile); + System.setProperty("spf4j.perf.ms.config", "TSDB@" + tsDbFile + "," + "TSDB_TXT@" + tsTextFile); + } + + public static final class RecorderSourceForIsPrimeNumber extends RecorderSourceInstance { + public static final MeasurementRecorderSource INSTANCE; + + static { + Object forWhat = App.class + " isPrimeNumber"; + String unitOfMeasurement = "ms"; + int sampleTimeMillis = 1_000; + int factor = 10; + int lowerMagnitude = 0; + int higherMagnitude = 4; + int quantasPerMagnitude = 10; + INSTANCE = RecorderFactory.createScalableQuantizedRecorderSource(forWhat, unitOfMeasurement, + sampleTimeMillis, factor, lowerMagnitude, higherMagnitude, quantasPerMagnitude); + } + } +} diff --git a/spf4j/spf4j-aspects-app/src/main/resources/META-INF/aop.xml b/spf4j/spf4j-aspects-app/src/main/resources/META-INF/aop.xml new file mode 100644 index 0000000000..1643f5fba9 --- /dev/null +++ b/spf4j/spf4j-aspects-app/src/main/resources/META-INF/aop.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spf4j/spf4j-aspects-app/src/main/resources/logback.xml b/spf4j/spf4j-aspects-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..4677fac9bf --- /dev/null +++ b/spf4j/spf4j-aspects-app/src/main/resources/logback.xml @@ -0,0 +1,11 @@ + + + + [%level] %msg%n + + + + + + \ No newline at end of file diff --git a/spf4j/spf4j-core-app/pom.xml b/spf4j/spf4j-core-app/pom.xml new file mode 100644 index 0000000000..ae346065ef --- /dev/null +++ b/spf4j/spf4j-core-app/pom.xml @@ -0,0 +1,83 @@ + + 4.0.0 + spf4j-core-app + 0.0.1-SNAPSHOT + jar + spf4j-core-app + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + ../../ + + + + org.spf4j + spf4j-core + ${spf4j.version} + + + org.spf4j + spf4j-ui + ${spf4j.version} + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + + spf4j-core-app + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + + ${project.build.directory}/dependency-jars/ + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.baeldung.spf4j.core.App + true + dependency-jars/ + + + + + + + + UTF-8 + 8.6.10 + 1.7.21 + + diff --git a/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/App.java b/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/App.java new file mode 100644 index 0000000000..fa107d8e4f --- /dev/null +++ b/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/App.java @@ -0,0 +1,34 @@ +package com.baeldung.spf4j.core; + +import java.util.Random; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spf4j.perf.MeasurementRecorder; + +public class App { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void main(String[] args) throws InterruptedException { + Spf4jConfig.initialize(); + MeasurementRecorder measurementRecorder = Spf4jConfig.getMeasurementRecorder(App.class + " isPrimeNumber"); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + long numberToCheck = random.nextInt(999_999_999 - 100_000_000 + 1) + 100_000_000; + long startTime = System.currentTimeMillis(); + boolean isPrime = isPrimeNumber(numberToCheck); + measurementRecorder.record(System.currentTimeMillis() - startTime); + LOGGER.info("{}. {} is prime? {}", i + 1, numberToCheck, isPrime); + } + System.exit(0); + } + + private static boolean isPrimeNumber(long number) { + for (long i = 2; i <= number / 2; i++) { + if (number % i == 0) + return false; + } + return true; + } + +} diff --git a/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/Spf4jConfig.java b/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/Spf4jConfig.java new file mode 100644 index 0000000000..0f806e1576 --- /dev/null +++ b/spf4j/spf4j-core-app/src/main/java/com/baeldung/spf4j/core/Spf4jConfig.java @@ -0,0 +1,31 @@ +package com.baeldung.spf4j.core; + +import java.io.File; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spf4j.perf.MeasurementRecorder; +import org.spf4j.perf.impl.RecorderFactory; + +public class Spf4jConfig { + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + + public static void initialize() { + String tsDbFile = System.getProperty("user.dir") + File.separator + "spf4j-performance-monitoring.tsdb2"; + String tsTextFile = System.getProperty("user.dir") + File.separator + "spf4j-performance-monitoring.txt"; + + LOGGER.info("\nTime Series DB (TSDB) : {}\nTime Series text file : {}", tsDbFile, tsTextFile); + System.setProperty("spf4j.perf.ms.config", "TSDB@" + tsDbFile + "," + "TSDB_TXT@" + tsTextFile); + } + + public static MeasurementRecorder getMeasurementRecorder(Object forWhat) { + String unitOfMeasurement = "ms"; + int sampleTimeMillis = 1_000; + int factor = 10; + int lowerMagnitude = 0; + int higherMagnitude = 4; + int quantasPerMagnitude = 10; + + return RecorderFactory.createScalableQuantizedRecorder(forWhat, unitOfMeasurement, sampleTimeMillis, factor, lowerMagnitude, higherMagnitude, quantasPerMagnitude); + } +} diff --git a/spf4j/spf4j-core-app/src/main/resources/logback.xml b/spf4j/spf4j-core-app/src/main/resources/logback.xml new file mode 100644 index 0000000000..4677fac9bf --- /dev/null +++ b/spf4j/spf4j-core-app/src/main/resources/logback.xml @@ -0,0 +1,11 @@ + + + + [%level] %msg%n + + + + + + \ No newline at end of file From 847ad4d0ddd504e204b0e2ac858c1e4feb442b55 Mon Sep 17 00:00:00 2001 From: Lukasz Rys Date: Wed, 12 Jun 2019 05:21:06 +0200 Subject: [PATCH 61/63] [ BAEL-2978 ]: Determine file creation date in java (#7099) * [ BAEL-2978 ]: Determine file creation date in java --- core-java-modules/core-java-nio/README.md | 3 ++ .../creationdate/CreationDateResolver.java | 35 +++++++++++++++ .../CreationDateResolverUnitTest.java | 45 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 core-java-modules/core-java-nio/README.md create mode 100644 core-java-modules/core-java-nio/src/main/java/com/baeldung/creationdate/CreationDateResolver.java create mode 100644 core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java diff --git a/core-java-modules/core-java-nio/README.md b/core-java-modules/core-java-nio/README.md new file mode 100644 index 0000000000..e73a9850ad --- /dev/null +++ b/core-java-modules/core-java-nio/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Determine File Creating Date in Java](https://www.baeldung.com/file-creation-date-java) diff --git a/core-java-modules/core-java-nio/src/main/java/com/baeldung/creationdate/CreationDateResolver.java b/core-java-modules/core-java-nio/src/main/java/com/baeldung/creationdate/CreationDateResolver.java new file mode 100644 index 0000000000..6347a6e681 --- /dev/null +++ b/core-java-modules/core-java-nio/src/main/java/com/baeldung/creationdate/CreationDateResolver.java @@ -0,0 +1,35 @@ +package com.baeldung.creationdate; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.FileTime; +import java.time.Instant; +import java.util.Optional; + +public class CreationDateResolver { + + public Instant resolveCreationTimeWithBasicAttributes(Path path) { + try { + final BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class); + final FileTime fileTime = attr.creationTime(); + + return fileTime.toInstant(); + } catch (IOException ex) { + throw new RuntimeException("An issue occured went wrong when resolving creation time", ex); + } + } + + public Optional resolveCreationTimeWithAttribute(Path path) { + try { + final FileTime creationTime = (FileTime) Files.getAttribute(path, "creationTime"); + + return Optional + .ofNullable(creationTime) + .map((FileTime::toInstant)); + } catch (IOException ex) { + throw new RuntimeException("An issue occured went wrong when resolving creation time", ex); + } + } +} diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java new file mode 100644 index 0000000000..5402852c74 --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/creationdate/CreationDateResolverUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.creationdate; + +import org.junit.Test; + +import java.io.File; +import java.nio.file.Path; +import java.time.Instant; +import java.util.Optional; + +import static org.junit.Assert.assertTrue; + +public class CreationDateResolverUnitTest { + + private final CreationDateResolver creationDateResolver = new CreationDateResolver(); + + @Test + public void givenFile_whenGettingCreationDateTimeFromBasicAttributes_thenReturnDate() throws Exception { + + final File file = File.createTempFile("createdFile", ".txt"); + final Path path = file.toPath(); + + final Instant response = creationDateResolver.resolveCreationTimeWithBasicAttributes(path); + + assertTrue(Instant + .now() + .isAfter(response)); + + } + + @Test + public void givenFile_whenGettingCreationDateTimeFromAttribute_thenReturnDate() throws Exception { + + final File file = File.createTempFile("createdFile", ".txt"); + final Path path = file.toPath(); + + final Optional response = creationDateResolver.resolveCreationTimeWithAttribute(path); + + response.ifPresent((value) -> { + assertTrue(Instant + .now() + .isAfter(value)); + }); + + } +} From d73ad96976c79a55758df9ae9e265f2133590d6a Mon Sep 17 00:00:00 2001 From: eric-martin Date: Tue, 11 Jun 2019 22:57:24 -0500 Subject: [PATCH 62/63] BAEL-2937: Moved delay to core-java-concurrency-basic --- .../src/main/java/com/baeldung/concurrent}/delay/Delay.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename core-java-modules/{core-java-8-2/src/main/java/com/baeldung => core-java-concurrency-basic/src/main/java/com/baeldung/concurrent}/delay/Delay.java (95%) diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/delay/Delay.java similarity index 95% rename from core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java rename to core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/delay/Delay.java index 0cc0c9487f..1689c09f51 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java +++ b/core-java-modules/core-java-concurrency-basic/src/main/java/com/baeldung/concurrent/delay/Delay.java @@ -1,4 +1,4 @@ -package com.baeldung.delay; +package com.baeldung.concurrent.delay; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -61,6 +61,7 @@ public class Delay { executorService.schedule(Delay::someTask1, delayInSeconds, TimeUnit.SECONDS); + executorService.shutdown(); } private static void fixedRateServiceTask(Integer delayInSeconds) { @@ -78,6 +79,7 @@ public class Delay { sf.cancel(true); + executorService.shutdown(); } private static void someTask1() { From a057010fed3686088ce6f5d336dd9d9113fbd5fb Mon Sep 17 00:00:00 2001 From: pcoates33 Date: Wed, 12 Jun 2019 06:09:20 +0100 Subject: [PATCH 63/63] BAEL-2922 Add Json to CSV code using Jackson CsvMapper (#7115) --- jackson-2/pom.xml | 7 +++ .../jackson/csv/JsonCsvConverter.java | 59 +++++++++++++++++++ .../jackson/mixin/OrderLineForCsv.java | 25 ++++++++ jackson-2/src/main/resources/orderLines.csv | 3 + jackson-2/src/main/resources/orderLines.json | 9 +++ .../com/baeldung/jackson/csv/CsvUnitTest.java | 54 +++++++++++++++++ .../test/resources/expectedCsvFromJson.csv | 3 + .../expectedFormattedCsvFromJson.csv | 3 + .../test/resources/expectedJsonFromCsv.json | 9 +++ 9 files changed, 172 insertions(+) create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/csv/JsonCsvConverter.java create mode 100644 jackson-2/src/main/java/com/baeldung/jackson/mixin/OrderLineForCsv.java create mode 100644 jackson-2/src/main/resources/orderLines.csv create mode 100644 jackson-2/src/main/resources/orderLines.json create mode 100644 jackson-2/src/test/java/com/baeldung/jackson/csv/CsvUnitTest.java create mode 100644 jackson-2/src/test/resources/expectedCsvFromJson.csv create mode 100644 jackson-2/src/test/resources/expectedFormattedCsvFromJson.csv create mode 100644 jackson-2/src/test/resources/expectedJsonFromCsv.json diff --git a/jackson-2/pom.xml b/jackson-2/pom.xml index 6b973dd6f5..6a975f1de7 100644 --- a/jackson-2/pom.xml +++ b/jackson-2/pom.xml @@ -28,6 +28,13 @@ jackson-dataformat-yaml 2.9.8 + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-csv + 2.9.8 + diff --git a/jackson-2/src/main/java/com/baeldung/jackson/csv/JsonCsvConverter.java b/jackson-2/src/main/java/com/baeldung/jackson/csv/JsonCsvConverter.java new file mode 100644 index 0000000000..71c6de4d7e --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/csv/JsonCsvConverter.java @@ -0,0 +1,59 @@ +package com.baeldung.jackson.csv; + +import java.io.File; +import java.io.IOException; + +import com.baeldung.jackson.entities.OrderLine; +import com.baeldung.jackson.mixin.OrderLineForCsv; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.MappingIterator; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.dataformat.csv.CsvMapper; +import com.fasterxml.jackson.dataformat.csv.CsvSchema; +import com.fasterxml.jackson.dataformat.csv.CsvSchema.Builder; + +public class JsonCsvConverter { + + public static void JsonToCsv(File jsonFile, File csvFile) throws IOException { + JsonNode jsonTree = new ObjectMapper().readTree(jsonFile); + + Builder csvSchemaBuilder = CsvSchema.builder(); + JsonNode firstObject = jsonTree.elements().next(); + firstObject.fieldNames().forEachRemaining(fieldName -> {csvSchemaBuilder.addColumn(fieldName);} ); + CsvSchema csvSchema = csvSchemaBuilder + .build() + .withHeader(); + + CsvMapper csvMapper = new CsvMapper(); + csvMapper.writerFor(JsonNode.class) + .with(csvSchema) + .writeValue(csvFile, jsonTree); + } + + public static void csvToJson(File csvFile, File jsonFile) throws IOException { + CsvSchema orderLineSchema = CsvSchema.emptySchema().withHeader(); + CsvMapper csvMapper = new CsvMapper(); + MappingIterator orderLines = csvMapper.readerFor(OrderLine.class) + .with(orderLineSchema) + .readValues(csvFile); + + new ObjectMapper() + .configure(SerializationFeature.INDENT_OUTPUT, true) + .writeValue(jsonFile, orderLines.readAll()); + } + + public static void JsonToFormattedCsv(File jsonFile, File csvFile) throws IOException { + CsvMapper csvMapper = new CsvMapper(); + CsvSchema csvSchema = csvMapper + .schemaFor(OrderLineForCsv.class) + .withHeader(); + csvMapper.addMixIn(OrderLine.class, OrderLineForCsv.class); + + OrderLine[] orderLines = new ObjectMapper() + .readValue(jsonFile, OrderLine[].class); + csvMapper.writerFor(OrderLine[].class) + .with(csvSchema) + .writeValue(csvFile, orderLines); + } +} diff --git a/jackson-2/src/main/java/com/baeldung/jackson/mixin/OrderLineForCsv.java b/jackson-2/src/main/java/com/baeldung/jackson/mixin/OrderLineForCsv.java new file mode 100644 index 0000000000..05d70a8053 --- /dev/null +++ b/jackson-2/src/main/java/com/baeldung/jackson/mixin/OrderLineForCsv.java @@ -0,0 +1,25 @@ +package com.baeldung.jackson.mixin; + +import java.math.BigDecimal; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({ + "count", + "name" +}) +public abstract class OrderLineForCsv { + + @JsonProperty("name") + private String item; + + @JsonProperty("count") + private int quantity; + + @JsonIgnore + private BigDecimal unitPrice; + + +} diff --git a/jackson-2/src/main/resources/orderLines.csv b/jackson-2/src/main/resources/orderLines.csv new file mode 100644 index 0000000000..e15e12f2bf --- /dev/null +++ b/jackson-2/src/main/resources/orderLines.csv @@ -0,0 +1,3 @@ +item,quantity,unitPrice +"No. 9 Sprockets",12,1.23 +"Widget (10mm)",4,3.45 diff --git a/jackson-2/src/main/resources/orderLines.json b/jackson-2/src/main/resources/orderLines.json new file mode 100644 index 0000000000..64f18e1673 --- /dev/null +++ b/jackson-2/src/main/resources/orderLines.json @@ -0,0 +1,9 @@ +[ { + "item" : "No. 9 Sprockets", + "quantity" : 12, + "unitPrice" : 1.23 +}, { + "item" : "Widget (10mm)", + "quantity" : 4, + "unitPrice" : 3.45 +} ] \ No newline at end of file diff --git a/jackson-2/src/test/java/com/baeldung/jackson/csv/CsvUnitTest.java b/jackson-2/src/test/java/com/baeldung/jackson/csv/CsvUnitTest.java new file mode 100644 index 0000000000..60c8ce79f3 --- /dev/null +++ b/jackson-2/src/test/java/com/baeldung/jackson/csv/CsvUnitTest.java @@ -0,0 +1,54 @@ +package com.baeldung.jackson.csv; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.List; + +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.google.common.io.Files; + + +public class CsvUnitTest { + + @Test + public void givenJsonInput_thenWriteCsv() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.JsonToCsv(new File("src/main/resources/orderLines.json"), + new File("src/main/resources/csvFromJson.csv")); + + assertEquals(readFile("src/main/resources/csvFromJson.csv"), + readFile("src/test/resources/expectedCsvFromJson.csv")); + } + + @Test + public void givenCsvInput_thenWritesJson() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.csvToJson(new File("src/main/resources/orderLines.csv"), + new File("src/main/resources/jsonFromCsv.json")); + + assertEquals(readFile("src/main/resources/jsonFromCsv.json"), + readFile("src/test/resources/expectedJsonFromCsv.json")); + + } + + @Test + public void givenJsonInput_thenWriteFormattedCsvOutput() throws JsonParseException, JsonMappingException, IOException { + JsonCsvConverter.JsonToFormattedCsv(new File("src/main/resources/orderLines.json"), + new File("src/main/resources/formattedCsvFromJson.csv")); + + assertEquals(readFile("src/main/resources/formattedCsvFromJson.csv"), + readFile("src/test/resources/expectedFormattedCsvFromJson.csv")); + + } + + private List readFile(String filename) throws IOException { + return Files.readLines(new File(filename), Charset.forName("utf-8")); + } + + +} +; \ No newline at end of file diff --git a/jackson-2/src/test/resources/expectedCsvFromJson.csv b/jackson-2/src/test/resources/expectedCsvFromJson.csv new file mode 100644 index 0000000000..e15e12f2bf --- /dev/null +++ b/jackson-2/src/test/resources/expectedCsvFromJson.csv @@ -0,0 +1,3 @@ +item,quantity,unitPrice +"No. 9 Sprockets",12,1.23 +"Widget (10mm)",4,3.45 diff --git a/jackson-2/src/test/resources/expectedFormattedCsvFromJson.csv b/jackson-2/src/test/resources/expectedFormattedCsvFromJson.csv new file mode 100644 index 0000000000..5a60ba602a --- /dev/null +++ b/jackson-2/src/test/resources/expectedFormattedCsvFromJson.csv @@ -0,0 +1,3 @@ +count,name +12,"No. 9 Sprockets" +4,"Widget (10mm)" diff --git a/jackson-2/src/test/resources/expectedJsonFromCsv.json b/jackson-2/src/test/resources/expectedJsonFromCsv.json new file mode 100644 index 0000000000..64f18e1673 --- /dev/null +++ b/jackson-2/src/test/resources/expectedJsonFromCsv.json @@ -0,0 +1,9 @@ +[ { + "item" : "No. 9 Sprockets", + "quantity" : 12, + "unitPrice" : 1.23 +}, { + "item" : "Widget (10mm)", + "quantity" : 4, + "unitPrice" : 3.45 +} ] \ No newline at end of file