From c389f56da5b7c74584771b80692e73775c7e6c86 Mon Sep 17 00:00:00 2001 From: Nikhil Khatwani Date: Thu, 26 Oct 2017 23:16:35 +0530 Subject: [PATCH 1/9] Bael 1166 intro apache spark (#2875) * Changes for BAEL-1166 * Changes for BAEL_1166 * Changes for BAEL 1166 * Changes for BAEL 1166 * Changes for BAEL_1166 --- .../src/main/java/com/baeldung/WordCount.java | 49 +++++++------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/apache-spark/src/main/java/com/baeldung/WordCount.java b/apache-spark/src/main/java/com/baeldung/WordCount.java index ec1dedcb69..bc73b05536 100644 --- a/apache-spark/src/main/java/com/baeldung/WordCount.java +++ b/apache-spark/src/main/java/com/baeldung/WordCount.java @@ -17,37 +17,24 @@ import scala.Tuple2; public class WordCount { private static final Pattern SPACE = Pattern.compile(" "); - + public static void main(String[] args) throws Exception { - if (args.length < 1) { - System.err.println("Usage: JavaWordCount "); - System.exit(1); + if (args.length < 1) { + System.err.println("Usage: JavaWordCount "); + System.exit(1); + } + SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount") + .setMaster("local"); + JavaSparkContext ctx = new JavaSparkContext(sparkConf); + JavaRDD lines = ctx.textFile(args[0], 1); + + JavaRDD words = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator()); + JavaPairRDD wordAsTuple = words.mapToPair(word -> new Tuple2<>(word, 1)); + JavaPairRDD wordWithCount = wordAsTuple.reduceByKey((Integer i1, Integer i2)->i1 + i2); + List> output = wordWithCount.collect(); + for (Tuple2 tuple : output) { + System.out.println(tuple._1() + ": " + tuple._2()); + } + ctx.stop(); } - SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount").setMaster("local"); - JavaSparkContext ctx = new JavaSparkContext(sparkConf); - JavaRDD lines = ctx.textFile(args[0], 1); - - JavaRDD words = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator()); - JavaPairRDD ones = words.mapToPair( - new PairFunction() { - @Override - public Tuple2 call(String s) { - return new Tuple2<>(s, 1); - } - }); - - JavaPairRDD counts = ones.reduceByKey( - new Function2() { - @Override - public Integer call(Integer i1, Integer i2) { - return i1 + i2; - } - }); - - List> output = counts.collect(); - for (Tuple2 tuple : output) { - System.out.println(tuple._1() + ": " + tuple._2()); - } - ctx.stop(); -} } From b1219990ec45c540c23a2d9ac502450a5ac2400a Mon Sep 17 00:00:00 2001 From: Eric Goebelbecker Date: Thu, 26 Oct 2017 14:34:25 -0400 Subject: [PATCH 2/9] Add Mockito tutorial for void methods (#2869) --- .../mockito/MockitoVoidMethodsTest.java | 62 +++++++++++++++++++ .../java/org/baeldung/mockito/MyList.java | 5 ++ 2 files changed, 67 insertions(+) create mode 100644 mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java diff --git a/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java b/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java new file mode 100644 index 0000000000..4de9a88dcc --- /dev/null +++ b/mockito/src/test/java/org/baeldung/mockito/MockitoVoidMethodsTest.java @@ -0,0 +1,62 @@ +package org.baeldung.mockito; + +import org.junit.Test; +import org.junit.runner.RunWith; +import static org.junit.Assert.assertEquals; + +import static org.mockito.Mockito.*; +import org.mockito.ArgumentCaptor; +import static org.mockito.Matchers.any; +import org.mockito.stubbing.Answer; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MockitoVoidMethodsTest { + + @Test + public void whenAddCalledVerified() { + MyList mockVoid = mock(MyList.class); + mockVoid.add(0, ""); + verify(mockVoid, times(1)).add(0, ""); + } + + @Test(expected = Exception.class) + public void givenNull_addThrows() { + MyList mockVoid = mock(MyList.class); + doThrow().when(mockVoid).add(isA(Integer.class), isNull()); + mockVoid.add(0, null); + } + + @Test + public void whenAddCalledValueCaptured() { + MyList mockVoid = mock(MyList.class); + ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); + doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture()); + mockVoid.add(0, "captured"); + assertEquals("captured", valueCapture.getValue()); + } + + @Test + public void whenAddCalledAnswered() { + MyList mockVoid = mock(MyList.class); + doAnswer((Answer) invocation -> { + Object arg0 = invocation.getArgument(0); + Object arg1 = invocation.getArgument(1); + + //do something with the arguments here + assertEquals(3, arg0); + assertEquals("answer me", arg1); + + return null; + }).when(mockVoid).add(any(Integer.class), any(String.class)); + mockVoid.add(3, "answer me"); + } + + @Test + public void whenAddCalledRealMethodCalled() { + MyList mockVoid = mock(MyList.class); + doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class)); + mockVoid.add(1, "real"); + verify(mockVoid, times(1)).add(1, "real"); + } +} diff --git a/mockito/src/test/java/org/baeldung/mockito/MyList.java b/mockito/src/test/java/org/baeldung/mockito/MyList.java index be69ef8a8a..0b501225ad 100644 --- a/mockito/src/test/java/org/baeldung/mockito/MyList.java +++ b/mockito/src/test/java/org/baeldung/mockito/MyList.java @@ -14,4 +14,9 @@ class MyList extends AbstractList { return 1; } + @Override + public void add(int index, String element) { + // no-op + } + } From dc349c17a89e56f4ea0f516cb172ac8966eba4d0 Mon Sep 17 00:00:00 2001 From: Michael C Good <31810784+michaelcgood@users.noreply.github.com> Date: Fri, 27 Oct 2017 00:32:25 -0400 Subject: [PATCH 3/9] BAEL-1238 michael.good703@gmail.com (#2879) * michael.good703@gmail.com michael.good703@gmail.com * michael.good703@gmail.com michael.good703@gmail.com * michael.good703@gmail.com michael.good703@gmail.com * update --- spring-boot/.factorypath | 149 ++++++++++++++++++ spring-boot/.gitignore | 1 + spring-boot/pom.xml | 16 +- .../java/com/baeldung/keycloak/Customer.java | 42 +++++ .../com/baeldung/keycloak/CustomerDAO.java | 7 + .../com/baeldung/keycloak/SecurityConfig.java | 52 ++++++ .../com/baeldung/keycloak/SpringBoot.java | 13 ++ .../com/baeldung/keycloak/WebController.java | 52 ++++++ .../src/main/resources/application.properties | 7 + .../main/resources/templates/customers.html | 33 ++++ .../main/resources/templates/external.html | 31 ++++ .../src/main/resources/templates/layout.html | 18 +++ .../keycloak/KeycloakConfigurationTest.java | 53 +++++++ .../src/main/webapp/META-INF/MANIFEST.MF | 3 + 14 files changed, 476 insertions(+), 1 deletion(-) create mode 100644 spring-boot/.factorypath create mode 100644 spring-boot/src/main/java/com/baeldung/keycloak/Customer.java create mode 100644 spring-boot/src/main/java/com/baeldung/keycloak/CustomerDAO.java create mode 100644 spring-boot/src/main/java/com/baeldung/keycloak/SecurityConfig.java create mode 100644 spring-boot/src/main/java/com/baeldung/keycloak/SpringBoot.java create mode 100644 spring-boot/src/main/java/com/baeldung/keycloak/WebController.java create mode 100644 spring-boot/src/main/resources/templates/customers.html create mode 100644 spring-boot/src/main/resources/templates/external.html create mode 100644 spring-boot/src/main/resources/templates/layout.html create mode 100644 spring-boot/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java create mode 100644 spring-jms/src/main/webapp/META-INF/MANIFEST.MF diff --git a/spring-boot/.factorypath b/spring-boot/.factorypath new file mode 100644 index 0000000000..aa15485f5c --- /dev/null +++ b/spring-boot/.factorypath @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-boot/.gitignore b/spring-boot/.gitignore index e26d6af438..a64317df5e 100644 --- a/spring-boot/.gitignore +++ b/spring-boot/.gitignore @@ -2,3 +2,4 @@ .settings/ .classpath .project +/.apt_generated/ diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 9d44de64a3..583aaf2984 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -24,7 +24,10 @@ org.springframework.boot spring-boot-starter-web - + + org.keycloak + keycloak-spring-boot-starter + org.springframework.boot spring-boot-starter-data-jpa @@ -170,6 +173,17 @@ artemis-server + + + + org.keycloak.bom + keycloak-adapter-bom + 3.3.0.CR2 + pom + import + + + spring-boot diff --git a/spring-boot/src/main/java/com/baeldung/keycloak/Customer.java b/spring-boot/src/main/java/com/baeldung/keycloak/Customer.java new file mode 100644 index 0000000000..c35eebf4c5 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/keycloak/Customer.java @@ -0,0 +1,42 @@ +package com.baeldung.keycloak; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Customer { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + private String name; + private String serviceRendered; + private String address; + + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getServiceRendered() { + return serviceRendered; + } + public void setServiceRendered(String serviceRendered) { + this.serviceRendered = serviceRendered; + } + public String getAddress() { + return address; + } + public void setAddress(String address) { + this.address = address; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/keycloak/CustomerDAO.java b/spring-boot/src/main/java/com/baeldung/keycloak/CustomerDAO.java new file mode 100644 index 0000000000..20d992d335 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/keycloak/CustomerDAO.java @@ -0,0 +1,7 @@ +package com.baeldung.keycloak; + +import org.springframework.data.repository.CrudRepository; + +public interface CustomerDAO extends CrudRepository { + +} diff --git a/spring-boot/src/main/java/com/baeldung/keycloak/SecurityConfig.java b/spring-boot/src/main/java/com/baeldung/keycloak/SecurityConfig.java new file mode 100644 index 0000000000..4ecb62b6d4 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/keycloak/SecurityConfig.java @@ -0,0 +1,52 @@ +package com.baeldung.keycloak; + +import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver; +import org.keycloak.adapters.springsecurity.KeycloakSecurityComponents; +import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider; +import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; + +@Configuration +@EnableWebSecurity +@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class) +class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter { + // Submits the KeycloakAuthenticationProvider to the AuthenticationManager + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider(); + keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); + auth.authenticationProvider(keycloakAuthenticationProvider); + } + + @Bean + public KeycloakSpringBootConfigResolver KeycloakConfigResolver() { + return new KeycloakSpringBootConfigResolver(); + } + + // Specifies the session authentication strategy + @Bean + @Override + protected SessionAuthenticationStrategy sessionAuthenticationStrategy() { + return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + super.configure(http); + http.authorizeRequests() + .antMatchers("/customers*") + .hasRole("user") + .anyRequest() + .permitAll(); + } +} diff --git a/spring-boot/src/main/java/com/baeldung/keycloak/SpringBoot.java b/spring-boot/src/main/java/com/baeldung/keycloak/SpringBoot.java new file mode 100644 index 0000000000..87b22cf50a --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/keycloak/SpringBoot.java @@ -0,0 +1,13 @@ +package com.baeldung.keycloak; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBoot { + + public static void main(String[] args) { + SpringApplication.run(SpringBoot.class, args); +} + +} diff --git a/spring-boot/src/main/java/com/baeldung/keycloak/WebController.java b/spring-boot/src/main/java/com/baeldung/keycloak/WebController.java new file mode 100644 index 0000000000..3bafe1f195 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/keycloak/WebController.java @@ -0,0 +1,52 @@ +package com.baeldung.keycloak; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +import java.security.Principal; + +import org.springframework.beans.factory.annotation.Autowired; + +@Controller +public class WebController { + + @Autowired + private CustomerDAO customerDAO; + + @GetMapping(path = "/") + public String index() { + return "external"; + } + + @GetMapping(path = "/customers") + public String customers(Principal principal, Model model) { + addCustomers(); + Iterable customers = customerDAO.findAll(); + model.addAttribute("customers", customers); + model.addAttribute("username", principal.getName()); + return "customers"; + } + + // add customers for demonstration + public void addCustomers() { + + Customer customer1 = new Customer(); + customer1.setAddress("1111 foo blvd"); + customer1.setName("Foo Industries"); + customer1.setServiceRendered("Important services"); + customerDAO.save(customer1); + + Customer customer2 = new Customer(); + customer2.setAddress("2222 bar street"); + customer2.setName("Bar LLP"); + customer2.setServiceRendered("Important services"); + customerDAO.save(customer2); + + Customer customer3 = new Customer(); + customer3.setAddress("33 main street"); + customer3.setName("Big LLC"); + customer3.setServiceRendered("Important services"); + customerDAO.save(customer3); + } +} diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 458b4e0d46..18d1223d43 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -49,3 +49,10 @@ contactInfoType=email endpoints.beans.id=springbeans endpoints.beans.sensitive=false + +#Keycloak Configuration +keycloak.auth-server-url=http://localhost:8180/auth +keycloak.realm=SpringBootKeycloak +keycloak.resource=login-app +keycloak.public-client=true +keycloak.principal-attribute=preferred_username diff --git a/spring-boot/src/main/resources/templates/customers.html b/spring-boot/src/main/resources/templates/customers.html new file mode 100644 index 0000000000..5a060d31da --- /dev/null +++ b/spring-boot/src/main/resources/templates/customers.html @@ -0,0 +1,33 @@ + + + + + +
+

+ Hello, --name--. +

+ + + + + + + + + + + + + + + + + +
IDNameAddressService Rendered
Text ...Text ...Text ...Text...
+ +
+ + + diff --git a/spring-boot/src/main/resources/templates/external.html b/spring-boot/src/main/resources/templates/external.html new file mode 100644 index 0000000000..2f9cc76961 --- /dev/null +++ b/spring-boot/src/main/resources/templates/external.html @@ -0,0 +1,31 @@ + + + + + +
+
+

Customer Portal

+
+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam + erat lectus, vehicula feugiat ultricies at, tempus sed ante. Cras + arcu erat, lobortis vitae quam et, mollis pharetra odio. Nullam sit + amet congue ipsum. Nunc dapibus odio ut ligula venenatis porta non + id dui. Duis nec tempor tellus. Suspendisse id blandit ligula, sit + amet varius mauris. Nulla eu eros pharetra, tristique dui quis, + vehicula libero. Aenean a neque sit amet tellus porttitor rutrum nec + at leo.

+ +

Existing Customers

+
+ Enter the intranet: customers +
+
+ +
+ + + + diff --git a/spring-boot/src/main/resources/templates/layout.html b/spring-boot/src/main/resources/templates/layout.html new file mode 100644 index 0000000000..bab0c2982b --- /dev/null +++ b/spring-boot/src/main/resources/templates/layout.html @@ -0,0 +1,18 @@ + + + +Customer Portal + + + + + \ No newline at end of file diff --git a/spring-boot/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java b/spring-boot/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java new file mode 100644 index 0000000000..8e3436a8ef --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/keycloak/KeycloakConfigurationTest.java @@ -0,0 +1,53 @@ +package com.baeldung.keycloak; + + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.keycloak.KeycloakPrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.springboot.client.KeycloakSecurityContextClientRequestInterceptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.when; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = SpringBoot.class) +public class KeycloakConfigurationTest { + + @Spy + private KeycloakSecurityContextClientRequestInterceptor factory; + + private MockHttpServletRequest servletRequest; + + @Mock + public KeycloakSecurityContext keycloakSecurityContext; + + @Mock + private KeycloakPrincipal keycloakPrincipal; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + servletRequest = new MockHttpServletRequest(); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(servletRequest)); + servletRequest.setUserPrincipal(keycloakPrincipal); + when(keycloakPrincipal.getKeycloakSecurityContext()).thenReturn(keycloakSecurityContext); + } + + @Test + public void testGetKeycloakSecurityContext() throws Exception { + assertNotNull(keycloakPrincipal.getKeycloakSecurityContext()); + } + + + +} diff --git a/spring-jms/src/main/webapp/META-INF/MANIFEST.MF b/spring-jms/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..5e9495128c --- /dev/null +++ b/spring-jms/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + From 7489cf6effece4e08ddc2bb2dc274278766472e5 Mon Sep 17 00:00:00 2001 From: nabyla <31042612+nabyla@users.noreply.github.com> Date: Fri, 27 Oct 2017 10:46:29 +0100 Subject: [PATCH 4/9] PR Bouncycastle article (#2882) * Add bouncycastle depedencies * Add certificate and private key to resources folder * add bouncycastle code sample * Add bouncycastle test --- libraries/pom.xml | 15 +++ .../bouncycastle/BouncyCastleCrypto.java | 111 ++++++++++++++++++ libraries/src/main/resources/Baeldung.cer | 20 ++++ libraries/src/main/resources/Baeldung.p12 | Bin 0 -> 2502 bytes .../bouncycastle/BouncyCastleLiveTest.java | 53 +++++++++ 5 files changed, 199 insertions(+) create mode 100644 libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java create mode 100644 libraries/src/main/resources/Baeldung.cer create mode 100644 libraries/src/main/resources/Baeldung.p12 create mode 100644 libraries/src/test/java/com/baeldung/bouncycastle/BouncyCastleLiveTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index b519b9cd53..409b4df08d 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -600,6 +600,21 @@ caffeine ${caffeine.version} + + org.bouncycastle + bcprov-jdk15on + 1.58 + + + org.bouncycastle + bcprov-jdk15on + 1.58 + + + org.bouncycastle + bcpkix-jdk15on + 1.58 + diff --git a/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java b/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java new file mode 100644 index 0000000000..5d8a7a6643 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/bouncycastle/BouncyCastleCrypto.java @@ -0,0 +1,111 @@ +package com.baeldung.bouncycastle; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.CMSAlgorithm; +import org.bouncycastle.cms.CMSEnvelopedData; +import org.bouncycastle.cms.CMSEnvelopedDataGenerator; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSProcessableByteArray; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataGenerator; +import org.bouncycastle.cms.CMSTypedData; +import org.bouncycastle.cms.KeyTransRecipientInformation; +import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.OutputEncryptor; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.util.Store; + +public class BouncyCastleCrypto { + + public static byte[] signData(byte[] data, final X509Certificate signingCertificate, final PrivateKey signingKey) + throws CertificateEncodingException, OperatorCreationException, CMSException, IOException { + byte[] signedMessage = null; + List certList = new ArrayList(); + CMSTypedData cmsData = new CMSProcessableByteArray(data); + certList.add(signingCertificate); + Store certs = new JcaCertStore(certList); + CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey); + cmsGenerator.addSignerInfoGenerator( + new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) + .build(contentSigner, signingCertificate)); + cmsGenerator.addCertificates(certs); + CMSSignedData cms = cmsGenerator.generate(cmsData, true); + signedMessage = cms.getEncoded(); + return signedMessage; + } + + public static boolean verifSignData(final byte[] signedData) + throws CMSException, IOException, OperatorCreationException, CertificateException { + ByteArrayInputStream bIn = new ByteArrayInputStream(signedData); + ASN1InputStream aIn = new ASN1InputStream(bIn); + CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); + aIn.close(); + bIn.close(); + Store certs = s.getCertificates(); + SignerInformationStore signers = s.getSignerInfos(); + Collection c = signers.getSigners(); + SignerInformation signer = c.iterator().next(); + Collection certCollection = certs.getMatches(signer.getSID()); + Iterator certIt = certCollection.iterator(); + X509CertificateHolder certHolder = certIt.next(); + boolean verifResult = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(certHolder)); + if (!verifResult) { + return false; + } + return true; + } + + public static byte[] encryptData(final byte[] data, X509Certificate encryptionCertificate) + throws CertificateEncodingException, CMSException, IOException { + byte[] encryptedData = null; + if (null != data && null != encryptionCertificate) { + CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator(); + JceKeyTransRecipientInfoGenerator jceKey = new JceKeyTransRecipientInfoGenerator(encryptionCertificate); + cmsEnvelopedDataGenerator.addRecipientInfoGenerator(jceKey); + CMSTypedData msg = new CMSProcessableByteArray(data); + OutputEncryptor encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC") + .build(); + CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(msg, encryptor); + encryptedData = cmsEnvelopedData.getEncoded(); + } + return encryptedData; + } + + public static byte[] decryptData(final byte[] encryptedData, final PrivateKey decryptionKey) throws CMSException { + byte[] decryptedData = null; + if (null != encryptedData && null != decryptionKey) { + CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData); + Collection recip = envelopedData.getRecipientInfos().getRecipients(); + KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation) recip.iterator().next(); + JceKeyTransRecipient recipient = new JceKeyTransEnvelopedRecipient(decryptionKey); + decryptedData = recipientInfo.getContent(recipient); + } + return decryptedData; + } +} diff --git a/libraries/src/main/resources/Baeldung.cer b/libraries/src/main/resources/Baeldung.cer new file mode 100644 index 0000000000..72d0918424 --- /dev/null +++ b/libraries/src/main/resources/Baeldung.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV +BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw +DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa +MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh +YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh +jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM +AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr +CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj +fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV +whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR +BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB +AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1 +vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP +pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU +CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt +XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU +ia7y5BL6uOa/4ShSV8pcJDYz +-----END CERTIFICATE----- diff --git a/libraries/src/main/resources/Baeldung.p12 b/libraries/src/main/resources/Baeldung.p12 new file mode 100644 index 0000000000000000000000000000000000000000..65ec8bc8fec33120b2c11276883dde5dad7a3ea6 GIT binary patch literal 2502 zcmY+Ec{CJ^8pg-W7-KiSAxm~&AvE}qeFbou@HKRX#MCzW*R!0LL7Y% z7)Sr`m+g30_7yeFjs-&~fCI+{-yx;|%9MeT2(tgQ10!G4XA2 zkG>wSErwX=^nQsIu&jb*uF4fhJf{o`c{-h8IOQJ-3P1FiZj0wRF6K9 z8mc&Zv?tvBj9P!Y^4uoj2G=6#18%wBeI!8jBRU|{P+P>0Aj=k375X=>QV+%oS!bk}+lJ+=1;z2pF||>sP$r3Brd~; zK)4%I2x>Ka+<;kKSK~)>L|uxGz&8_NxTGL2SC%Ui58tY=@-RCRhmrcaiO=Kg3VLao zL4POxN4d@n*d5|D3|P>OiNs!L2y3}V91S9g=+MPm2z2B)8SfIlps2SxADFc?et7bp zX$NVVRh<~4WzxjUvYD%W)wYw9O8Brp^L0RcbZ~X#P4;$ zj@d^cTmNv5A?VBUvx?k4kPIs2@lgJ*dzk-y`e;r~_tMcguyihj(WZx;W7st6eU1^p zA%3;BP+|V=UsgnMaP2xR9K?kLwyMXM~nWS!589aEx|ZivtPE+FCig}|Cv7n z4X_Xg-u#7*)&HXc=rv2DY6l{514xv{C2smp+M* z0HVF+G4qecX9^nOQ_20k2BM02$9dQ593Rq`jJUz%jTp%B$M|BdRc91;W`+2m}mmXL+cwS z-&0lg5an|f6il`kXk#vPZhK2Z{$$;;@;0;b_10a*B5Rf5vKBR^@uJW`WS*}TZ=JLU zrj7F9)-nOh*HW4C!Otz_FqYnEa!4nC@x0Wy?`_DN=c%fjkhTs@U^UB&)l0w$4n{K* zxd;D}W@$I_F{l@h(sB)s*Iz+sw{FOEa8& z#EfydGU+EgJ3m#S4b&`TTCBfC)eJ1M>U(%yKc+7F3lI-0X##xff#=dtmj;cWs@*(1 zZXS(tbGXP@?braN#P>=GxwN^xFqQBRSvZbJniMWr*lo`MXc=JWLQ&?yr)-$(Q$h^t zmmrKH?`t%wDk~pX1aJ^CbU%HXCAh@rR6?f`m^|7yVOF)+`(Y=4B-tto(B<>E=#QYq z&@RDn^M$lUwdx-1I4h;lvzUX6)HqThjqi4SlgM#nYG;nAtd-nO%TPn)KA9c{jep;9 zv79sQ{V`P{aJuEBb+8(|yi8}R z6hXIAFE*35l(toZR?k^d;kDRbp0Bi3D0P+;?`sW)yZdU2IS(8r-PlbgD6J2GLhODl zx^Ea$kiSoZQ1qd#$ zrw<*y{e#y|n++B0#ujM&wp!KoH<8hT7JB{RiW`47kpL%2BP;hRkV5E^;HN+5b za*HI=nMx7`*nucDb(iCuuCi`KplQ=xzr^Ya{l%oz=!5s?{M_rv@Zq3;FGnmok06!C z!iZ>7b}M(R4R=#t|6J8 Date: Fri, 27 Oct 2017 13:23:32 -0400 Subject: [PATCH 5/9] BAEL-1238 Quick Guide to Using Keycloak with a Spring Boot Application (#2886) * michael.good703@gmail.com michael.good703@gmail.com * michael.good703@gmail.com michael.good703@gmail.com * michael.good703@gmail.com michael.good703@gmail.com * update From 6d0d878ba4f35435fe7fb91c55b63bee97aff27e Mon Sep 17 00:00:00 2001 From: daoire Date: Fri, 27 Oct 2017 20:59:09 +0100 Subject: [PATCH 6/9] Update README.md (#2887) --- spring-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-jpa/README.md b/spring-jpa/README.md index 70f4404f98..d93271164c 100644 --- a/spring-jpa/README.md +++ b/spring-jpa/README.md @@ -14,6 +14,7 @@ - [Spring, Hibernate and a JNDI Datasource](http://www.baeldung.com/spring-persistence-jpa-jndi-datasource) - [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate) - [Self-Contained Testing Using an In-Memory Database](http://www.baeldung.com/spring-jpa-test-in-memory-database) +- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories) ### Eclipse Config After importing the project into Eclipse, you may see the following error: From 303db6c66357f2258d3738b452f205cb69a68b79 Mon Sep 17 00:00:00 2001 From: Shaimaa Shalaby Date: Fri, 27 Oct 2017 23:42:37 +0200 Subject: [PATCH 7/9] Intro to JDO Queries 2/2 article (#2871) * ADD MyApp.java class ProductItem.java class modify: package.jdo to add a named query pom.xml to add datanucleus-jdo-query.jar * remove sys.out statements --- libraries/pom.xml | 54 +++++---- .../java/com/baeldung/jdo/query/MyApp.java | 104 ++++++++++++++++++ .../com/baeldung/jdo/query/ProductItem.java | 68 ++++++++++++ .../src/main/resources/META-INF/package.jdo | 10 +- 4 files changed, 214 insertions(+), 22 deletions(-) create mode 100644 libraries/src/main/java/com/baeldung/jdo/query/MyApp.java create mode 100644 libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java diff --git a/libraries/pom.xml b/libraries/pom.xml index 409b4df08d..d04234bf2f 100644 --- a/libraries/pom.xml +++ b/libraries/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"> parent-modules com.baeldung @@ -105,6 +105,13 @@ + + maven-compiler-plugin + + 1.8 + 1.8 + +
@@ -326,6 +333,11 @@ datanucleus-xml 5.0.0-release + + org.datanucleus + datanucleus-jdo-query + 5.0.2 + net.openhft chronicle @@ -546,29 +558,29 @@ ${protonpack.version} - org.functionaljava - functionaljava - 4.7 - - - org.functionaljava - functionaljava-java8 - 4.7 + org.functionaljava + functionaljava + 4.7 - org.functionaljava - functionaljava-quickcheck - 4.7 - - - org.functionaljava - functionaljava-java-core - 4.7 + org.functionaljava + functionaljava-java8 + 4.7 - javax.cache - cache-api - ${cache.version} + org.functionaljava + functionaljava-quickcheck + 4.7 + + + org.functionaljava + functionaljava-java-core + 4.7 + + + javax.cache + cache-api + ${cache.version} com.hazelcast @@ -581,7 +593,7 @@ 1.0.1 - com.netopyr.wurmloch + com.netopyr.wurmloch wurmloch-crdt ${crdt.version} diff --git a/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java b/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java new file mode 100644 index 0000000000..384dde48d1 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java @@ -0,0 +1,104 @@ +package com.baeldung.jdo.query; + +import java.util.List; + +import javax.jdo.JDOQLTypedQuery; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Query; + +import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; +import org.datanucleus.metadata.PersistenceUnitMetaData; + +public class MyApp { + + private static PersistenceManagerFactory pmf; + private static PersistenceManager pm; + + public static void main(String[] args) { + + defineDynamicPersistentUnit(); + createTestData(); + queryUsingJDOQL(); + queryUsingTypedJDOQL(); + queryUsingSQL(); + queryUsingJPQL(); + + } + + public static void createTestData(){ + ProductItem item1 = new ProductItem("supportedItem", "price less than 10", "SoldOut",5); + ProductItem item2 = new ProductItem("pro2", "price less than 10","InStock", 8); + ProductItem item3 = new ProductItem("pro3", "price more than 10","SoldOut", 15); + + if( pm != null ){ + pm.makePersistent(item1); + pm.makePersistent(item2); + pm.makePersistent(item3); + } + } + + public static void defineDynamicPersistentUnit(){ + + PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); + pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/jdo_db"); + pumd.addProperty("javax.jdo.option.ConnectionUserName", "root"); + pumd.addProperty("javax.jdo.option.ConnectionPassword", "admin"); + pumd.addProperty("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver"); + pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); + + pmf = new JDOPersistenceManagerFactory(pumd, null); + pm = pmf.getPersistenceManager(); + } + + public static void queryUsingJDOQL(){ + + Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem " + + "WHERE price < threshold PARAMETERS double threshold"); + List explicitParamResults = (List)query.execute(10); + + query = pm.newQuery("SELECT FROM " + + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + query.setParameters("double threshold"); + List explicitParamResults2 = (List)query.execute(10); + + query = pm.newQuery("SELECT FROM " + + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + List implicitParamResults = (List)query.execute(10); + + } + + public static void queryUsingTypedJDOQL(){ + + JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class); + QProductItem cand = QProductItem.candidate(); + tq=tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro"))); + List results = tq.executeList(); + + } + + public static void queryUsingSQL(){ + + Query query = pm.newQuery("javax.jdo.query.SQL","select * from " + + "product_item where price < ? and status = ?"); + query.setClass(ProductItem.class); + query.setParameters(10,"InStock"); + List results = query.executeList(); + + } + + public static void queryUsingJPQL(){ + Query query = pm.newQuery("JPQL","select i from " + + "com.baeldung.jdo.query.ProductItem i where i.price < 10" + + " and i.status = 'InStock'"); + List results = (List) query.execute(); + + } + + public static void namedQuery(){ + Query query = pm.newNamedQuery( + ProductItem.class, "PriceBelow10"); + List results = query.executeList(); + + } +} diff --git a/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java b/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java new file mode 100644 index 0000000000..52221a7d97 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java @@ -0,0 +1,68 @@ +package com.baeldung.jdo.query; + +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.PersistenceAware; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable(table = "product_item") +public class ProductItem { + + @PrimaryKey + @Persistent(valueStrategy=IdGeneratorStrategy.INCREMENT) + int id; + String name; + String description; + String status; + double price; + + public ProductItem(){ + + } + + public ProductItem(String name,String description,String status,double price){ + this.name=name; + this.description = description; + this.status = status; + this.price = price; + } + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public double getPrice() { + return price; + } + public void setPrice(double price) { + this.price = price; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + +} diff --git a/libraries/src/main/resources/META-INF/package.jdo b/libraries/src/main/resources/META-INF/package.jdo index d30207e2e0..d3cf501bb6 100644 --- a/libraries/src/main/resources/META-INF/package.jdo +++ b/libraries/src/main/resources/META-INF/package.jdo @@ -16,6 +16,14 @@ - + + + + + + + + \ No newline at end of file From fb283f35c73a02ad664f8de49cfb1217d650fb1f Mon Sep 17 00:00:00 2001 From: dimitarsazdovski Date: Fri, 27 Oct 2017 23:45:27 +0200 Subject: [PATCH 8/9] BAEL 148 move to this repo (#2885) --- spring-groovy/pom.xml | 33 +++++++++++ .../com/baeldug/groovyconfig/BandsBean.java | 17 ++++++ .../groovyconfig/GroovyBeanConfig.groovy | 18 ++++++ .../baeldug/groovyconfig/JavaBeanConfig.java | 21 +++++++ .../baeldug/groovyconfig/JavaPersonBean.java | 57 +++++++++++++++++++ .../src/main/resources/xml-bean-config.xml | 12 ++++ .../groovyconfig/GroovyConfigurationTest.java | 50 ++++++++++++++++ .../groovyconfig/JavaConfigurationTest.java | 24 ++++++++ .../groovyconfig/XmlConfigurationTest.java | 23 ++++++++ 9 files changed, 255 insertions(+) create mode 100644 spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java create mode 100644 spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy create mode 100644 spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java create mode 100644 spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java create mode 100644 spring-groovy/src/main/resources/xml-bean-config.xml create mode 100644 spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java create mode 100644 spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java create mode 100644 spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java diff --git a/spring-groovy/pom.xml b/spring-groovy/pom.xml index 59c7ba4a7c..9086369fa4 100644 --- a/spring-groovy/pom.xml +++ b/spring-groovy/pom.xml @@ -37,5 +37,38 @@ spring-integration-groovy 4.3.7.RELEASE + + org.codehaus.groovy + groovy-all + 2.4.12 + + + + + maven-compiler-plugin + 3.7.0 + + groovy-eclipse-compiler + true + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.codehaus.groovy + groovy-eclipse-compiler + 2.9.2-01 + + + org.codehaus.groovy + groovy-eclipse-batch + 2.4.3-01 + + + + + + diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java new file mode 100644 index 0000000000..1deba5d2f6 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/BandsBean.java @@ -0,0 +1,17 @@ +package com.baeldug.groovyconfig; + +import java.util.ArrayList; +import java.util.List; + +public class BandsBean { + + private List bandsList = new ArrayList<>(); + + public List getBandsList() { + return bandsList; + } + + public void setBandsList(List bandsList) { + this.bandsList = bandsList; + } +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy b/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy new file mode 100644 index 0000000000..32a6fedff0 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/GroovyBeanConfig.groovy @@ -0,0 +1,18 @@ +package com.baeldug.groovyconfig; + +beans { + javaPesronBean(JavaPersonBean) { + firstName = 'John' + lastName = 'Doe' + age ='32' + eyesColor = 'blue' + hairColor='black' + } + + bandsBean(BandsBean) { bean-> + bean.scope = "singleton" + bandsList=['Nirvana', 'Pearl Jam', 'Foo Fighters'] + } + + registerAlias("bandsBean","bands") +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java new file mode 100644 index 0000000000..7c4238ae28 --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaBeanConfig.java @@ -0,0 +1,21 @@ +package com.baeldug.groovyconfig; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class JavaBeanConfig { + + @Bean + public JavaPersonBean javaPerson() { + JavaPersonBean jPerson = new JavaPersonBean(); + jPerson.setFirstName("John"); + jPerson.setLastName("Doe"); + jPerson.setAge("31"); + jPerson.setEyesColor("green"); + jPerson.setHairColor("blond"); + + return jPerson; + } + +} diff --git a/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java new file mode 100644 index 0000000000..db988d4abf --- /dev/null +++ b/spring-groovy/src/main/java/com/baeldug/groovyconfig/JavaPersonBean.java @@ -0,0 +1,57 @@ +package com.baeldug.groovyconfig; + +public class JavaPersonBean { + + public String jj; + + private String firstName; + + private String lastName; + + private String age; + + private String eyesColor; + + private String hairColor; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public String getEyesColor() { + return eyesColor; + } + + public void setEyesColor(String eyesColor) { + this.eyesColor = eyesColor; + } + + public String getHairColor() { + return hairColor; + } + + public void setHairColor(String hairColor) { + this.hairColor = hairColor; + } + +} diff --git a/spring-groovy/src/main/resources/xml-bean-config.xml b/spring-groovy/src/main/resources/xml-bean-config.xml new file mode 100644 index 0000000000..3b880bbd70 --- /dev/null +++ b/spring-groovy/src/main/resources/xml-bean-config.xml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java new file mode 100644 index 0000000000..91ca6dbfe9 --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/GroovyConfigurationTest.java @@ -0,0 +1,50 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.assertEquals; + +import java.io.File; + +import org.junit.Test; +import org.springframework.context.support.GenericGroovyApplicationContext; + +public class GroovyConfigurationTest { + + private static final String FILE_NAME = "GroovyBeanConfig.groovy"; + private static final String FILE_PATH = "src/main/java/com/baeldug/groovyconfig/"; + + @Test + public void whenGroovyConfig_thenCorrectPerson() throws Exception { + + GenericGroovyApplicationContext ctx = new GenericGroovyApplicationContext(); + ctx.load("file:" + getPathPart() + FILE_NAME); + ctx.refresh(); + + JavaPersonBean j = ctx.getBean(JavaPersonBean.class); + + assertEquals("32", j.getAge()); + assertEquals("blue", j.getEyesColor()); + assertEquals("black", j.getHairColor()); + } + + @Test + public void whenGroovyConfig_thenCorrectListLength() throws Exception { + + GenericGroovyApplicationContext ctx = new GenericGroovyApplicationContext(); + ctx.load("file:" + getPathPart() + FILE_NAME); + ctx.refresh(); + + BandsBean bb = ctx.getBean(BandsBean.class); + + assertEquals(3, bb.getBandsList() + .size()); + } + + private String getPathPart() { + String pathPart = new File(".").getAbsolutePath(); + pathPart = pathPart.replace(".", ""); + pathPart = pathPart.replace("\\", "/"); + pathPart = pathPart + FILE_PATH; + + return pathPart; + } +} diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java new file mode 100644 index 0000000000..2d9b1000ff --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/JavaConfigurationTest.java @@ -0,0 +1,24 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class JavaConfigurationTest { + + @Test + public void whenJavaConfig_thenCorrectPerson() { + + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(JavaBeanConfig.class); + ctx.refresh(); + + JavaPersonBean j = ctx.getBean(JavaPersonBean.class); + + assertEquals("31", j.getAge()); + assertEquals("green", j.getEyesColor()); + assertEquals("blond", j.getHairColor()); + + } +} diff --git a/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java new file mode 100644 index 0000000000..3ee724207c --- /dev/null +++ b/spring-groovy/src/test/java/com/baeldug/groovyconfig/XmlConfigurationTest.java @@ -0,0 +1,23 @@ +package com.baeldug.groovyconfig; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class XmlConfigurationTest { + + @Test + public void whenXmlConfig_thenCorrectPerson() { + final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("xml-bean-config.xml"); + + JavaPersonBean j = (JavaPersonBean) applicationContext.getBean("JavaPersonBean"); + + assertEquals("30", j.getAge()); + assertEquals("brown", j.getEyesColor()); + assertEquals("brown", j.getHairColor()); + + } + +} From 26f38c1b69f29e92ecef3f2e8988b5a772256a00 Mon Sep 17 00:00:00 2001 From: Hany Ahmed Date: Sat, 28 Oct 2017 04:48:33 +0200 Subject: [PATCH 9/9] JUnit5 with Mockito using @ExtendWith (#2770) * JUnit5 with Mockito using @ExtendWith * rename method: givenUserWithExistingName_whenSaveUser_thenGiveUsernameAlreadyExistsError rename this class according to the standard -- UserServiceUnitTest.java --- junit5/pom.xml | 7 +- .../com/baeldung/junit5/mockito/User.java | 41 ++++++ .../junit5/mockito/repository/MailClient.java | 9 ++ .../mockito/repository/SettingRepository.java | 9 ++ .../mockito/repository/UserRepository.java | 10 ++ .../mockito/service/DefaultUserService.java | 46 +++++++ .../junit5/mockito/service/Errors.java | 10 ++ .../junit5/mockito/service/UserService.java | 9 ++ .../junit5/mockito/MockitoExtension.java | 75 +++++++++++ .../junit5/mockito/UserServiceUnitTest.java | 122 ++++++++++++++++++ 10 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/User.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java create mode 100644 junit5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java create mode 100644 junit5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java create mode 100644 junit5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java diff --git a/junit5/pom.xml b/junit5/pom.xml index 1fa4818447..b820d7b7bc 100644 --- a/junit5/pom.xml +++ b/junit5/pom.xml @@ -19,11 +19,12 @@ UTF-8 1.8 - 5.0.0-RC2 - 1.0.0-RC2 - 4.12.0-RC2 + 5.0.1 + 1.0.1 + 4.12.1 2.8.2 1.4.196 + 2.11.0 3.6.0 2.19.1 diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/User.java b/junit5/src/main/java/com/baeldung/junit5/mockito/User.java new file mode 100644 index 0000000000..4276fd62b9 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/User.java @@ -0,0 +1,41 @@ +package com.baeldung.junit5.mockito; + +public class User { + + private Integer id; + private String name; + private int age; + + public User() { + } + + public User(String name, int age) { + this.name = name; + this.age = age; + } + + public Integer getId() { + return id; + } + public void setId(Integer id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public int getAge() { + return age; + } + public void setAge(int age) { + this.age = age; + } + + @Override + public String toString() { + return "User [id=" + id + ", name=" + name + ", age=" + age + "]"; + } + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java new file mode 100644 index 0000000000..d10169ef7a --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/MailClient.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.repository; + +import com.baeldung.junit5.mockito.User; + +public interface MailClient { + + void sendUserRegistrationMail(User user); + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java new file mode 100644 index 0000000000..23ae8fa35c --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/SettingRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.repository; + +public interface SettingRepository { + + int getUserMinAge(); + + int getUserNameMinLength(); + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java new file mode 100644 index 0000000000..e1b84c774b --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.junit5.mockito.repository; + +import com.baeldung.junit5.mockito.User; + +public interface UserRepository { + + User insert(User user); + boolean isUsernameAlreadyExists(String userName); + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java b/junit5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java new file mode 100644 index 0000000000..888edbd710 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/service/DefaultUserService.java @@ -0,0 +1,46 @@ +package com.baeldung.junit5.mockito.service; + +import com.baeldung.junit5.mockito.User; +import com.baeldung.junit5.mockito.repository.MailClient; +import com.baeldung.junit5.mockito.repository.SettingRepository; +import com.baeldung.junit5.mockito.repository.UserRepository; + +public class DefaultUserService implements UserService { + + private UserRepository userRepository; + private SettingRepository settingRepository; + private MailClient mailClient; + + public DefaultUserService(UserRepository userRepository, SettingRepository settingRepository, MailClient mailClient) { + this.userRepository = userRepository; + this.settingRepository = settingRepository; + this.mailClient = mailClient; + } + + @Override + public User register(User user) { + validate(user); + User insertedUser = userRepository.insert(user); + mailClient.sendUserRegistrationMail(insertedUser); + return insertedUser; + } + + private void validate(User user) { + if(user.getName() == null) { + throw new RuntimeException(Errors.USER_NAME_REQUIRED); + } + + if(user.getName().length() < settingRepository.getUserNameMinLength()) { + throw new RuntimeException(Errors.USER_NAME_SHORT); + } + + if(user.getAge() < settingRepository.getUserMinAge()) { + throw new RuntimeException(Errors.USER_AGE_YOUNG); + } + + if(userRepository.isUsernameAlreadyExists(user.getName())) { + throw new RuntimeException(Errors.USER_NAME_DUPLICATE); + } + } + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java b/junit5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java new file mode 100644 index 0000000000..28283754a3 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/service/Errors.java @@ -0,0 +1,10 @@ +package com.baeldung.junit5.mockito.service; + +public class Errors { + + public static final String USER_NAME_REQUIRED = "user.name.required"; + public static final String USER_NAME_SHORT = "user.name.short"; + public static final String USER_AGE_YOUNG = "user.age.young"; + public static final String USER_NAME_DUPLICATE = "user.name.duplicate"; + +} diff --git a/junit5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java b/junit5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java new file mode 100644 index 0000000000..326d019b4a --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/mockito/service/UserService.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5.mockito.service; + +import com.baeldung.junit5.mockito.User; + +public interface UserService { + + User register(User user); + +} diff --git a/junit5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java b/junit5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java new file mode 100644 index 0000000000..5836ef46e6 --- /dev/null +++ b/junit5/src/test/java/com/baeldung/junit5/mockito/MockitoExtension.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015-2016 the original author or authors. + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution and is available at + * + * http://www.eclipse.org/legal/epl-v10.html + */ + +package com.baeldung.junit5.mockito; + +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Parameter; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ExtensionContext.Namespace; +import org.junit.jupiter.api.extension.ExtensionContext.Store; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.junit.jupiter.api.extension.TestInstancePostProcessor; +import org.mockito.MockitoAnnotations; +import org.mockito.Mock; + +/** + * {@code MockitoExtension} showcases the {@link TestInstancePostProcessor} + * and {@link ParameterResolver} extension APIs of JUnit 5 by providing + * dependency injection support at the field level and at the method parameter + * level via Mockito 2.x's {@link Mock @Mock} annotation. + * + * @since 5.0 + */ +public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver { + + @Override + public void postProcessTestInstance(Object testInstance, ExtensionContext context) { + MockitoAnnotations.initMocks(testInstance); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return parameterContext.getParameter().isAnnotationPresent(Mock.class); + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { + return getMock(parameterContext.getParameter(), extensionContext); + } + + private Object getMock(Parameter parameter, ExtensionContext extensionContext) { + Class mockType = parameter.getType(); + Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType)); + String mockName = getMockName(parameter); + + if (mockName != null) { + return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName)); + } + else { + return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType)); + } + } + + private String getMockName(Parameter parameter) { + String explicitMockName = parameter.getAnnotation(Mock.class).name().trim(); + if (!explicitMockName.isEmpty()) { + return explicitMockName; + } + else if (parameter.isNamePresent()) { + return parameter.getName(); + } + return null; + } + +} \ No newline at end of file diff --git a/junit5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java b/junit5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java new file mode 100644 index 0000000000..1ddab0531a --- /dev/null +++ b/junit5/src/test/java/com/baeldung/junit5/mockito/UserServiceUnitTest.java @@ -0,0 +1,122 @@ +package com.baeldung.junit5.mockito; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import com.baeldung.junit5.mockito.repository.MailClient; +import com.baeldung.junit5.mockito.repository.SettingRepository; +import com.baeldung.junit5.mockito.repository.UserRepository; +import com.baeldung.junit5.mockito.service.DefaultUserService; +import com.baeldung.junit5.mockito.service.Errors; +import com.baeldung.junit5.mockito.service.UserService; + +@RunWith(JUnitPlatform.class) +@ExtendWith(MockitoExtension.class) +public class UserServiceUnitTest { + + UserService userService; + @Mock UserRepository userRepository; + + User user; + + @BeforeEach + void init(@Mock SettingRepository settingRepository, @Mock MailClient mailClient) { + userService = new DefaultUserService(userRepository, settingRepository, mailClient); + when(settingRepository.getUserMinAge()).thenReturn(10); + when(settingRepository.getUserNameMinLength()).thenReturn(4); + when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false); + } + + @Test + void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) { + // Given + user = new User("Jerry", 12); + when(userRepository.insert(any(User.class))).then(new Answer() { + int sequence = 1; + + @Override + public User answer(InvocationOnMock invocation) throws Throwable { + User user = (User) invocation.getArgument(0); + user.setId(sequence++); + return user; + } + }); + + // When + User insertedUser = userService.register(user); + + // Then + verify(userRepository).insert(user); + Assertions.assertNotNull(user.getId()); + verify(mailClient).sendUserRegistrationMail(insertedUser); + } + + @Test + void givenShortName_whenSaveUser_thenGiveShortUsernameError() { + // Given + user = new User("tom", 12); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_NAME_SHORT); + } + + // Then + verify(userRepository, never()).insert(user); + } + + @Test + void givenSmallAge_whenSaveUser_thenGiveYoungUserError() { + // Given + user = new User("jerry", 3); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_AGE_YOUNG); + } + + // Then + verify(userRepository, never()).insert(user); + } + + @Test + void givenUserWithExistingName_whenSaveUser_thenGiveUsernameAlreadyExistsError() { + // Given + user = new User("jerry", 12); + Mockito.reset(userRepository); + when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(true); + + // When + try { + userService.register(user); + fail("Should give an error"); + } catch(Exception ex) { + assertEquals(ex.getMessage(), Errors.USER_NAME_DUPLICATE); + } + + // Then + verify(userRepository, never()).insert(user); + } + +}