From 9c39406c1686c4f3ddc637a8b85914a970639404 Mon Sep 17 00:00:00 2001 From: Pritam Banerjee Date: Sun, 26 Feb 2017 04:31:19 -0800 Subject: [PATCH 01/78] BAEL - 626 : EJB: Stateless and Stateful Session Beans(Initial Commit) --- ejb/ejb-session-beans-client/pom.xml | 54 +++++++++++ .../ejb/session/client/EJBStatefulClient.java | 85 +++++++++++++++++ .../session/client/EJBStatelessClient.java | 88 +++++++++++++++++ .../resources/jboss-ejb-client.properties | 8 ++ .../client/test/EJBStatefulClientTest.java | 17 ++++ .../client/test/EJBStatelessClientTest.java | 16 ++++ ejb/ejb-session-beans/pom.xml | 95 +++++++++++++++++++ .../ejb/stateful/beans/ItemStateful.java | 27 ++++++ .../stateful/beans/ItemStatefulRemote.java | 14 +++ .../ejb/stateless/beans/ItemStateless.java | 29 ++++++ .../stateless/beans/ItemStatelessRemote.java | 13 +++ .../src/main/resources/META-INF/ejb-jar.xml | 6 ++ ejb/pom.xml | 9 +- 13 files changed, 460 insertions(+), 1 deletion(-) create mode 100644 ejb/ejb-session-beans-client/pom.xml create mode 100644 ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java create mode 100644 ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java create mode 100755 ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties create mode 100644 ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java create mode 100644 ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java create mode 100644 ejb/ejb-session-beans/pom.xml create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java create mode 100755 ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml diff --git a/ejb/ejb-session-beans-client/pom.xml b/ejb/ejb-session-beans-client/pom.xml new file mode 100644 index 0000000000..b5e107f23a --- /dev/null +++ b/ejb/ejb-session-beans-client/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + com.baeldung.ejb + ejb + 1.0-SNAPSHOT + + ejb-session-beans-client + EJB3 Client Maven + EJB3 Client Maven + + + 4.12 + 2.19 + + + + + org.wildfly + wildfly-ejb-client-bom + pom + import + + + + com.baeldung.ejb + ejb-session-beans + ejb + + + + junit + junit + 4.12 + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.19 + + + **/*EJBSetupTest.java + + + + + + \ No newline at end of file diff --git a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java new file mode 100644 index 0000000000..b2f79a2b13 --- /dev/null +++ b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java @@ -0,0 +1,85 @@ +package com.baeldung.ejb.session.client; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import com.baeldung.ejb.stateful.beans.ItemStatefulRemote; + +public class EJBStatefulClient { + + public EJBStatefulClient() { + } + + private Context context = null; + + public Boolean getEJBRemoteMessage() { + EJBStatefulClient ejb = new EJBStatefulClient(); + Boolean result = true; + try { + // 1. Obtaining Context + ejb.createInitialContext(); + // 2. Generate JNDI Lookup name and caste + ItemStatefulRemote itemStatefulOne = ejb.lookup(); + ItemStatefulRemote itemStatefulTwo = ejb.lookup(); + + itemStatefulOne.addItem("Book"); + itemStatefulOne.addItem("Pen"); + itemStatefulOne.addItem("Copy"); + itemStatefulOne.addItem("Pencil"); + + result = itemStatefulOne.getItemList().equals(itemStatefulTwo.getItemList()); + + return result; + } catch (NamingException e) { + e.printStackTrace(); + return false; + } finally { + try { + ejb.closeContext(); + } catch (NamingException e) { + e.printStackTrace(); + + } + } + } + + public ItemStatefulRemote lookup() throws NamingException { + + // The app name is the EAR name of the deployed EJB without .ear suffix. + // Since we haven't deployed the application as a .ear, the app name for + // us will be an empty string + final String appName = ""; + final String moduleName = "session-beans"; + final String distinctName = ""; + final String beanName = "ItemStatefulRemote"; + final String viewClassName = ItemStatefulRemote.class.getName() + "?stateful"; + final String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName, + viewClassName); + return (ItemStatefulRemote) context.lookup(toLookup); + } + + public void createInitialContext() throws NamingException { + Properties prop = new Properties(); + prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); + prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); + prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); + prop.put(Context.SECURITY_PRINCIPAL, "testUser"); + prop.put(Context.SECURITY_CREDENTIALS, "admin1234!"); + prop.put("jboss.naming.client.ejb.context", false); + + context = new InitialContext(prop); + } + + public void closeContext() throws NamingException { + if (context != null) { + context.close(); + } + } + +} diff --git a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java new file mode 100644 index 0000000000..3d00771a07 --- /dev/null +++ b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java @@ -0,0 +1,88 @@ +package com.baeldung.ejb.session.client; + +import java.util.List; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import com.baeldung.ejb.stateless.beans.ItemStatelessRemote; + +public class EJBStatelessClient { + + public EJBStatelessClient() { + } + + private Context context = null; + + public static void main(String[] arg) { + EJBStatelessClient ejb = new EJBStatelessClient(); + System.out.println(ejb.getEJBRemoteMessage()); + + } + + public Boolean getEJBRemoteMessage() { + EJBStatelessClient main = new EJBStatelessClient(); + Boolean result = true; + try { + // 1. Obtaining Context + main.createInitialContext(); + // 2. Generate JNDI Lookup name and caste + ItemStatelessRemote itemStatelessOne = main.lookup(); + ItemStatelessRemote itemStatelessTwo = main.lookup(); + + itemStatelessOne.addItem("Book"); + itemStatelessOne.addItem("Pen"); + itemStatelessOne.addItem("Pencil"); + itemStatelessOne.addItem("Eraser"); + + result = itemStatelessOne.getItemList().equals(itemStatelessTwo.getItemList()); + + return result; + } catch (NamingException e) { + e.printStackTrace(); + return false; + } finally { + try { + main.closeContext(); + } catch (NamingException e) { + e.printStackTrace(); + } + } + } + + public ItemStatelessRemote lookup() throws NamingException { + + // The app name is the EAR name of the deployed EJB without .ear suffix. + // Since we haven't deployed the application as a .ear, the app name for + // us will be an empty string + final String appName = ""; + final String moduleName = "session-beans"; + final String distinctName = ""; + final String beanName = "ItemStatelessRemote"; + final String viewClassName = ItemStatelessRemote.class.getName(); + final String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName, viewClassName); + + return (ItemStatelessRemote) context.lookup(toLookup); + } + + public void createInitialContext() throws NamingException { + Properties prop = new Properties(); + prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); + prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); + prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); + prop.put(Context.SECURITY_PRINCIPAL, "testUser"); + prop.put(Context.SECURITY_CREDENTIALS, "admin1234!"); + prop.put("jboss.naming.client.ejb.context", false); + + context = new InitialContext(prop); + } + + public void closeContext() throws NamingException { + if (context != null) { + context.close(); + } + } + +} diff --git a/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties b/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties new file mode 100755 index 0000000000..077cd7583f --- /dev/null +++ b/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties @@ -0,0 +1,8 @@ +remote.connections=default +remote.connection.default.host=127.0.0.1 +remote.connection.default.port=8080 +remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false +remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false +remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=${host.auth:JBOSS-LOCAL-USER} +remote.connection.default.username=testUser +remote.connection.default.password=admin1234! \ No newline at end of file diff --git a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java new file mode 100644 index 0000000000..670dacc7aa --- /dev/null +++ b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java @@ -0,0 +1,17 @@ +package com.baeldung.ejb.session.client.test; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.baeldung.ejb.session.client.EJBStatefulClient; + +public class EJBStatefulClientTest { + + @Test + public void EJBClientTest() { + EJBStatefulClient ejbStatefulClient = new EJBStatefulClient(); + assertFalse(ejbStatefulClient.getEJBRemoteMessage()); + } + +} diff --git a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java new file mode 100644 index 0000000000..90e3106130 --- /dev/null +++ b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java @@ -0,0 +1,16 @@ +package com.baeldung.ejb.session.client.test; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import com.baeldung.ejb.session.client.EJBStatelessClient; + +public class EJBStatelessClientTest { + + @Test + public void EJBClientTest() { + EJBStatelessClient ejbStatelessClient = new EJBStatelessClient(); + assertTrue(ejbStatelessClient.getEJBRemoteMessage()); + } + +} diff --git a/ejb/ejb-session-beans/pom.xml b/ejb/ejb-session-beans/pom.xml new file mode 100644 index 0000000000..c1b908c0aa --- /dev/null +++ b/ejb/ejb-session-beans/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + + com.baeldung.ejb + ejb + 1.0-SNAPSHOT + + + ejb-session-beans + ejb + + + + javax + javaee-api + ${javaee-api.version} + provided + + + + + + + + wildfly-standalone + + true + + + + + org.codehaus.cargo + cargo-maven2-plugin + ${cargo-maven2-plugin.version} + + + + + wildfly10x + + http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip + + + + + + 127.0.0.1 + 9990 + testUser:admin1234! + + + + + + + + + + + + wildfly-runtime + + false + + + + + org.wildfly.plugins + wildfly-maven-plugin + 1.1.0.Alpha5 + + 127.0.0.1 + 9990 + testUser + admin1234! + ${build.finalName}.jar + + + + + + + + + + 7.0 + 1.6.1 + + + + + diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java new file mode 100644 index 0000000000..faab0bd4b1 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java @@ -0,0 +1,27 @@ +package com.baeldung.ejb.stateful.beans; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Stateful; + +@Stateful(name = "ItemStatefulRemote") +public class ItemStateful implements ItemStatefulRemote { + + private List itemList; + + public ItemStateful() { + itemList = new ArrayList(); + } + + @Override + public void addItem(String itemName) { + itemList.add(itemName); + } + + @Override + public List getItemList() { + return itemList; + } + +} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java new file mode 100644 index 0000000000..0d5313772d --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java @@ -0,0 +1,14 @@ +package com.baeldung.ejb.stateful.beans; + +import java.util.List; + +import javax.ejb.Remote; + +@Remote +public interface ItemStatefulRemote { + + void addItem(String itemName); + + List getItemList(); + +} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java new file mode 100644 index 0000000000..23d24a5f21 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java @@ -0,0 +1,29 @@ +package com.baeldung.ejb.stateless.beans; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Stateless; + +@Stateless(name = "ItemStatelessRemote") +public class ItemStateless implements ItemStatelessRemote { + + private List itemList; + + public ItemStateless() { + itemList = new ArrayList(); + } + + @Override + public void addItem(String itemName) { + + itemList.add(itemName); + } + + @Override + public List getItemList() { + + return itemList; + } + +} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java new file mode 100644 index 0000000000..2ed2029cc8 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java @@ -0,0 +1,13 @@ +package com.baeldung.ejb.stateless.beans; + +import java.util.List; + +import javax.ejb.Remote; + +@Remote +public interface ItemStatelessRemote { + + void addItem(String itemName); + + List getItemList(); +} diff --git a/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml b/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml new file mode 100755 index 0000000000..7ae4711863 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml @@ -0,0 +1,6 @@ + + + session-beans + \ No newline at end of file diff --git a/ejb/pom.xml b/ejb/pom.xml index bfcc972417..c8ffcc4a55 100755 --- a/ejb/pom.xml +++ b/ejb/pom.xml @@ -34,7 +34,12 @@ 1.0-SNAPSHOT ejb - + + com.baeldung.ejb + ejb-session-beans + 1.0-SNAPSHOT + ejb + javax javaee-api @@ -78,5 +83,7 @@ ejb-remote ejb-client + ejb-session-beans + ejb-session-beans-client \ No newline at end of file From 0ebaefcb958ce6e5fdcbb3be22c0f2aec0184b74 Mon Sep 17 00:00:00 2001 From: Pritam Banerjee Date: Thu, 18 May 2017 23:56:44 -0700 Subject: [PATCH 02/78] session beans --- ejb/ejb-session-beans-client/pom.xml | 54 ------ .../ejb/session/client/EJBStatefulClient.java | 85 --------- .../session/client/EJBStatelessClient.java | 88 ---------- .../resources/jboss-ejb-client.properties | 8 - .../client/test/EJBStatefulClientTest.java | 17 -- .../client/test/EJBStatelessClientTest.java | 16 -- ejb/ejb-session-beans/pom.xml | 163 ++++++++++-------- .../ejb/stateful/beans/ItemStateful.java | 27 --- .../stateful/beans/ItemStatefulRemote.java | 14 -- .../ejb/stateless/beans/ItemStateless.java | 29 ---- .../stateless/beans/ItemStatelessRemote.java | 13 -- .../readlearncode/stateful/EJBClient1.java | 17 ++ .../readlearncode/stateful/EJBClient2.java | 17 ++ .../readlearncode/stateful/StatefulEJB.java | 16 ++ .../readlearncode/stateless/EJBClient1.java | 16 ++ .../readlearncode/stateless/EJBClient2.java | 17 ++ .../readlearncode/stateless/StatelessEJB.java | 16 ++ .../src/main/resources/META-INF/ejb-jar.xml | 6 - .../stateful/StatefulEJBTest.java | 52 ++++++ .../stateless/StatelessEJBTest.java | 63 +++++++ 20 files changed, 301 insertions(+), 433 deletions(-) delete mode 100644 ejb/ejb-session-beans-client/pom.xml delete mode 100644 ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java delete mode 100644 ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java delete mode 100755 ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties delete mode 100644 ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java delete mode 100644 ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java delete mode 100755 ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml create mode 100644 ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java create mode 100644 ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java diff --git a/ejb/ejb-session-beans-client/pom.xml b/ejb/ejb-session-beans-client/pom.xml deleted file mode 100644 index b5e107f23a..0000000000 --- a/ejb/ejb-session-beans-client/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - 4.0.0 - - com.baeldung.ejb - ejb - 1.0-SNAPSHOT - - ejb-session-beans-client - EJB3 Client Maven - EJB3 Client Maven - - - 4.12 - 2.19 - - - - - org.wildfly - wildfly-ejb-client-bom - pom - import - - - - com.baeldung.ejb - ejb-session-beans - ejb - - - - junit - junit - 4.12 - test - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.19 - - - **/*EJBSetupTest.java - - - - - - \ No newline at end of file diff --git a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java deleted file mode 100644 index b2f79a2b13..0000000000 --- a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatefulClient.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.baeldung.ejb.session.client; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -import com.baeldung.ejb.stateful.beans.ItemStatefulRemote; - -public class EJBStatefulClient { - - public EJBStatefulClient() { - } - - private Context context = null; - - public Boolean getEJBRemoteMessage() { - EJBStatefulClient ejb = new EJBStatefulClient(); - Boolean result = true; - try { - // 1. Obtaining Context - ejb.createInitialContext(); - // 2. Generate JNDI Lookup name and caste - ItemStatefulRemote itemStatefulOne = ejb.lookup(); - ItemStatefulRemote itemStatefulTwo = ejb.lookup(); - - itemStatefulOne.addItem("Book"); - itemStatefulOne.addItem("Pen"); - itemStatefulOne.addItem("Copy"); - itemStatefulOne.addItem("Pencil"); - - result = itemStatefulOne.getItemList().equals(itemStatefulTwo.getItemList()); - - return result; - } catch (NamingException e) { - e.printStackTrace(); - return false; - } finally { - try { - ejb.closeContext(); - } catch (NamingException e) { - e.printStackTrace(); - - } - } - } - - public ItemStatefulRemote lookup() throws NamingException { - - // The app name is the EAR name of the deployed EJB without .ear suffix. - // Since we haven't deployed the application as a .ear, the app name for - // us will be an empty string - final String appName = ""; - final String moduleName = "session-beans"; - final String distinctName = ""; - final String beanName = "ItemStatefulRemote"; - final String viewClassName = ItemStatefulRemote.class.getName() + "?stateful"; - final String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName, - viewClassName); - return (ItemStatefulRemote) context.lookup(toLookup); - } - - public void createInitialContext() throws NamingException { - Properties prop = new Properties(); - prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); - prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); - prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); - prop.put(Context.SECURITY_PRINCIPAL, "testUser"); - prop.put(Context.SECURITY_CREDENTIALS, "admin1234!"); - prop.put("jboss.naming.client.ejb.context", false); - - context = new InitialContext(prop); - } - - public void closeContext() throws NamingException { - if (context != null) { - context.close(); - } - } - -} diff --git a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java b/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java deleted file mode 100644 index 3d00771a07..0000000000 --- a/ejb/ejb-session-beans-client/src/main/java/com/baeldung/ejb/session/client/EJBStatelessClient.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.baeldung.ejb.session.client; - -import java.util.List; -import java.util.Properties; - -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -import com.baeldung.ejb.stateless.beans.ItemStatelessRemote; - -public class EJBStatelessClient { - - public EJBStatelessClient() { - } - - private Context context = null; - - public static void main(String[] arg) { - EJBStatelessClient ejb = new EJBStatelessClient(); - System.out.println(ejb.getEJBRemoteMessage()); - - } - - public Boolean getEJBRemoteMessage() { - EJBStatelessClient main = new EJBStatelessClient(); - Boolean result = true; - try { - // 1. Obtaining Context - main.createInitialContext(); - // 2. Generate JNDI Lookup name and caste - ItemStatelessRemote itemStatelessOne = main.lookup(); - ItemStatelessRemote itemStatelessTwo = main.lookup(); - - itemStatelessOne.addItem("Book"); - itemStatelessOne.addItem("Pen"); - itemStatelessOne.addItem("Pencil"); - itemStatelessOne.addItem("Eraser"); - - result = itemStatelessOne.getItemList().equals(itemStatelessTwo.getItemList()); - - return result; - } catch (NamingException e) { - e.printStackTrace(); - return false; - } finally { - try { - main.closeContext(); - } catch (NamingException e) { - e.printStackTrace(); - } - } - } - - public ItemStatelessRemote lookup() throws NamingException { - - // The app name is the EAR name of the deployed EJB without .ear suffix. - // Since we haven't deployed the application as a .ear, the app name for - // us will be an empty string - final String appName = ""; - final String moduleName = "session-beans"; - final String distinctName = ""; - final String beanName = "ItemStatelessRemote"; - final String viewClassName = ItemStatelessRemote.class.getName(); - final String toLookup = String.format("ejb:%s/%s/%s/%s!%s", appName, moduleName, distinctName, beanName, viewClassName); - - return (ItemStatelessRemote) context.lookup(toLookup); - } - - public void createInitialContext() throws NamingException { - Properties prop = new Properties(); - prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); - prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); - prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); - prop.put(Context.SECURITY_PRINCIPAL, "testUser"); - prop.put(Context.SECURITY_CREDENTIALS, "admin1234!"); - prop.put("jboss.naming.client.ejb.context", false); - - context = new InitialContext(prop); - } - - public void closeContext() throws NamingException { - if (context != null) { - context.close(); - } - } - -} diff --git a/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties b/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties deleted file mode 100755 index 077cd7583f..0000000000 --- a/ejb/ejb-session-beans-client/src/main/resources/jboss-ejb-client.properties +++ /dev/null @@ -1,8 +0,0 @@ -remote.connections=default -remote.connection.default.host=127.0.0.1 -remote.connection.default.port=8080 -remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false -remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false -remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=${host.auth:JBOSS-LOCAL-USER} -remote.connection.default.username=testUser -remote.connection.default.password=admin1234! \ No newline at end of file diff --git a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java deleted file mode 100644 index 670dacc7aa..0000000000 --- a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatefulClientTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.ejb.session.client.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.baeldung.ejb.session.client.EJBStatefulClient; - -public class EJBStatefulClientTest { - - @Test - public void EJBClientTest() { - EJBStatefulClient ejbStatefulClient = new EJBStatefulClient(); - assertFalse(ejbStatefulClient.getEJBRemoteMessage()); - } - -} diff --git a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java b/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java deleted file mode 100644 index 90e3106130..0000000000 --- a/ejb/ejb-session-beans-client/src/test/java/com/baeldung/ejb/session/client/test/EJBStatelessClientTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.ejb.session.client.test; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import com.baeldung.ejb.session.client.EJBStatelessClient; - -public class EJBStatelessClientTest { - - @Test - public void EJBClientTest() { - EJBStatelessClient ejbStatelessClient = new EJBStatelessClient(); - assertTrue(ejbStatelessClient.getEJBRemoteMessage()); - } - -} diff --git a/ejb/ejb-session-beans/pom.xml b/ejb/ejb-session-beans/pom.xml index c1b908c0aa..a9b667baac 100644 --- a/ejb/ejb-session-beans/pom.xml +++ b/ejb/ejb-session-beans/pom.xml @@ -1,95 +1,106 @@ - - - 4.0.0 + + 4.0.0 + + com.baeldung.ejb + ejb + 1.0-SNAPSHOT + + ejb-session-beans + + + UTF-8 + 1.1.12.Final + 2.2.6 + 1.1.12.Final + 1.0.0.Final + 4.12 + 7.0 + - - com.baeldung.ejb - ejb - 1.0-SNAPSHOT - - - ejb-session-beans - ejb + + + + org.jboss.arquillian + arquillian-bom + 1.1.13.Final + import + pom + + + + javax javaee-api ${javaee-api.version} provided + + + + junit + junit + 4.12 + test + + + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + - - - wildfly-standalone + arquillian-glassfish-embedded true - - - - org.codehaus.cargo - cargo-maven2-plugin - ${cargo-maven2-plugin.version} - - - - - wildfly10x - - http://download.jboss.org/wildfly/10.1.0.Final/wildfly-10.1.0.Final.zip - - - - - - 127.0.0.1 - 9990 - testUser:admin1234! - - - - - - - + + + org.jboss.arquillian.container + arquillian-glassfish-embedded-3.1 + 1.0.0.CR4 + test + + + org.glassfish.main.extras + glassfish-embedded-all + 3.1.2 + test + + - - - - wildfly-runtime - - false - - - - - org.wildfly.plugins - wildfly-maven-plugin - 1.1.0.Alpha5 - - 127.0.0.1 - 9990 - testUser - admin1234! - ${build.finalName}.jar - - - - - - - - 7.0 - 1.6.1 - - - - - + + + + maven-compiler-plugin + 3.1 + + 1.8 + 1.8 + + + + maven-war-plugin + 2.4 + + false + + + + maven-surefire-plugin + 2.17 + + + + + + \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java deleted file mode 100644 index faab0bd4b1..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStateful.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.ejb.stateful.beans; - -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.Stateful; - -@Stateful(name = "ItemStatefulRemote") -public class ItemStateful implements ItemStatefulRemote { - - private List itemList; - - public ItemStateful() { - itemList = new ArrayList(); - } - - @Override - public void addItem(String itemName) { - itemList.add(itemName); - } - - @Override - public List getItemList() { - return itemList; - } - -} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java deleted file mode 100644 index 0d5313772d..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/beans/ItemStatefulRemote.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.ejb.stateful.beans; - -import java.util.List; - -import javax.ejb.Remote; - -@Remote -public interface ItemStatefulRemote { - - void addItem(String itemName); - - List getItemList(); - -} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java deleted file mode 100644 index 23d24a5f21..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStateless.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.ejb.stateless.beans; - -import java.util.ArrayList; -import java.util.List; - -import javax.ejb.Stateless; - -@Stateless(name = "ItemStatelessRemote") -public class ItemStateless implements ItemStatelessRemote { - - private List itemList; - - public ItemStateless() { - itemList = new ArrayList(); - } - - @Override - public void addItem(String itemName) { - - itemList.add(itemName); - } - - @Override - public List getItemList() { - - return itemList; - } - -} diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java deleted file mode 100644 index 2ed2029cc8..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/beans/ItemStatelessRemote.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.ejb.stateless.beans; - -import java.util.List; - -import javax.ejb.Remote; - -@Remote -public interface ItemStatelessRemote { - - void addItem(String itemName); - - List getItemList(); -} diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java new file mode 100644 index 0000000000..a61a3fef0c --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java @@ -0,0 +1,17 @@ +package com.readlearncode.stateful; + +import javax.ejb.EJB; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +public class EJBClient1 { + + @EJB + public StatefulEJB statefulEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java new file mode 100644 index 0000000000..350df5ff86 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java @@ -0,0 +1,17 @@ +package com.readlearncode.stateful; + +import javax.ejb.EJB; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +public class EJBClient2 { + + @EJB + public StatefulEJB statefulEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java new file mode 100644 index 0000000000..771508584e --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java @@ -0,0 +1,16 @@ +package com.readlearncode.stateful; + +import javax.ejb.Stateful; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +@Stateful +public class StatefulEJB { + + public String name; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java new file mode 100644 index 0000000000..e8e6e79a2d --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java @@ -0,0 +1,16 @@ +package com.readlearncode.stateless; + +import javax.ejb.EJB; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +public class EJBClient1 { + + @EJB + public StatelessEJB statelessEJB; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java new file mode 100644 index 0000000000..ff90f2fcf1 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java @@ -0,0 +1,17 @@ +package com.readlearncode.stateless; + +import javax.ejb.EJB; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +public class EJBClient2 { + + @EJB + public StatelessEJB statelessEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java new file mode 100644 index 0000000000..1f60d12e71 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java @@ -0,0 +1,16 @@ +package com.readlearncode.stateless; + +import javax.ejb.Stateless; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +@Stateless +public class StatelessEJB { + + public String name; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml b/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml deleted file mode 100755 index 7ae4711863..0000000000 --- a/ejb/ejb-session-beans/src/main/resources/META-INF/ejb-jar.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - session-beans - \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java new file mode 100644 index 0000000000..04d01975f6 --- /dev/null +++ b/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java @@ -0,0 +1,52 @@ +package com.readlearncode.stateful; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.inject.Inject; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +@RunWith(Arquillian.class) +public class StatefulEJBTest { + + @Inject + private EJBClient1 ejbClient1; + + @Inject + private EJBClient2 ejbClient2; + + @Test + public void givenOneStatefulBean_whenTwoClientsSetValueOnBean_thenClientStateIsMaintained() { + + // act + ejbClient1.statefulEJB.name = "Client 1"; + ejbClient2.statefulEJB.name = "Client 2"; + + // assert + Assert.assertNotEquals(ejbClient1.statefulEJB.name, ejbClient2.statefulEJB.name); + Assert.assertEquals("Client 1", ejbClient1.statefulEJB.name); + Assert.assertEquals("Client 2", ejbClient2.statefulEJB.name); + + } + + @Deployment + public static JavaArchive createDeployment() { + return ShrinkWrap.create(JavaArchive.class) + .addClass(StatefulEJB.class) + .addClass(EJBClient1.class) + .addClass(EJBClient2.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + } + +} diff --git a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java new file mode 100644 index 0000000000..8c7d3e1bc9 --- /dev/null +++ b/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java @@ -0,0 +1,63 @@ +package com.readlearncode.stateless; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.inject.Inject; + +/** + * Source code github.com/readlearncode + * + * @author Alex Theedom www.readlearncode.com + * @version 1.0 + */ +@RunWith(Arquillian.class) +public class StatelessEJBTest { + + @Inject + private EJBClient1 ejbClient1; + + @Inject + private EJBClient2 ejbClient2; + + @Test + public void givenOneStatelessBean_whenStateIsSetInOneBean_secondBeanShouldHaveSameState() { + + // act + ejbClient1.statelessEJB.name = "Client 1"; + + // assert + Assert.assertEquals("Client 1", ejbClient1.statelessEJB.name); + Assert.assertEquals("Client 1", ejbClient2.statelessEJB.name); + + } + + + @Test + public void givenOneStatelessBean_whenStateIsSetInBothBeans_secondBeanShouldHaveSecondBeanState() { + + // act + ejbClient1.statelessEJB.name = "Client 1"; + ejbClient2.statelessEJB.name = "Client 2"; + + // assert + Assert.assertEquals("Client 2", ejbClient2.statelessEJB.name); + + } + + @Deployment + public static JavaArchive createDeployment() { + return ShrinkWrap.create(JavaArchive.class) + .addClass(StatelessEJB.class) + .addClass(EJBClient1.class) + .addClass(EJBClient2.class) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + } + +} From cfc44ecbb67aa6233a3d51afb781bd3eb04dccaf Mon Sep 17 00:00:00 2001 From: Mohamed Sanaulla Date: Sat, 20 May 2017 20:21:33 +0300 Subject: [PATCH 03/78] code for BAEL-860 - Introduction to mustache (#1885) --- mustache/pom.xml | 77 +++++++++++++ .../com/baeldung/mustache/MustacheUtil.java | 15 +++ .../com/baeldung/mustache/model/Todo.java | 84 +++++++++++++++ .../src/main/resources/todo-section.mustache | 5 + mustache/src/main/resources/todo.mustache | 3 + .../resources/todos-inverted-section.mustache | 6 ++ .../src/main/resources/todos-lambda.mustache | 3 + mustache/src/main/resources/todos.mustache | 3 + .../mustache/TodoMustacheServiceTest.java | 102 ++++++++++++++++++ pom.xml | 1 + 10 files changed, 299 insertions(+) create mode 100644 mustache/pom.xml create mode 100644 mustache/src/main/java/com/baeldung/mustache/MustacheUtil.java create mode 100644 mustache/src/main/java/com/baeldung/mustache/model/Todo.java create mode 100644 mustache/src/main/resources/todo-section.mustache create mode 100644 mustache/src/main/resources/todo.mustache create mode 100644 mustache/src/main/resources/todos-inverted-section.mustache create mode 100644 mustache/src/main/resources/todos-lambda.mustache create mode 100644 mustache/src/main/resources/todos.mustache create mode 100644 mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java diff --git a/mustache/pom.xml b/mustache/pom.xml new file mode 100644 index 0000000000..8916b196f0 --- /dev/null +++ b/mustache/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + com.baeldung + mustache + 0.0.1-SNAPSHOT + jar + mustache + + + + com.github.spullara.mustache.java + compiler + ${mustache.compiler.api.version} + + + + org.assertj + assertj-core + ${assertj.version} + + + + + log4j + log4j + ${log4j.version} + + + junit + junit + ${junit.version} + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + 0.9.2 + 3.7.0 + 1.2.16 + 4.12 + + UTF-8 + + + 3.6.0 + 2.19.1 + + + \ No newline at end of file diff --git a/mustache/src/main/java/com/baeldung/mustache/MustacheUtil.java b/mustache/src/main/java/com/baeldung/mustache/MustacheUtil.java new file mode 100644 index 0000000000..a30bb23adb --- /dev/null +++ b/mustache/src/main/java/com/baeldung/mustache/MustacheUtil.java @@ -0,0 +1,15 @@ +package com.baeldung.mustache; + +import com.github.mustachejava.DefaultMustacheFactory; +import com.github.mustachejava.MustacheFactory; + +public class MustacheUtil { + + private static final MustacheFactory mf = new DefaultMustacheFactory(); + + public static MustacheFactory getMustacheFactory(){ + return mf; + } + + +} diff --git a/mustache/src/main/java/com/baeldung/mustache/model/Todo.java b/mustache/src/main/java/com/baeldung/mustache/model/Todo.java new file mode 100644 index 0000000000..c329045876 --- /dev/null +++ b/mustache/src/main/java/com/baeldung/mustache/model/Todo.java @@ -0,0 +1,84 @@ +package com.baeldung.mustache.model; + +import java.time.Duration; +import java.time.temporal.Temporal; +import java.util.Date; +import java.util.function.Function; + +public class Todo { + + public Todo(){} + + public Todo(String title, String text){ + this.title = title; + this.text = text; + createdOn = new Date(); + } + + private String title; + private String text; + private boolean done = false; + + private Date createdOn; + private Date completedOn; + + public void markAsDone(){ + done = true; + completedOn = new Date(); + } + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public boolean getDone() { + return done; + } + + public Date getCreatedOn() { + return createdOn; + } + + public Date getCompletedOn() { + return completedOn; + } + + public void setDone(boolean done) { + this.done = done; + } + + public void setCompletedOn(Date completedOn) { + this.completedOn = completedOn; + } + + public long doneSince(){ + if ( done ){ + return Duration.between(createdOn.toInstant(), completedOn.toInstant()).toMinutes(); + } + return 0; + } + + public Function handleDone(){ + return (obj) -> { + if ( done ){ + return String.format("Done %s minutes ago", obj); + }else{ + return ""; + } + + }; + + } + +} diff --git a/mustache/src/main/resources/todo-section.mustache b/mustache/src/main/resources/todo-section.mustache new file mode 100644 index 0000000000..f05be6f553 --- /dev/null +++ b/mustache/src/main/resources/todo-section.mustache @@ -0,0 +1,5 @@ +{{#todo}} +

{{title}}

+Created on {{createdOn}} +

{{text}}

+{{/todo}} diff --git a/mustache/src/main/resources/todo.mustache b/mustache/src/main/resources/todo.mustache new file mode 100644 index 0000000000..5cd7a99ff5 --- /dev/null +++ b/mustache/src/main/resources/todo.mustache @@ -0,0 +1,3 @@ +

{{title}}

+Created on {{createdOn}} +

{{text}}

\ No newline at end of file diff --git a/mustache/src/main/resources/todos-inverted-section.mustache b/mustache/src/main/resources/todos-inverted-section.mustache new file mode 100644 index 0000000000..5d3cd16c73 --- /dev/null +++ b/mustache/src/main/resources/todos-inverted-section.mustache @@ -0,0 +1,6 @@ +{{#todos}} +

{{title}}

+{{/todos}} +{{^todos}} +

No todos!

+{{/todos}} \ No newline at end of file diff --git a/mustache/src/main/resources/todos-lambda.mustache b/mustache/src/main/resources/todos-lambda.mustache new file mode 100644 index 0000000000..c89a7bc4c5 --- /dev/null +++ b/mustache/src/main/resources/todos-lambda.mustache @@ -0,0 +1,3 @@ +{{#todos}} +

{{title}}{{#handleDone}}{{doneSince}}{{/handleDone}}

+{{/todos}} \ No newline at end of file diff --git a/mustache/src/main/resources/todos.mustache b/mustache/src/main/resources/todos.mustache new file mode 100644 index 0000000000..90722e74bb --- /dev/null +++ b/mustache/src/main/resources/todos.mustache @@ -0,0 +1,3 @@ +{{#todos}} +

{{title}}

+{{/todos}} \ No newline at end of file diff --git a/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java b/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java new file mode 100644 index 0000000000..17a59aa6a1 --- /dev/null +++ b/mustache/src/test/java/com/baeldung/mustache/TodoMustacheServiceTest.java @@ -0,0 +1,102 @@ +package com.baeldung.mustache; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.io.StringWriter; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.temporal.TemporalUnit; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.junit.Test; + +import com.baeldung.mustache.model.Todo; +import com.github.mustachejava.Mustache; +public class TodoMustacheServiceTest { + + private String executeTemplate(Mustache m, Map context) throws IOException{ + StringWriter writer = new StringWriter(); + m.execute(writer, context).flush(); + return writer.toString(); + } + + private String executeTemplate(Mustache m, Todo todo) throws IOException{ + StringWriter writer = new StringWriter(); + m.execute(writer, todo).flush(); + return writer.toString(); + } + + @Test + public void givenTodoObject_whenGetHtml_thenSuccess() throws IOException{ + Todo todo = new Todo("Todo 1", "Todo description"); + Mustache m = MustacheUtil.getMustacheFactory().compile("todo.mustache"); + Map context = new HashMap<>(); + context.put("todo", todo); + + String expected = "

Todo 1

"; + assertThat(executeTemplate(m, todo)).contains(expected); + } + + @Test + public void givenNullTodoObject_whenGetHtml_thenEmptyHtml() throws IOException{ + Mustache m = MustacheUtil.getMustacheFactory().compile("todo-section.mustache"); + Map context = new HashMap<>(); + assertThat(executeTemplate(m, context)).isEmpty(); + } + + @Test + public void givenTodoList_whenGetHtml_thenSuccess() throws IOException{ + Mustache m = MustacheUtil.getMustacheFactory().compile("todos.mustache"); + + List todos = Arrays.asList( + new Todo("Todo 1", "Todo description"), + new Todo("Todo 2", "Todo description another"), + new Todo("Todo 3", "Todo description another") + ); + Map context = new HashMap<>(); + context.put("todos", todos); + + assertThat(executeTemplate(m, context)) + .contains("

Todo 1

") + .contains("

Todo 2

") + .contains("

Todo 3

"); + } + + @Test + public void givenEmptyList_whenGetHtml_thenEmptyHtml() throws IOException{ + Mustache m = MustacheUtil.getMustacheFactory().compile("todos.mustache"); + + Map context = new HashMap<>(); + assertThat(executeTemplate(m, context)).isEmpty();; + } + + @Test + public void givenEmptyList_whenGetHtmlUsingInvertedSection_thenHtml() throws IOException{ + Mustache m = MustacheUtil.getMustacheFactory().compile("todos-inverted-section.mustache"); + + Map context = new HashMap<>(); + assertThat(executeTemplate(m, context).trim()).isEqualTo("

No todos!

"); + } + + @Test + public void givenTodoList_whenGetHtmlUsingLamdba_thenHtml() throws IOException{ + Mustache m = MustacheUtil.getMustacheFactory().compile("todos-lambda.mustache"); + List todos = Arrays.asList( + new Todo("Todo 1", "Todo description"), + new Todo("Todo 2", "Todo description another"), + new Todo("Todo 3", "Todo description another") + ); + todos.get(2).setDone(true); + todos.get(2).setCompletedOn(Date.from(Instant.now().plusSeconds(300))); + + Map context = new HashMap<>(); + context.put("todos", todos); + assertThat(executeTemplate(m, context).trim()).contains("Done 5 minutes ago"); + } +} diff --git a/pom.xml b/pom.xml index 609d69c3ea..3663d1308a 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,7 @@ mockito mockito2 mocks + mustache orika From 3a34f906a258659102d1017bdef5a0257a02478d Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sun, 21 May 2017 16:24:50 +0200 Subject: [PATCH 04/78] Mustache refactor (#1889) --- mustache/pom.xml | 32 +++---------- .../com/baeldung/mustache/model/Todo.java | 45 ++++++++----------- 2 files changed, 25 insertions(+), 52 deletions(-) diff --git a/mustache/pom.xml b/mustache/pom.xml index 8916b196f0..d5d80b58e9 100644 --- a/mustache/pom.xml +++ b/mustache/pom.xml @@ -2,12 +2,17 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung mustache 0.0.1-SNAPSHOT jar mustache + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + com.github.spullara.mustache.java @@ -36,31 +41,6 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - - **/*IntegrationTest.java - **/*LiveTest.java - - - - - - 0.9.2 3.7.0 diff --git a/mustache/src/main/java/com/baeldung/mustache/model/Todo.java b/mustache/src/main/java/com/baeldung/mustache/model/Todo.java index c329045876..cf845a3227 100644 --- a/mustache/src/main/java/com/baeldung/mustache/model/Todo.java +++ b/mustache/src/main/java/com/baeldung/mustache/model/Todo.java @@ -1,31 +1,32 @@ package com.baeldung.mustache.model; import java.time.Duration; -import java.time.temporal.Temporal; import java.util.Date; import java.util.function.Function; public class Todo { - public Todo(){} - - public Todo(String title, String text){ + public Todo() { + } + + public Todo(String title, String text) { this.title = title; this.text = text; createdOn = new Date(); } - + private String title; private String text; private boolean done = false; - + private Date createdOn; private Date completedOn; - - public void markAsDone(){ + + public void markAsDone() { done = true; completedOn = new Date(); } + public String getTitle() { return title; } @@ -61,24 +62,16 @@ public class Todo { public void setCompletedOn(Date completedOn) { this.completedOn = completedOn; } - - public long doneSince(){ - if ( done ){ - return Duration.between(createdOn.toInstant(), completedOn.toInstant()).toMinutes(); - } - return 0; + + public long doneSince() { + return done ? Duration + .between(createdOn.toInstant(), completedOn.toInstant()) + .toMinutes() : 0; } - - public Function handleDone(){ - return (obj) -> { - if ( done ){ - return String.format("Done %s minutes ago", obj); - }else{ - return ""; - } - - }; - + + public Function handleDone() { + return (obj) -> done ? String.format("Done %s minutes ago", obj) : ""; + } - + } From 378d20f053c88492f5723ba69e1825d30a02b24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Ju=C3=A1rez?= Date: Sun, 21 May 2017 13:23:04 -0500 Subject: [PATCH 05/78] BAEL-917 Testing with Google Truth (#1874) * BAEL-917 Testing with Google Truth * BAEL-917 Testing with Google Truth --- testing/pom.xml | 15 +- .../java/com/baeldung/testing/truth/User.java | 57 ++ .../baeldung/testing/truth/UserSubject.java | 46 ++ .../testing/truth/GoogleTruthUnitTest.java | 561 ++++++++++++++++++ 4 files changed, 678 insertions(+), 1 deletion(-) create mode 100644 testing/src/main/java/com/baeldung/testing/truth/User.java create mode 100644 testing/src/main/java/com/baeldung/testing/truth/UserSubject.java create mode 100644 testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java diff --git a/testing/pom.xml b/testing/pom.xml index 0bc70bdb96..a0bc5b99cf 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -52,6 +52,18 @@ ${pitest.version} pom
+ + + com.google.truth + truth + ${truth.version} + + + com.google.truth.extensions + truth-java8-extension + ${truth.version} + test + @@ -114,8 +126,9 @@ 1.2.5 1.1.10 0.7.7.201606060606 - 19.0 + 21.0 3.1.0 3.6.1 + 0.32 diff --git a/testing/src/main/java/com/baeldung/testing/truth/User.java b/testing/src/main/java/com/baeldung/testing/truth/User.java new file mode 100644 index 0000000000..fe857dd265 --- /dev/null +++ b/testing/src/main/java/com/baeldung/testing/truth/User.java @@ -0,0 +1,57 @@ +package com.baeldung.testing.truth; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class User implements Comparable { + private String name = "John Doe"; + private List emails = Arrays.asList("contact@baeldung.com", "staff@baeldung.com"); + + public User() { + } + + public User(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getEmails() { + return emails; + } + + public void setEmails(List emails) { + this.emails = emails; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 37 * hash + Objects.hashCode(this.name); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + final User other = (User) obj; + return Objects.equals(this.name, other.name); + } + + @Override + public int compareTo(User o) { + return this.getName() + .compareToIgnoreCase(o.getName()); + } + +} diff --git a/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java b/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java new file mode 100644 index 0000000000..2fd84085a0 --- /dev/null +++ b/testing/src/main/java/com/baeldung/testing/truth/UserSubject.java @@ -0,0 +1,46 @@ +package com.baeldung.testing.truth; + +import com.google.common.truth.ComparableSubject; +import com.google.common.truth.FailureStrategy; +import com.google.common.truth.IterableSubject; +import com.google.common.truth.SubjectFactory; +import com.google.common.truth.Truth; + +public class UserSubject extends ComparableSubject { + + private UserSubject(FailureStrategy failureStrategy, User target) { + super(failureStrategy, target); + } + + private static final SubjectFactory USER_SUBJECT_FACTORY = new SubjectFactory() { + @Override + public UserSubject getSubject(FailureStrategy failureStrategy, User target) { + return new UserSubject(failureStrategy, target); + } + }; + + public static UserSubject assertThat(User user) { + return Truth.assertAbout(USER_SUBJECT_FACTORY) + .that(user); + } + + // Our API begins here + public void hasName(String name) { + if (!actual().getName() + .equals(name)) { + fail("has name", name); + } + } + + public void hasNameIgnoringCase(String name) { + if (!actual().getName() + .equalsIgnoreCase(name)) { + fail("has name ignoring case", name); + } + } + + public IterableSubject emails() { + return Truth.assertThat(actual().getEmails()); + } + +} \ No newline at end of file diff --git a/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java new file mode 100644 index 0000000000..dfda21d99a --- /dev/null +++ b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java @@ -0,0 +1,561 @@ +package com.baeldung.testing.truth; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Range; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import com.google.common.collect.TreeMultiset; +import static com.baeldung.testing.truth.UserSubject.*; +import static com.google.common.truth.Truth.*; +import static com.google.common.truth.Truth8.*; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import org.junit.Ignore; +import org.junit.Test; + +public class GoogleTruthUnitTest { + + @Test + public void whenComparingInteger_thenEqual() { + int anInt = 10; + + assertThat(anInt).isEqualTo(10); + } + + @Test + public void whenComparingFloat_thenIsBigger() { + float aFloat = 10.0f; + + assertThat(aFloat).isGreaterThan(1.0f); + } + + @Test + public void whenComparingDouble_thenIsSmaller() { + double aDouble = 10.0f; + + assertThat(aDouble).isLessThan(20.0); + } + + @Test + public void whenComparingFloat_thenWithinPrecision() { + float aFloat = 23.04f; + + assertThat(aFloat).isWithin(1.3f) + .of(23.3f); + } + + @Test + public void whenComparingFloat_thenNotWithinPrecision() { + float aFloat = 23.04f; + + assertThat(aFloat).isNotWithin(1.3f) + .of(100f); + } + + @Test + public void whenComparingDouble_thenWithinPrecision() { + double aDouble = 22.18; + + assertThat(aDouble).isWithin(2) + .of(23d); + } + + @Test + public void whenComparingDouble_thenNotWithinPrecision() { + double aDouble = 22.08; + + assertThat(aDouble).isNotWithin(2) + .of(100); + } + + @Test + public void whenComparingBigDecimal_thenEqualIgnoringScale() { + BigDecimal aBigDecimal = BigDecimal.valueOf(1000, 3); + + assertThat(aBigDecimal).isEqualToIgnoringScale(new BigDecimal(1.0)); + } + + @Test + public void whenChekingBoolean_thenTrue() { + boolean aBoolean = true; + + assertThat(aBoolean).isTrue(); + } + + @Test + public void whenChekingBoolean_thenFalse() { + boolean aBoolean = false; + + assertThat(aBoolean).isFalse(); + } + + @Test + public void whenComparingArrays_thenEqual() { + String[] firstArrayOfStrings = { "one", "two", "three" }; + String[] secondArrayOfStrings = { "one", "two", "three" }; + + assertThat(firstArrayOfStrings).isEqualTo(secondArrayOfStrings); + } + + @Test + public void whenComparingArrays_thenNotEqual() { + String[] firstArrayOfStrings = { "one", "two", "three" }; + String[] secondArrayOfStrings = { "three", "two", "one" }; + + assertThat(firstArrayOfStrings).isNotEqualTo(secondArrayOfStrings); + } + + @Test + public void whenCheckingArray_thenEmpty() { + Object[] anArray = {}; + + assertThat(anArray).isEmpty(); + } + + @Test + public void whenCheckingArray_thenNotEmpty() { + String[] arrayOfStrings = { "One String " }; + + assertThat(arrayOfStrings).isNotEmpty(); + } + + @Test + public void whenCheckingArrayOfDoubles_thenWithinPrecision() { + double[] arrayOfDoubles = { 1, 2, 3, 4, 5 }; + + assertThat(arrayOfDoubles).hasValuesWithin(5) + .of(6, 7, 8, 9, 10); + } + + @Test + public void whenComparingUsers_thenEqual() { + User aUser = new User("John Doe"); + User anotherUser = new User("John Doe"); + + assertThat(aUser).isEqualTo(anotherUser); + } + + @Test + public void whenComparingUser_thenIsNull() { + User aUser = null; + + assertThat(aUser).isNull(); + } + + @Test + public void whenComparingUser_thenNotNull() { + User aUser = new User(); + + assertThat(aUser).isNotNull(); + } + + @Test + public void whenComparingUser_thenInstanceOf() { + User aUser = new User(); + + assertThat(aUser).isInstanceOf(User.class); + } + + @Test + public void whenComparingUser_thenInList() { + User aUser = new User(); + + assertThat(aUser).isIn(Arrays.asList(1, 3, aUser, null)); + } + + @Test + public void whenComparingUser_thenNotInList() { + User aUser = new User(); + + assertThat(aUser).isNotIn(Arrays.asList(1, 3, "Three")); + } + + @Test + public void whenComparingNullUser_thenInList() { + User aUser = null; + User anotherUser = new User(); + + assertThat(aUser).isIn(Arrays.asList(1, 3, anotherUser, null)); + } + + @Test + public void whenChekingString_thenStartsWithString() { + String aString = "This is a string"; + + assertThat(aString).startsWith("This"); + } + + @Test + public void whenChekingString_thenContainsString() { + String aString = "This is a string"; + + assertThat(aString).contains("is a"); + } + + @Test + public void whenChekingString_thenEndsWithString() { + String aString = "This is a string"; + + assertThat(aString).endsWith("string"); + } + + @Test + public void whenChekingString_thenExpectedLength() { + String aString = "This is a string"; + + assertThat(aString).hasLength(16); + } + + @Test + public void whenChekingString_thenEmpty() { + String aString = ""; + + assertThat(aString).isEmpty(); + } + + @Test + public void whenChekingString_thenMatches() { + String aString = "The string to match"; + + assertThat(aString).matches(Pattern.compile("[a-zA-Z\\s]+")); + } + + @Test + public void whenCheckingComparable_thenAtLeast() { + Comparable aComparable = 5; + + assertThat(aComparable).isAtLeast(1); + } + + @Test + public void whenCheckingComparable_thenAtMost() { + Comparable aComparable = 5; + + assertThat(aComparable).isAtMost(10); + } + + @Test + public void whenCheckingComparable_thenInList() { + Comparable aComparable = 5; + + assertThat(aComparable).isIn(Arrays.asList(4, 5, 6)); + } + + @Test + public void whenCheckingComparable_thenInRange() { + Comparable aComparable = 5; + + assertThat(aComparable).isIn(Range.closed(1, 10)); + } + + @Test + public void whenCheckingComparable_thenNotInRange() { + Comparable aComparable = 5; + + assertThat(aComparable).isNotIn(Range.closed(10, 15)); + } + + @Test + public void whenComparingUsers_thenEquivalent() { + User aUser = new User(); + aUser.setName("John Doe"); + + User anotherUser = new User(); + anotherUser.setName("john doe"); + + assertThat(aUser).isEquivalentAccordingToCompareTo(anotherUser); + } + + @Test + public void whenCheckingIterable_thenContains() { + List aList = Arrays.asList(4, 5, 6); + + assertThat(aList).contains(5); + } + + @Test + public void whenCheckingIterable_thenDoesNotContains() { + List aList = Arrays.asList(4, 5, 6); + + assertThat(aList).doesNotContain(9); + } + + @Test + public void whenCheckingIterable_thenContainsAny() { + List aList = Arrays.asList(4, 5, 6); + + assertThat(aList).containsAnyOf(0, 5, 10); + } + + @Test + public void whenCheckingIterable_thenContainsAnyInList() { + List aList = Arrays.asList(1, 2, 3); + + assertThat(aList).containsAnyIn(Arrays.asList(1, 5, 10)); + } + + @Test + public void whenCheckingIterable_thenNoDuplicates() { + List aList = Arrays.asList(-2, -1, 0, 1, 2); + + assertThat(aList).containsNoDuplicates(); + } + + @Test + public void whenCheckingIterable_thenContainsNoneOf() { + List aList = Arrays.asList(4, 5, 6); + + assertThat(aList).containsNoneOf(9, 8, 7); + } + + @Test + public void whenCheckingIterable_thenContainsNoneIn() { + List aList = Arrays.asList(4, 5, 6); + + assertThat(aList).containsNoneIn(Arrays.asList(9, 10, 11)); + } + + @Test + public void whenCheckingIterable_thenContainsExactElements() { + List aList = Arrays.asList("10", "20", "30"); + List anotherList = Arrays.asList("10", "20", "30"); + + assertThat(aList).containsExactlyElementsIn(anotherList) + .inOrder(); + } + + @Test + public void whenCheckingIterable_thenOrdered() { + Set aSet = new LinkedHashSet<>(Arrays.asList("one", "three", "two")); + + assertThat(aSet).isOrdered(); + } + + @Test + public void givenComparator_whenCheckingIterable_thenOrdered() { + Comparator aComparator = (a, b) -> new Float(a).compareTo(new Float(b)); + + List aList = Arrays.asList("1", "012", "0020", "100"); + + assertThat(aList).isOrdered(aComparator); + } + + @Test + public void whenCheckingMap_thenContainsEntry() { + Map aMap = new HashMap<>(); + aMap.put("one", 1L); + + assertThat(aMap).containsEntry("one", 1L); + } + + @Test + public void whenCheckingMap_thenContainsKey() { + Map map = new HashMap<>(); + map.put("one", 1L); + + assertThat(map).containsKey("one"); + } + + @Test + public void whenCheckingMap_thenContainsEntries() { + Map aMap = new HashMap<>(); + aMap.put("first", 1L); + aMap.put("second", 2.0); + aMap.put("third", 3f); + + Map anotherMap = new HashMap<>(aMap); + + assertThat(aMap).containsExactlyEntriesIn(anotherMap); + } + + @Test + public void whenCheckingException_thenInstanceOf() { + Exception anException = new IllegalArgumentException(new NumberFormatException()); + + assertThat(anException).hasCauseThat() + .isInstanceOf(NumberFormatException.class); + } + + @Test + public void whenCheckingException_thenCauseMessageIsKnown() { + Exception anException = new IllegalArgumentException("Bad value"); + + assertThat(anException).hasMessageThat() + .startsWith("Bad"); + } + + @Test + public void whenCheckingClass_thenIsAssignable() { + Class aClass = Double.class; + + assertThat(aClass).isAssignableTo(Number.class); + } + + // Java 8 Tests + @Test + public void whenChekingJavaOptional_thenHasValue() { + Optional anOptional = Optional.of(1); + + assertThat(anOptional).hasValue(1); + } + + @Test + public void whenCheckingJavaOptional_thenPresent() { + Optional anOptional = Optional.of("Baeldung"); + + assertThat(anOptional).isPresent(); + } + + @Test + public void whenCheckingJavaOptional_thenEmpty() { + Optional anOptional = Optional.empty(); + + assertThat(anOptional).isEmpty(); + } + + @Test + public void whenCheckingStream_thenContainsInOrder() { + Stream anStream = Stream.of(1, 2, 3); + + assertThat(anStream).containsAllOf(1, 2, 3) + .inOrder(); + } + + @Test + public void whenCheckingStream_thenDoesNotContain() { + Stream anStream = IntStream.range(1, 100) + .boxed(); + + assertThat(anStream).doesNotContain(0); + } + + // Guava Tests + @Test + public void whenChekingGuavaOptional_thenIsAbsent() { + com.google.common.base.Optional anOptional = com.google.common.base.Optional.absent(); + + assertThat(anOptional).isAbsent(); + } + + @Test + public void whenCheckingGuavaMultimap_thenExpectedSize() { + Multimap aMultimap = ArrayListMultimap.create(); + aMultimap.put("one", 1L); + aMultimap.put("one", 2.0); + + assertThat(aMultimap).valuesForKey("one") + .hasSize(2); + } + + @Test + public void whenCheckingGuavaMultiset_thenExpectedCount() { + TreeMultiset aMultiset = TreeMultiset.create(); + aMultiset.add("baeldung", 10); + + assertThat(aMultiset).hasCount("baeldung", 10); + } + + @Test + public void whenCheckingGuavaTable_thenContains() { + Table aTable = getDummyGuavaTable(); + + assertThat(aTable).contains("firstRow", "firstColumn"); + } + + @Test + public void whenCheckingGuavaTable_thenContainsCell() { + Table aTable = getDummyGuavaTable(); + + assertThat(aTable).containsCell("firstRow", "firstColumn", "baeldung"); + } + + @Test + public void whenCheckingGuavaTable_thenContainsRow() { + Table aTable = getDummyGuavaTable(); + + assertThat(aTable).containsRow("firstRow"); + } + + @Test + public void whenCheckingGuavaTable_thenContainsColumn() { + Table aTable = getDummyGuavaTable(); + + assertThat(aTable).containsColumn("firstColumn"); + } + + @Test + public void whenCheckingGuavaTable_thenContainsValue() { + Table aTable = getDummyGuavaTable(); + + assertThat(aTable).containsValue("baeldung"); + } + + @Ignore + @Test + public void whenFailingAssertion_thenMessagePrefix() { + User aUser = new User(); + + assertThat(aUser).named("User [%s]", aUser.getName()) + .isNull(); + } + + @Ignore + @Test + public void whenFailingAssertion_thenCustomMessage() { + User aUser = new User(); + + assertWithMessage("TEST-985: Secret user subject was NOT null!").that(aUser) + .isNull(); + } + + @Ignore + @Test + public void whenFailingAssertion_thenCustomMessageAndPrefix() { + User aUser = new User(); + + assertWithMessage("TEST-985: Secret user subject was NOT null!").that(aUser) + .named("User [%s]", aUser.getName()) + .isNull(); + } + + private Table getDummyGuavaTable() { + Table aTable = TreeBasedTable.create(); + aTable.put("firstRow", "firstColumn", "baeldung"); + return aTable; + } + + // Custom User type + @Test + public void whenCheckingUser_thenHasName() { + User aUser = new User(); + + assertThat(aUser).hasName("John Doe"); + } + + @Test + public void whenCheckingUser_thenHasNameIgnoringCase() { + User aUser = new User(); + + assertThat(aUser).hasNameIgnoringCase("john doe"); + } + + @Test + public void givenUser_whenCheckingEmails_thenExpectedSize() { + User aUser = new User(); + + assertThat(aUser).emails() + .hasSize(2); + } + +} From 93b4f3620251b86dee37403e0cd46ec20fe96c91 Mon Sep 17 00:00:00 2001 From: Pritam Banerjee Date: Sun, 21 May 2017 13:34:17 -0700 Subject: [PATCH 06/78] Fixed Package Names --- .../com/baeldung/ejb/stateful/EJBClient1.java | 11 +++++++++++ .../com/baeldung/ejb/stateful/EJBClient2.java | 11 +++++++++++ .../com/baeldung/ejb/stateful/StatefulEJB.java | 10 ++++++++++ .../com/baeldung/ejb/stateless/EJBClient1.java | 10 ++++++++++ .../com/baeldung/ejb/stateless/EJBClient2.java | 11 +++++++++++ .../baeldung/ejb/stateless/StatelessEJB.java | 11 +++++++++++ .../com/readlearncode/stateful/EJBClient1.java | 17 ----------------- .../com/readlearncode/stateful/EJBClient2.java | 17 ----------------- .../com/readlearncode/stateful/StatefulEJB.java | 16 ---------------- .../com/readlearncode/stateless/EJBClient1.java | 16 ---------------- .../com/readlearncode/stateless/EJBClient2.java | 17 ----------------- .../readlearncode/stateless/StatelessEJB.java | 16 ---------------- .../ejb/test}/stateful/StatefulEJBTest.java | 13 ++++++------- .../ejb/test}/stateless/StatelessEJBTest.java | 13 ++++++------- 14 files changed, 76 insertions(+), 113 deletions(-) create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient1.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient2.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/StatefulEJB.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient1.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient2.java create mode 100644 ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/StatelessEJB.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java delete mode 100644 ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java rename ejb/ejb-session-beans/src/test/java/com/{readlearncode => baeldung/ejb/test}/stateful/StatefulEJBTest.java (88%) rename ejb/ejb-session-beans/src/test/java/com/{readlearncode => baeldung/ejb/test}/stateless/StatelessEJBTest.java (89%) diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient1.java new file mode 100644 index 0000000000..0387beeb3c --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient1.java @@ -0,0 +1,11 @@ +package com.baeldung.ejb.stateful; + +import javax.ejb.EJB; + +public class EJBClient1 { + + @EJB + public StatefulEJB statefulEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient2.java new file mode 100644 index 0000000000..54f88a993d --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/EJBClient2.java @@ -0,0 +1,11 @@ +package com.baeldung.ejb.stateful; + +import javax.ejb.EJB; + +public class EJBClient2 { + + @EJB + public StatefulEJB statefulEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/StatefulEJB.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/StatefulEJB.java new file mode 100644 index 0000000000..17bb08491a --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateful/StatefulEJB.java @@ -0,0 +1,10 @@ +package com.baeldung.ejb.stateful; + +import javax.ejb.Stateful; + +@Stateful +public class StatefulEJB { + + public String name; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient1.java new file mode 100644 index 0000000000..0d6f06449b --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient1.java @@ -0,0 +1,10 @@ +package com.baeldung.ejb.stateless; + +import javax.ejb.EJB; + +public class EJBClient1 { + + @EJB + public StatelessEJB statelessEJB; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient2.java new file mode 100644 index 0000000000..a7fe650b1b --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/EJBClient2.java @@ -0,0 +1,11 @@ +package com.baeldung.ejb.stateless; + +import javax.ejb.EJB; + +public class EJBClient2 { + + @EJB + public StatelessEJB statelessEJB; + + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/StatelessEJB.java b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/StatelessEJB.java new file mode 100644 index 0000000000..d4e9749252 --- /dev/null +++ b/ejb/ejb-session-beans/src/main/java/com/baeldung/ejb/stateless/StatelessEJB.java @@ -0,0 +1,11 @@ +package com.baeldung.ejb.stateless; + +import javax.ejb.Stateless; + + +@Stateless +public class StatelessEJB { + + public String name; + +} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java deleted file mode 100644 index a61a3fef0c..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient1.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.readlearncode.stateful; - -import javax.ejb.EJB; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -public class EJBClient1 { - - @EJB - public StatefulEJB statefulEJB; - - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java deleted file mode 100644 index 350df5ff86..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/EJBClient2.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.readlearncode.stateful; - -import javax.ejb.EJB; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -public class EJBClient2 { - - @EJB - public StatefulEJB statefulEJB; - - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java deleted file mode 100644 index 771508584e..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateful/StatefulEJB.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.readlearncode.stateful; - -import javax.ejb.Stateful; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -@Stateful -public class StatefulEJB { - - public String name; - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java deleted file mode 100644 index e8e6e79a2d..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient1.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.readlearncode.stateless; - -import javax.ejb.EJB; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -public class EJBClient1 { - - @EJB - public StatelessEJB statelessEJB; - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java deleted file mode 100644 index ff90f2fcf1..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/EJBClient2.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.readlearncode.stateless; - -import javax.ejb.EJB; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -public class EJBClient2 { - - @EJB - public StatelessEJB statelessEJB; - - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java b/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java deleted file mode 100644 index 1f60d12e71..0000000000 --- a/ejb/ejb-session-beans/src/main/java/com/readlearncode/stateless/StatelessEJB.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.readlearncode.stateless; - -import javax.ejb.Stateless; - -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ -@Stateless -public class StatelessEJB { - - public String name; - -} \ No newline at end of file diff --git a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java similarity index 88% rename from ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java rename to ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java index 04d01975f6..2f3e45a769 100644 --- a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateful/StatefulEJBTest.java +++ b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateful/StatefulEJBTest.java @@ -1,4 +1,4 @@ -package com.readlearncode.stateful; +package com.baeldung.ejb.test.stateful; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; @@ -9,14 +9,13 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import com.baeldung.ejb.stateful.EJBClient1; +import com.baeldung.ejb.stateful.EJBClient2; +import com.baeldung.ejb.stateful.StatefulEJB; + import javax.inject.Inject; -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ + @RunWith(Arquillian.class) public class StatefulEJBTest { diff --git a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java similarity index 89% rename from ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java rename to ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java index 8c7d3e1bc9..9f88d478b7 100644 --- a/ejb/ejb-session-beans/src/test/java/com/readlearncode/stateless/StatelessEJBTest.java +++ b/ejb/ejb-session-beans/src/test/java/com/baeldung/ejb/test/stateless/StatelessEJBTest.java @@ -1,4 +1,4 @@ -package com.readlearncode.stateless; +package com.baeldung.ejb.test.stateless; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; @@ -9,14 +9,13 @@ import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; +import com.baeldung.ejb.stateless.EJBClient1; +import com.baeldung.ejb.stateless.EJBClient2; +import com.baeldung.ejb.stateless.StatelessEJB; + import javax.inject.Inject; -/** - * Source code github.com/readlearncode - * - * @author Alex Theedom www.readlearncode.com - * @version 1.0 - */ + @RunWith(Arquillian.class) public class StatelessEJBTest { From e74de67c598644619b65b5d9441144a0eb0caaf5 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Sun, 21 May 2017 15:58:12 -0500 Subject: [PATCH 07/78] BAEL-827 README (#1890) * Add files via upload * Update pom.xml * Update RunGuice.java * Update Communication.java * Update CommunicationMode.java * Update DefaultCommunicator.java * Update EmailCommunicationMode.java * Update IMCommunicationMode.java * Update SMSCommunicationMode.java * Update MessageLogger.java * Update MessageSentLoggable.java * Update AOPModule.java * Update BasicModule.java * Update CommunicationModel.java * Update Communicator.java * Update BasicModule.java * Update RunGuice.java * Update MessageLogger.java * Update Communicator.java * Update pom.xml * BAEL-278: Updated README.md * BAEL-554: Add and update README.md files * Update pom.xml * Update pom.xml * Update pom.xml * BAEL-345: fixed assertion * BAEL-109: Updated README.md * BAEL-345: Added README.md * Reinstating reactor-core module in root-level pom * BAEL-393: Adding guide-intro module to root pom * BAEL-9: Updated README.md * BAEL-157: README.md updated * Changed project name * Update RunGuice.java Removed references to message logging and output * Update Communication.java Removed message logging-related code * BAEL-566: Updated README.md * New project name * BAEL-393: removing guice-intro directory * BAEL-393: renamed module guice-intro to guice in root pom.xml * BAEL-393 and BAEL-541 README.md files * BAEL-731: Updated README.md * BAEL-680: renamed test methods * BAEL-714: Updated README.md * BAEL-737: Updated README.md * BAEL-680 and BAEL-756 README.md updates * BAEL-666: Updated README * BAEL-415: Custom Scope * BAEL-415: Custom Scope - renamed classes to reflect TenantScope * README file updates for BAEL-723, BAEL-763, and BAEL-415 * BAEL-735: README * BAEL-567: README * BAEL-736: README * BAEL-766: Update README * BAEL-555: README update * BAEL-761: README update * BAEL-742: Stripe API for Java README file * BAEL-86: Correction to README file * BAEL-828: Updated README.md * BAEL-830: Updated README * BAEL-870: Switched from TestNG to JUnit due to build errors * BAEL-870: Update README * BAEL-827: Updated README --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index c17677c23c..1cc99a3a6b 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -102,3 +102,4 @@ - [How to Perform a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) - [Call Methods at Runtime Using Java Reflection](http://www.baeldung.com/java-method-reflection) - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) +- [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) From 489e0e012fd9348ea21eb5dbdce7aa54a788215b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Ju=C3=A1rez?= Date: Sun, 21 May 2017 21:06:05 -0500 Subject: [PATCH 08/78] BAEL-886 How to add a single element to a Stream (#1887) --- .../baeldung/stream/StreamAddUnitTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core-java/src/test/java/com/baeldung/stream/StreamAddUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/stream/StreamAddUnitTest.java b/core-java/src/test/java/com/baeldung/stream/StreamAddUnitTest.java new file mode 100644 index 0000000000..8176d6a60c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stream/StreamAddUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.stream; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class StreamAddUnitTest { + + @Test + public void givenStream_whenAppendingObject_thenAppended() { + Stream anStream = Stream.of("a", "b", "c", "d", "e"); + + Stream newStream = Stream.concat(anStream, Stream.of("A")); + + List resultList = newStream.collect(Collectors.toList()); + assertEquals(resultList.get(resultList.size() - 1), "A"); + } + + @Test + public void givenStream_whenPrependingObject_thenPrepended() { + Stream anStream = Stream.of(1, 2, 3, 4, 5); + + Stream newStream = Stream.concat(Stream.of(99), anStream); + + assertEquals(newStream.findFirst() + .get(), (Integer) 99); + } + + @Test + public void givenStream_whenInsertingObject_thenInserted() { + Stream anStream = Stream.of(1.1, 2.2, 3.3); + + Stream newStream = insertInStream(anStream, 9.9, 3); + + List resultList = newStream.collect(Collectors.toList()); + assertEquals(resultList.get(3), (Double) 9.9); + } + + public Stream insertInStream(Stream stream, T elem, int index) { + List result = stream.collect(Collectors.toList()); + result.add(index, elem); + return result.stream(); + } +} From 468c06ff1962bfe30680d72d198f045464cf6a3d Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:48:02 +0530 Subject: [PATCH 09/78] Create new folder for BAEL-839 --- core-java/src/main/java/com/baeldung/regexp/test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 core-java/src/main/java/com/baeldung/regexp/test.txt diff --git a/core-java/src/main/java/com/baeldung/regexp/test.txt b/core-java/src/main/java/com/baeldung/regexp/test.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/regexp/test.txt @@ -0,0 +1 @@ + From 0a5526ea23635ba0f03b39d4291a67c233bf855c Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:49:36 +0530 Subject: [PATCH 10/78] Add class EscapingChars for BAEL-839 --- .../com/baeldung/regexp/EscapingChars.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/regexp/EscapingChars.java diff --git a/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java b/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java new file mode 100644 index 0000000000..3268339a15 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java @@ -0,0 +1,25 @@ +package com.baeldung.regexp; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class EscapingChars { + public boolean isMatching(String input, String pattern) { + return input.matches(pattern); + } + + public int splitAndCountWords(String input, String pattern) { + return input.split(pattern).length; + } + + public int splitAndCountWordsUsingQuoteMethod(String input, String pattern) { + return input.split(Pattern.quote(pattern)).length; + } + + public String changeCurrencySymbol(String input, String pattern, + String correctStr) { + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(input); + return m.replaceAll(correctStr); + } +} From 338e74ae3f0759831a5bfe2814d356d0949a2e50 Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:51:30 +0530 Subject: [PATCH 11/78] Create new folder BAEL-839 --- core-java/src/test/java/com/baeldung/regexp/test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 core-java/src/test/java/com/baeldung/regexp/test.txt diff --git a/core-java/src/test/java/com/baeldung/regexp/test.txt b/core-java/src/test/java/com/baeldung/regexp/test.txt new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/regexp/test.txt @@ -0,0 +1 @@ + From 156c8a3bdd588771df5819b34979f599d855d552 Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:52:22 +0530 Subject: [PATCH 12/78] Add EscapingCharsManualTest BAEL-839 --- .../regexp/EscapingCharsManualTest.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java diff --git a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java new file mode 100644 index 0000000000..60281fda7a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java @@ -0,0 +1,70 @@ +package com.baeldung.regexp; + +import static junit.framework.TestCase.assertEquals; + +import org.junit.Test; + +public class EscapingCharsManualTest { + @Test + public void givenRegexWithDot_whenMatchingStr_thenMatches() { + String strInput = "foof"; + String strRegex = "foo."; + EscapingChars e = new EscapingChars(); + + assertEquals(true, e.isMatching(strInput, strRegex)); + } + + @Test + public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching() { + String strInput = "foof"; + String strRegex = "foo\\."; + EscapingChars e = new EscapingChars(); + + assertEquals(false, e.isMatching(strInput, strRegex)); + } + + @Test + public void givenRegexWithPipeEscaped_whenSplitStr_thenSplits() { + String strInput = "foo|bar|hello|world"; + String strRegex = "\\Q|\\E"; + EscapingChars e = new EscapingChars(); + + assertEquals(4, e.splitAndCountWords(strInput, strRegex)); + } + + @Test + public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits() { + String strInput = "foo|bar|hello|world"; + String strRegex = "|"; + EscapingChars e = new EscapingChars(); + + assertEquals(4, + e.splitAndCountWordsUsingQuoteMethod(strInput, strRegex)); + } + + @Test + public void givenRegexWithDollar_whenReplacing_thenNotReplace() { + String strInput = "I gave $50 to my brother." + + "He bought candy for $35. Now he has $15 left."; + String strRegex = "$"; + String strReplacement = "£"; + String output = "I gave £50 to my brother." + + "He bought candy for £35. Now he has £15 left."; + EscapingChars e = new EscapingChars(); + + assertEquals(output, + e.changeCurrencySymbol(strInput, strRegex, strReplacement)); + } + + @Test + public void givenRegexWithDollarEsc_whenReplacing_thenReplace() { + String strInput = "I gave $50 to my brother. He bought candy for $35. Now he has $15 left."; + String strRegex = "\\$"; + String strReplacement = "£"; + String output = "I gave £50 to my brother. He bought candy for £35. Now he has £15 left."; + EscapingChars e = new EscapingChars(); + + assertEquals(output, + e.changeCurrencySymbol(strInput, strRegex, strReplacement)); + } +} From ef1c191dfbc19507edbda3deada08d8cb1417031 Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:53:19 +0530 Subject: [PATCH 13/78] Delete --- core-java/src/main/java/com/baeldung/regexp/test.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 core-java/src/main/java/com/baeldung/regexp/test.txt diff --git a/core-java/src/main/java/com/baeldung/regexp/test.txt b/core-java/src/main/java/com/baeldung/regexp/test.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/core-java/src/main/java/com/baeldung/regexp/test.txt +++ /dev/null @@ -1 +0,0 @@ - From abdc90442613ccfde365d785102b77e8ae15495b Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 22 May 2017 08:54:14 +0530 Subject: [PATCH 14/78] Delete --- core-java/src/test/java/com/baeldung/regexp/test.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 core-java/src/test/java/com/baeldung/regexp/test.txt diff --git a/core-java/src/test/java/com/baeldung/regexp/test.txt b/core-java/src/test/java/com/baeldung/regexp/test.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/core-java/src/test/java/com/baeldung/regexp/test.txt +++ /dev/null @@ -1 +0,0 @@ - From 3aae854ea2dcad648164783dbd5f62c68048a39d Mon Sep 17 00:00:00 2001 From: slavisa-baeldung Date: Mon, 22 May 2017 06:08:39 +0100 Subject: [PATCH 15/78] BAEL-839 - minor test changes --- ...ManualTest.java => EscapingCharsTest.java} | 137 +++++++++--------- 1 file changed, 67 insertions(+), 70 deletions(-) rename core-java/src/test/java/com/baeldung/regexp/{EscapingCharsManualTest.java => EscapingCharsTest.java} (65%) diff --git a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java similarity index 65% rename from core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java rename to core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java index 60281fda7a..1e2293955a 100644 --- a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsManualTest.java +++ b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java @@ -1,70 +1,67 @@ -package com.baeldung.regexp; - -import static junit.framework.TestCase.assertEquals; - -import org.junit.Test; - -public class EscapingCharsManualTest { - @Test - public void givenRegexWithDot_whenMatchingStr_thenMatches() { - String strInput = "foof"; - String strRegex = "foo."; - EscapingChars e = new EscapingChars(); - - assertEquals(true, e.isMatching(strInput, strRegex)); - } - - @Test - public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching() { - String strInput = "foof"; - String strRegex = "foo\\."; - EscapingChars e = new EscapingChars(); - - assertEquals(false, e.isMatching(strInput, strRegex)); - } - - @Test - public void givenRegexWithPipeEscaped_whenSplitStr_thenSplits() { - String strInput = "foo|bar|hello|world"; - String strRegex = "\\Q|\\E"; - EscapingChars e = new EscapingChars(); - - assertEquals(4, e.splitAndCountWords(strInput, strRegex)); - } - - @Test - public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits() { - String strInput = "foo|bar|hello|world"; - String strRegex = "|"; - EscapingChars e = new EscapingChars(); - - assertEquals(4, - e.splitAndCountWordsUsingQuoteMethod(strInput, strRegex)); - } - - @Test - public void givenRegexWithDollar_whenReplacing_thenNotReplace() { - String strInput = "I gave $50 to my brother." - + "He bought candy for $35. Now he has $15 left."; - String strRegex = "$"; - String strReplacement = "£"; - String output = "I gave £50 to my brother." - + "He bought candy for £35. Now he has £15 left."; - EscapingChars e = new EscapingChars(); - - assertEquals(output, - e.changeCurrencySymbol(strInput, strRegex, strReplacement)); - } - - @Test - public void givenRegexWithDollarEsc_whenReplacing_thenReplace() { - String strInput = "I gave $50 to my brother. He bought candy for $35. Now he has $15 left."; - String strRegex = "\\$"; - String strReplacement = "£"; - String output = "I gave £50 to my brother. He bought candy for £35. Now he has £15 left."; - EscapingChars e = new EscapingChars(); - - assertEquals(output, - e.changeCurrencySymbol(strInput, strRegex, strReplacement)); - } -} +package com.baeldung.regexp; + +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.*; + +import org.junit.Test; + +public class EscapingCharsTest { + @Test + public void givenRegexWithDot_whenMatchingStr_thenMatches() { + String strInput = "foof"; + String strRegex = "foo."; + EscapingChars e = new EscapingChars(); + + assertEquals(true, e.isMatching(strInput, strRegex)); + } + + @Test + public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching() { + String strInput = "foof"; + String strRegex = "foo\\."; + EscapingChars e = new EscapingChars(); + + assertEquals(false, e.isMatching(strInput, strRegex)); + } + + @Test + public void givenRegexWithPipeEscaped_whenSplitStr_thenSplits() { + String strInput = "foo|bar|hello|world"; + String strRegex = "\\Q|\\E"; + EscapingChars e = new EscapingChars(); + + assertEquals(4, e.splitAndCountWords(strInput, strRegex)); + } + + @Test + public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits() { + String strInput = "foo|bar|hello|world"; + String strRegex = "|"; + EscapingChars e = new EscapingChars(); + + assertEquals(4, e.splitAndCountWordsUsingQuoteMethod(strInput, strRegex)); + } + + @Test + public void givenRegexWithDollar_whenReplacing_thenNotReplace() { + String strInput = "I gave $50 to my brother.He bought candy for $35. Now he has $15 left."; + String strRegex = "$"; + String strReplacement = "�"; + String output = "I gave �50 to my brother.He bought candy for �35. Now he has �15 left."; + EscapingChars e = new EscapingChars(); + + assertThat(output, not(equalTo(e.changeCurrencySymbol(strInput, strRegex, strReplacement)))); + } + + @Test + public void givenRegexWithDollarEsc_whenReplacing_thenReplace() { + String strInput = "I gave $50 to my brother. He bought candy for $35. Now he has $15 left."; + String strRegex = "\\$"; + String strReplacement = "�"; + String output = "I gave �50 to my brother. He bought candy for �35. Now he has �15 left."; + EscapingChars e = new EscapingChars(); + + assertEquals(output, e.changeCurrencySymbol(strInput, strRegex, strReplacement)); + } +} From d1e4eed806cea86d76f1108c773d2952c5f42238 Mon Sep 17 00:00:00 2001 From: Sunil Mogadati Date: Mon, 22 May 2017 03:49:00 -0600 Subject: [PATCH 16/78] BAEL-741: Spring Security Multiple Authentication Providers (#1838) * Add NDC and JBoss Logging to the demo application * NDC for Log4j, Log4j2 and JBoss Logging * Simplify NDC example by making it a single operation instead of two * Make NDC example as RestController, Use JBoss Logging only as a logging bridge * Fix merge conflicts in pull request - log-mdc pom.xml updated * BAEL-445 Update to Spring security SpEL example * BAEL-445: Change tabs to spaces in the updated code * BAEL-245: Add Enum Serialization exmaple * BAEL-245: Remove the folder jackson/src/test/java/com/baeldung/jackson/dtos/withEnum as the example is not used anymore * Add more enum serialization examples to align with previous example and prevent build fail * BAEL-611: Minor formatting changes * BAEL-611: Update Test case method names * BAEL-611 Add JAX-WS client and JUnit Test * BAEL-245: Issue 1753. Fix the typo - change from writeNumber() to writeString() * BAEL-741: Spring Security Multiple Authentication Providers * BAEL-741: Spring Security Multiple Authentication Providers * Remove unnecessary change in pom.xml --- .../CustomAuthenticationProvider.java | 31 ++++++++++ .../MultipleAuthController.java | 13 ++++ .../MultipleAuthProvidersApplication.java | 12 ++++ .../MultipleAuthProvidersSecurityConfig.java | 34 +++++++++++ ...pring-security-multiple-auth-providers.xml | 24 ++++++++ ...MultipleAuthProvidersApplicationTests.java | 61 +++++++++++++++++++ 6 files changed, 175 insertions(+) create mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java create mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java create mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java create mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java create mode 100644 spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml create mode 100644 spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java new file mode 100644 index 0000000000..1a89c362cd --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/CustomAuthenticationProvider.java @@ -0,0 +1,31 @@ +package org.baeldung.multipleauthproviders; + +import java.util.Collections; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.stereotype.Component; + +@Component +public class CustomAuthenticationProvider implements AuthenticationProvider { + @Override + public Authentication authenticate(Authentication auth) throws AuthenticationException { + final String username = auth.getName(); + final String password = auth.getCredentials() + .toString(); + + if ("externaluser".equals(username) && "pass".equals(password)) { + return new UsernamePasswordAuthenticationToken(username, password, Collections.emptyList()); + } else { + throw new BadCredentialsException("External system authentication failed"); + } + } + + @Override + public boolean supports(Class auth) { + return auth.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java new file mode 100644 index 0000000000..80573c1c7d --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java @@ -0,0 +1,13 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class MultipleAuthController { + + @RequestMapping("/api/ping") + public String getPing() { + return "OK"; + } +} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java new file mode 100644 index 0000000000..077f558bd2 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +// @ImportResource({ "classpath*:spring-security-multiple-auth-providers.xml" }) +public class MultipleAuthProvidersApplication { + public static void main(String[] args) { + SpringApplication.run(MultipleAuthProvidersApplication.class, args); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java new file mode 100644 index 0000000000..432cc61e87 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java @@ -0,0 +1,34 @@ +package org.baeldung.multipleauthproviders; + +import org.springframework.beans.factory.annotation.Autowired; +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.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + CustomAuthenticationProvider customAuthProvider; + + @Override + public void configure(AuthenticationManagerBuilder auth) throws Exception { + + auth.authenticationProvider(customAuthProvider); + + auth.inMemoryAuthentication() + .withUser("memuser") + .password("pass") + .roles("USER"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic() + .and() + .authorizeRequests() + .antMatchers("/api/**") + .authenticated(); + } +} diff --git a/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml new file mode 100644 index 0000000000..4cfa6bbf26 --- /dev/null +++ b/spring-security-mvc-boot/src/main/resources/spring-security-multiple-auth-providers.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java new file mode 100644 index 0000000000..0d70cd64e4 --- /dev/null +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/MultipleAuthProvidersApplicationTests.java @@ -0,0 +1,61 @@ +package org.baeldung.web; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; + +import org.baeldung.multipleauthproviders.MultipleAuthProvidersApplication; +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.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = MultipleAuthProvidersApplication.class) +public class MultipleAuthProvidersApplicationTests { + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void givenMemUsers_whenGetPingWithValidUser_thenOk() { + ResponseEntity result = makeRestCallToGetPing("memuser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenExternalUsers_whenGetPingWithValidUser_thenOK() { + ResponseEntity result = makeRestCallToGetPing("externaluser", "pass"); + + assertThat(result.getStatusCodeValue()).isEqualTo(200); + assertThat(result.getBody()).isEqualTo("OK"); + } + + @Test + public void givenAuthProviders_whenGetPingWithNoCred_then401() { + ResponseEntity result = makeRestCallToGetPing(); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + @Test + public void givenAuthProviders_whenGetPingWithBadCred_then401() { + ResponseEntity result = makeRestCallToGetPing("user", "bad_password"); + + assertThat(result.getStatusCodeValue()).isEqualTo(401); + } + + private ResponseEntity makeRestCallToGetPing(String username, String password) { + return restTemplate.withBasicAuth(username, password) + .getForEntity("/api/ping", String.class, Collections.emptyMap()); + } + + private ResponseEntity makeRestCallToGetPing() { + return restTemplate.getForEntity("/api/ping", String.class, Collections.emptyMap()); + } +} From 45e16d409bbc4cce21c2ba8f9449eb373115ef33 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Mon, 22 May 2017 16:26:51 +0200 Subject: [PATCH 17/78] Update GoogleTruthUnitTest.java (#1897) --- .../testing/truth/GoogleTruthUnitTest.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java index dfda21d99a..5be27db9db 100644 --- a/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java +++ b/testing/src/test/java/com/baeldung/testing/truth/GoogleTruthUnitTest.java @@ -87,14 +87,14 @@ public class GoogleTruthUnitTest { } @Test - public void whenChekingBoolean_thenTrue() { + public void whenCheckingBoolean_thenTrue() { boolean aBoolean = true; assertThat(aBoolean).isTrue(); } @Test - public void whenChekingBoolean_thenFalse() { + public void whenCheckingBoolean_thenFalse() { boolean aBoolean = false; assertThat(aBoolean).isFalse(); @@ -190,42 +190,42 @@ public class GoogleTruthUnitTest { } @Test - public void whenChekingString_thenStartsWithString() { + public void whenCheckingString_thenStartsWithString() { String aString = "This is a string"; assertThat(aString).startsWith("This"); } @Test - public void whenChekingString_thenContainsString() { + public void whenCheckingString_thenContainsString() { String aString = "This is a string"; assertThat(aString).contains("is a"); } @Test - public void whenChekingString_thenEndsWithString() { + public void whenCheckingString_thenEndsWithString() { String aString = "This is a string"; assertThat(aString).endsWith("string"); } @Test - public void whenChekingString_thenExpectedLength() { + public void whenCheckingString_thenExpectedLength() { String aString = "This is a string"; assertThat(aString).hasLength(16); } @Test - public void whenChekingString_thenEmpty() { + public void whenCheckingString_thenEmpty() { String aString = ""; assertThat(aString).isEmpty(); } @Test - public void whenChekingString_thenMatches() { + public void whenCheckingString_thenMatches() { String aString = "The string to match"; assertThat(aString).matches(Pattern.compile("[a-zA-Z\\s]+")); @@ -404,7 +404,7 @@ public class GoogleTruthUnitTest { // Java 8 Tests @Test - public void whenChekingJavaOptional_thenHasValue() { + public void whenCheckingJavaOptional_thenHasValue() { Optional anOptional = Optional.of(1); assertThat(anOptional).hasValue(1); @@ -442,7 +442,7 @@ public class GoogleTruthUnitTest { // Guava Tests @Test - public void whenChekingGuavaOptional_thenIsAbsent() { + public void whenCheckingGuavaOptional_thenIsAbsent() { com.google.common.base.Optional anOptional = com.google.common.base.Optional.absent(); assertThat(anOptional).isAbsent(); From 28adbeb53daa5942944a49ece4b0630370733e9b Mon Sep 17 00:00:00 2001 From: parthkaria Date: Mon, 22 May 2017 23:02:48 +0530 Subject: [PATCH 18/78] BAEL-831 ClassNotFoundExceptions vs NoClassDefFoundError (#1899) * Dependency Injection examples Dependency Injection examples for evaluation article * Junit test cases added for dependency injection Junit test cases added for dependency injection * ClassNotFoundException vs NoClassDefFoundError Example to reproduce ClassNotFoundException & NoClassDefFoundError * JUnit test cases for ClassNotFoundException & NoClassDefFoundError test cases to reproduce ClassNotFoundException & NoClassDefFoundError * Deleting exampls for evaluation article * BAEL-831 Examples for ClassNotFoundException & NoClassDefFoundError * deleting config file for evaluation article deleting config file for evaluation article --- .../ClassNotFoundExceptionExample.java | 7 +++++++ .../noclassdeffounderror/ClassWithInitErrors.java | 5 +++++ .../NoClassDefFoundErrorExample.java | 14 ++++++++++++++ .../ClassNotFoundExceptionTest.java | 12 ++++++++++++ .../NoClassDefFoundErrorTest.java | 12 ++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java create mode 100644 core-java/src/main/java/com/baeldung/noclassdeffounderror/ClassWithInitErrors.java create mode 100644 core-java/src/main/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorExample.java create mode 100644 core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java create mode 100644 core-java/src/test/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorTest.java diff --git a/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java b/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java new file mode 100644 index 0000000000..26d306d03f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java @@ -0,0 +1,7 @@ +package com.baeldung.classnotfoundexception; + +public class ClassNotFoundExceptionExample { + public void loadDrivers() throws ClassNotFoundException { + Class.forName("oracle.jdbc.driver.OracleDriver"); + } +} diff --git a/core-java/src/main/java/com/baeldung/noclassdeffounderror/ClassWithInitErrors.java b/core-java/src/main/java/com/baeldung/noclassdeffounderror/ClassWithInitErrors.java new file mode 100644 index 0000000000..2b19f3496d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/noclassdeffounderror/ClassWithInitErrors.java @@ -0,0 +1,5 @@ +package com.baeldung.noclassdeffounderror; + +public class ClassWithInitErrors { + static int data = 1 / 0; +} diff --git a/core-java/src/main/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorExample.java b/core-java/src/main/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorExample.java new file mode 100644 index 0000000000..2c852b5e82 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorExample.java @@ -0,0 +1,14 @@ +package com.baeldung.noclassdeffounderror; + +public class NoClassDefFoundErrorExample { + public ClassWithInitErrors getClassWithInitErrors() { + ClassWithInitErrors test; + try { + test = new ClassWithInitErrors(); + } catch (Throwable t) { + System.out.println(t); + } + test = new ClassWithInitErrors(); + return test; + } +} diff --git a/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java b/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java new file mode 100644 index 0000000000..2a16b7effd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java @@ -0,0 +1,12 @@ +package com.baeldung.classnotfoundexception; + +import org.junit.Test; + +public class ClassNotFoundExceptionTest { + + @Test(expected = ClassNotFoundException.class) + public void givenNoDriversInClassPath_whenLoadDrivers_thenClassNotFoundException() throws ClassNotFoundException { + ClassNotFoundExceptionExample test = new ClassNotFoundExceptionExample(); + test.loadDrivers(); + } +} diff --git a/core-java/src/test/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorTest.java b/core-java/src/test/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorTest.java new file mode 100644 index 0000000000..bb446dc385 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/noclassdeffounderror/NoClassDefFoundErrorTest.java @@ -0,0 +1,12 @@ +package com.baeldung.noclassdeffounderror; + +import org.junit.Test; + +public class NoClassDefFoundErrorTest { + + @Test(expected = NoClassDefFoundError.class) + public void givenInitErrorInClass_whenloadClass_thenNoClassDefFoundError() { + NoClassDefFoundErrorExample sample = new NoClassDefFoundErrorExample(); + sample.getClassWithInitErrors(); + } +} From 4fd99ca7a5aacdb441d0b13a73bdecca7ec5127e Mon Sep 17 00:00:00 2001 From: Tian Baoqiang Date: Mon, 22 May 2017 13:46:43 -0500 Subject: [PATCH 19/78] replace #BAEL-913 test scenario with simple add and sum test (#1895) --- .../serenity/spring/AdderController.java | 29 +++++++ .../serenity/spring/AdderService.java | 25 ++++++ .../serenity/spring/KonamiCodeController.java | 28 ------- .../serenity/spring/KonamiCodeService.java | 39 ---------- .../KonamiCodeServiceInjectionController.java | 41 ---------- .../serenity/spring/PlainAdderController.java | 26 +++++++ ...derClassDirtiesContextIntegrationTest.java | 76 +++++++++++++++++++ ...xtDependencyWorkaroundIntegrationTest.java | 54 +++++++++++++ ...sContextInitWorkaroundIntegrationTest.java | 51 +++++++++++++ ...erMethodDirtiesContextIntegrationTest.java | 46 +++++++++++ .../AdderMethodRuleIntegrationTest.java | 59 ++++++++++++++ .../spring/AdderMockMvcIntegrationTest.java | 33 ++++++++ .../spring/AdderServiceIntegrationTest.java | 26 +++++++ ...erSpringSerenityRunnerIntegrationTest.java | 29 +++++++ .../{KonamiCodeTest.java => AdderTest.java} | 8 +- ...eatClassDirtiesContextIntegrationTest.java | 74 ------------------ ...amCheatWithDirtyActionIntegrationTest.java | 62 --------------- ...nWithImplicitInjectionIntegrationTest.java | 54 ------------- .../KonamCheatWithServiceIntegrationTest.java | 27 ------- ...IntegrationMethodRulesIntegrationTest.java | 61 --------------- ...tWithIntegrationRunnerIntegrationTest.java | 58 -------------- .../KonamiCodeMockMvcIntegrationTest.java | 31 -------- .../serenity/spring/RandomNumberUtil.java | 13 ++++ .../AdderConstructorDependencySteps.java | 44 +++++++++++ .../serenity/spring/steps/AdderRestSteps.java | 46 +++++++++++ .../spring/steps/AdderServiceSteps.java | 44 +++++++++++ .../serenity/spring/steps/AdderSteps.java | 29 +++++++ .../spring/steps/KonamiCheatSteps.java | 25 ------ .../KonamiCodeConstructorDependencySteps.java | 58 -------------- .../spring/steps/KonamiCodeRestSteps.java | 68 ----------------- .../KonamiCodeServiceInjectionSteps.java | 55 -------------- .../serenity/spring/stories/AdderStory.java | 31 ++++++++ .../spring/stories/KonamiCodeStory.java | 37 --------- ...konami-cheat-beans.xml => adder-beans.xml} | 8 +- .../resources/stories/spring/adder_test.story | 11 +++ .../stories/spring/konami_code_test.story | 12 --- 36 files changed, 680 insertions(+), 738 deletions(-) create mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java create mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java delete mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeController.java delete mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeService.java delete mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeServiceInjectionController.java create mode 100644 libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java rename libraries/src/test/java/com/baeldung/serenity/spring/{KonamiCodeTest.java => AdderTest.java} (55%) delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatClassDirtiesContextIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionWithImplicitInjectionIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithServiceIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationMethodRulesIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationRunnerIntegrationTest.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeMockMvcIntegrationTest.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCheatSteps.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeConstructorDependencySteps.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeRestSteps.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeServiceInjectionSteps.java create mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java delete mode 100644 libraries/src/test/java/com/baeldung/serenity/spring/stories/KonamiCodeStory.java rename libraries/src/test/resources/{konami-cheat-beans.xml => adder-beans.xml} (82%) create mode 100644 libraries/src/test/resources/stories/spring/adder_test.story delete mode 100644 libraries/src/test/resources/stories/spring/konami_code_test.story diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java b/libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java new file mode 100644 index 0000000000..b89e72d117 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/serenity/spring/AdderController.java @@ -0,0 +1,29 @@ +package com.baeldung.serenity.spring; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +/** + * @author aiet + */ +@RequestMapping(value = "/adder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) +@RestController +public class AdderController { + + private AdderService adderService; + + public AdderController(AdderService adderService) { + this.adderService = adderService; + } + + @GetMapping("/current") + public int currentNum() { + return adderService.currentBase(); + } + + @PostMapping + public int add(@RequestParam int num) { + return adderService.add(num); + } + +} diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java b/libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java new file mode 100644 index 0000000000..756c05bc2c --- /dev/null +++ b/libraries/src/main/java/com/baeldung/serenity/spring/AdderService.java @@ -0,0 +1,25 @@ +package com.baeldung.serenity.spring; + +import org.springframework.stereotype.Service; + +@Service +public class AdderService { + + private int num; + + public void baseNum(int base) { + this.num = base; + } + + public int currentBase() { + return num; + } + + public int add(int adder) { + return this.num + adder; + } + + public int accumulate(int adder) { + return this.num += adder; + } +} diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeController.java b/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeController.java deleted file mode 100644 index f8ae66c229..0000000000 --- a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeController.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.serenity.spring; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author aiet - */ -@RequestMapping(value = "/konamicode", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -@RestController -public class KonamiCodeController { - - private final String classicCode = "↑↑↓↓â†â†’â†â†’BA"; - - @GetMapping("/classic") - public String classicCode() { - return classicCode; - } - - @GetMapping("/cheatable") - public boolean cheatCheck(@RequestParam String cheatcode){ - return classicCode.equals(cheatcode); - } - -} diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeService.java b/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeService.java deleted file mode 100644 index 2aa1804ba5..0000000000 --- a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeService.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.baeldung.serenity.spring; - -import org.springframework.stereotype.Service; - -/** - * refer to Konami Code - */ -@Service -public class KonamiCodeService { - - private String classicCode = "↑↑↓↓â†â†’â†â†’BA"; - - public String getClassicCode() { - return classicCode; - } - - public void alterClassicCode(String newCode) { - classicCode = newCode; - } - - public boolean cheatWith(String cheatcode) { - if ("↑↑↓↓â†â†’â†â†’BA".equals(cheatcode)) { - stageLeft++; - return true; - } - return false; - } - - private int stageLeft = 1; - - public void clearStage() { - stageLeft = 0; - } - - public int stageLeft() { - return stageLeft; - } - -} diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeServiceInjectionController.java b/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeServiceInjectionController.java deleted file mode 100644 index bb80963aa3..0000000000 --- a/libraries/src/main/java/com/baeldung/serenity/spring/KonamiCodeServiceInjectionController.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.serenity.spring; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; - -/** - * @author aiet - */ -@RequestMapping(value = "/konamicode", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -@RestController -public class KonamiCodeServiceInjectionController { - - private KonamiCodeService konamiCodeService; - - public KonamiCodeServiceInjectionController(KonamiCodeService konamiCodeService) { - this.konamiCodeService = konamiCodeService; - } - - @PutMapping("/stages") - public void clearStage(@RequestParam String action) { - if ("clear".equals(action)) { - konamiCodeService.clearStage(); - } - } - - @GetMapping("/classic") - public String classicCode() { - return konamiCodeService.getClassicCode(); - } - - @GetMapping("/cheatable") - public boolean cheatCheck(@RequestParam String cheatcode) { - return konamiCodeService.cheatWith(cheatcode); - } - - @GetMapping("/stages") - public int stageLeft() { - return konamiCodeService.stageLeft(); - } - -} diff --git a/libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java b/libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java new file mode 100644 index 0000000000..888ebaf8bf --- /dev/null +++ b/libraries/src/main/java/com/baeldung/serenity/spring/PlainAdderController.java @@ -0,0 +1,26 @@ +package com.baeldung.serenity.spring; + +import org.apache.commons.lang3.RandomUtils; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +/** + * @author aiet + */ +@RequestMapping(value = "/adder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) +@RestController +public class PlainAdderController { + + private final int currentNumber = RandomUtils.nextInt(); + + @GetMapping("/current") + public int currentNum() { + return currentNumber; + } + + @PostMapping + public int add(@RequestParam int num) { + return currentNumber + num; + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java new file mode 100644 index 0000000000..bb25186cee --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderClassDirtiesContextIntegrationTest.java @@ -0,0 +1,76 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderServiceSteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.junit.spring.integration.SpringIntegrationClassRule; +import net.thucydides.core.annotations.Steps; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; + +/** + * @author aiet + */ + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + AdderClassDirtiesContextIntegrationTest.DirtiesContextTest.class, AdderClassDirtiesContextIntegrationTest.AnotherDirtiesContextTest.class + }) +public class AdderClassDirtiesContextIntegrationTest { + + @RunWith(SerenityRunner.class) + @ContextConfiguration(classes = AdderService.class) + public static abstract class Base { + + @Steps AdderServiceSteps adderServiceSteps; + + @ClassRule public static SpringIntegrationClassRule springIntegrationClassRule = new SpringIntegrationClassRule(); + + void whenAccumulate_thenSummedUp() { + adderServiceSteps.whenAccumulate(); + adderServiceSteps.summedUp(); + } + + void whenAdd_thenSumWrong() { + adderServiceSteps.whenAdd(); + adderServiceSteps.sumWrong(); + } + + void whenAdd_thenSummedUp() { + adderServiceSteps.whenAdd(); + adderServiceSteps.summedUp(); + } + + } + + @DirtiesContext(classMode = AFTER_CLASS) + public static class AnotherDirtiesContextTest extends Base { + + @Test + public void givenNumber_whenAdd_thenSumWrong() { + super.whenAdd_thenSummedUp(); //expecting zero + adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt()); + super.whenAccumulate_thenSummedUp(); + super.whenAdd_thenSumWrong(); + } + } + + @DirtiesContext(classMode = AFTER_CLASS) + public static class DirtiesContextTest extends Base { + + @Test + public void givenNumber_whenAdd_thenSumWrong() { + super.whenAdd_thenSummedUp(); //expecting zero + adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt()); + super.whenAccumulate_thenSummedUp(); + super.whenAdd_thenSumWrong(); + } + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java new file mode 100644 index 0000000000..6524ade190 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest.java @@ -0,0 +1,54 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderConstructorDependencySteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +@RunWith(SerenityRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@ContextConfiguration(classes = AdderService.class) +public class AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest { + + private AdderConstructorDependencySteps adderSteps; + + @Autowired private AdderService adderService; + + @Before + public void init() { + adderSteps = new AdderConstructorDependencySteps(adderService); + } + + @Test + public void _1_givenNumber_whenAdd_thenSumWrong() { + adderSteps.whenAdd(); + adderSteps.summedUp(); + } + + @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule(); + + @DirtiesContext + @Test + public void _0_givenNumber_whenAddAndAccumulate_thenSummedUp() { + adderSteps.givenBaseAndAdder(randomInt(), randomInt()); + adderSteps.whenAccumulate(); + adderSteps.summedUp(); + + adderSteps.whenAdd(); + adderSteps.sumWrong(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java new file mode 100644 index 0000000000..87c66f03d9 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextInitWorkaroundIntegrationTest.java @@ -0,0 +1,51 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderServiceSteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; +import net.thucydides.core.annotations.Steps; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +@RunWith(SerenityRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@ContextConfiguration(classes = AdderService.class) +public class AdderMethodDirtiesContextInitWorkaroundIntegrationTest { + + @Steps private AdderServiceSteps adderServiceSteps; + + @Before + public void init() { + adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt()); + } + + @Test + public void _1_givenNumber_whenAdd_thenSumWrong() { + adderServiceSteps.whenAdd(); + adderServiceSteps.summedUp(); + } + + @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule(); + + @DirtiesContext + @Test + public void _0_givenNumber_whenAddAndAccumulate_thenSummedUp() { + adderServiceSteps.whenAccumulate(); + adderServiceSteps.summedUp(); + + adderServiceSteps.whenAdd(); + adderServiceSteps.sumWrong(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java new file mode 100644 index 0000000000..263ffc9854 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodDirtiesContextIntegrationTest.java @@ -0,0 +1,46 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderServiceSteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; +import net.thucydides.core.annotations.Steps; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +@RunWith(SerenityRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@ContextConfiguration(classes = AdderService.class) +public class AdderMethodDirtiesContextIntegrationTest { + + @Steps private AdderServiceSteps adderServiceSteps; + + @Test + public void _1_givenNumber_whenAdd_thenSumWrong() { + adderServiceSteps.whenAdd(); + adderServiceSteps.sumWrong(); + } + + @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule(); + + @DirtiesContext + @Test + public void _0_givenNumber_whenAddAndAccumulate_thenSummedUp() { + adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt()); + adderServiceSteps.whenAccumulate(); + adderServiceSteps.summedUp(); + + adderServiceSteps.whenAdd(); + adderServiceSteps.sumWrong(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java new file mode 100644 index 0000000000..bbf07a2b95 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMethodRuleIntegrationTest.java @@ -0,0 +1,59 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderSteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; +import net.thucydides.core.annotations.Steps; +import org.junit.*; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.test.context.ContextConfiguration; + +/** + * Unit test for simple App. + */ +@RunWith(SerenityRunner.class) +@ContextConfiguration(locations = "classpath:adder-beans.xml") +public class AdderMethodRuleIntegrationTest { + + private static Logger LOG = LoggerFactory.getLogger(AdderMethodRuleIntegrationTest.class); + + @BeforeClass + public static void initClass() { + LOG.info("static adder before test class: {}", staticAdder); + } + + @AfterClass + public static void destroyClass() { + LOG.info("static adder after test class: {}", staticAdder); + } + + @Before + public void init() { + LOG.info("adder before test: {}", adder); + staticAdder = adder; + } + + @After + public void destroy() { + LOG.info("adder after test: {}", adder); + } + + @Rule public SpringIntegrationMethodRule springMethodIntegration = new SpringIntegrationMethodRule(); + + @Steps private AdderSteps adderSteps; + + @Value("#{props['adder']}") private int adder; + + private static int staticAdder; + + @Test + public void givenNumber_whenAdd_thenSummedUp() { + adderSteps.givenNumber(); + adderSteps.whenAdd(adder); + adderSteps.thenSummedUp(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java new file mode 100644 index 0000000000..2b2777f0ed --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderMockMvcIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderRestSteps; +import io.restassured.module.mockmvc.RestAssuredMockMvc; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.thucydides.core.annotations.Steps; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +@RunWith(SerenityRunner.class) +public class AdderMockMvcIntegrationTest { + + @Before + public void init() { + RestAssuredMockMvc.standaloneSetup(new PlainAdderController()); + } + + @Steps AdderRestSteps steps; + + @Test + public void givenNumber_whenAdd_thenSummedUp() throws Exception { + steps.givenCurrentNumber(); + steps.whenAddNumber(randomInt()); + steps.thenSummedUp(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java new file mode 100644 index 0000000000..5f2aae8e3f --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderServiceIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderServiceSteps; +import net.serenitybdd.junit.runners.SerenityRunner; +import net.thucydides.core.annotations.Steps; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +@RunWith(SerenityRunner.class) +public class AdderServiceIntegrationTest { + + @Steps private AdderServiceSteps adderServiceSteps; + + @Test + public void givenNumber_whenAdd_thenSummedUp() { + adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt()); + adderServiceSteps.whenAdd(); + adderServiceSteps.summedUp(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java new file mode 100644 index 0000000000..cdabc17980 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderSpringSerenityRunnerIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.serenity.spring; + +import com.baeldung.serenity.spring.steps.AdderSteps; +import net.serenitybdd.junit.spring.integration.SpringIntegrationSerenityRunner; +import net.thucydides.core.annotations.Steps; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.test.context.ContextConfiguration; + +/** + * Unit test for simple App. + */ +@RunWith(SpringIntegrationSerenityRunner.class) +@ContextConfiguration(locations = "classpath:adder-beans.xml") +public class AdderSpringSerenityRunnerIntegrationTest { + + @Steps private AdderSteps adderSteps; + + @Value("#{props['adder']}") private int adder; + + @Test + public void givenNumber_whenAdd_thenSummedUp() { + adderSteps.givenNumber(); + adderSteps.whenAdd(adder); + adderSteps.thenSummedUp(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/AdderTest.java similarity index 55% rename from libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeTest.java rename to libraries/src/test/java/com/baeldung/serenity/spring/AdderTest.java index d2e5fd30f6..a57b924211 100644 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeTest.java +++ b/libraries/src/test/java/com/baeldung/serenity/spring/AdderTest.java @@ -9,14 +9,14 @@ import org.springframework.test.context.ContextConfiguration; /** * @author aiet */ -@ContextConfiguration(classes = { KonamiCodeServiceInjectionController.class, KonamiCodeService.class }) -public class KonamiCodeTest extends SerenityStory { +@ContextConfiguration(classes = { AdderController.class, AdderService.class }) +public class AdderTest extends SerenityStory { - @Autowired private KonamiCodeService konamiCodeService; + @Autowired private AdderService adderService; @BeforeStory public void init() { - RestAssuredMockMvc.standaloneSetup(new KonamiCodeServiceInjectionController(konamiCodeService)); + RestAssuredMockMvc.standaloneSetup(new AdderController(adderService)); } } diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatClassDirtiesContextIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatClassDirtiesContextIntegrationTest.java deleted file mode 100644 index 2e2fcd676f..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatClassDirtiesContextIntegrationTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCodeServiceInjectionSteps; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.serenitybdd.junit.spring.integration.SpringIntegrationClassRule; -import net.thucydides.core.annotations.Steps; -import net.thucydides.core.annotations.Title; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; - -import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; - -/** - * @author aiet - */ - -@RunWith(Suite.class) -@Suite.SuiteClasses({ - KonamCheatClassDirtiesContextIntegrationTest.DirtiesContextTest.class, KonamCheatClassDirtiesContextIntegrationTest.AnotherDirtiesContextTest.class - }) -public class KonamCheatClassDirtiesContextIntegrationTest { - - @RunWith(SerenityRunner.class) - @ContextConfiguration(classes = KonamiCodeService.class) - public static abstract class Base { - - @Steps KonamiCodeServiceInjectionSteps cheatSteps; - - @ClassRule public static SpringIntegrationClassRule springIntegrationClassRule = new SpringIntegrationClassRule(); - - void hiddenStageShouldBeUnlockedAfterCheating() { - fetchAndCheat(); - cheatSteps.aStageRemains(); - - cheatSteps.letsHack(); - - fetchAndCheat(); - cheatSteps.noStageRemains(); - } - - private void fetchAndCheat() { - cheatSteps.gameStageCleared(); - cheatSteps.fetchLatestCheatcode(); - cheatSteps.cheatWithLatestcode(); - } - - } - - @DirtiesContext(classMode = AFTER_CLASS) - public static class AnotherDirtiesContextTest extends Base { - - @Test - @Title("altering the cheatcode after unlocking would stop others from cheating, not affected by other tests (another)") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - super.hiddenStageShouldBeUnlockedAfterCheating(); - } - } - - @DirtiesContext(classMode = AFTER_CLASS) - public static class DirtiesContextTest extends Base { - - @Test - @Title("altering the cheatcode after unlocking would stop others from cheating, not affected by other tests") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - super.hiddenStageShouldBeUnlockedAfterCheating(); - } - } - - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionIntegrationTest.java deleted file mode 100644 index bbda1566af..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionIntegrationTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCodeConstructorDependencySteps; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; -import net.thucydides.core.annotations.Title; -import org.junit.Before; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author aiet - */ -@RunWith(SerenityRunner.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@ContextConfiguration(classes = KonamiCodeService.class) -public class KonamCheatWithDirtyActionIntegrationTest { - - private KonamiCodeConstructorDependencySteps cheatSteps; - - @Autowired private KonamiCodeService codeService; - - @Before - public void init() { - cheatSteps = new KonamiCodeConstructorDependencySteps(codeService); - } - - @Test - @Title("hidden stage should be unlocked after cheating (run in service with dirty action)") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - fetchCodeAndCheat(); - cheatSteps.aStageRemains(); - } - - @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule(); - - @DirtiesContext - @Test - @Title("altering the cheatcode after unlocking would stop others from cheating") - public void givenGameStageCleared_whenCheatAndHack_thenAnotherCheatFail() { - fetchCodeAndCheat(); - cheatSteps.aStageRemains(); - - cheatSteps.letsHack(); - - fetchCodeAndCheat(); - cheatSteps.noStageRemains(); - } - - private void fetchCodeAndCheat() { - cheatSteps.gameStageCleared(); - cheatSteps.fetchLatestCheatcode(); - cheatSteps.cheatWithLatestcode(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionWithImplicitInjectionIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionWithImplicitInjectionIntegrationTest.java deleted file mode 100644 index d9b8bd2cc7..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithDirtyActionWithImplicitInjectionIntegrationTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCodeServiceInjectionSteps; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; -import net.thucydides.core.annotations.Steps; -import net.thucydides.core.annotations.Title; -import org.junit.FixMethodOrder; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author aiet - */ -@RunWith(SerenityRunner.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -@ContextConfiguration(classes = KonamiCodeService.class) -public class KonamCheatWithDirtyActionWithImplicitInjectionIntegrationTest { - - @Steps private KonamiCodeServiceInjectionSteps cheatSteps; - - @Test - @Title("hidden stage is not unlocked after cheating (cheatcode hacked)") - public void givenGameStageCleared_whenCheat_thenCheatFail() { - fetchCodeAndCheat(); - cheatSteps.noStageRemains(); - } - - private void fetchCodeAndCheat() { - cheatSteps.gameStageCleared(); - cheatSteps.fetchLatestCheatcode(); - cheatSteps.cheatWithLatestcode(); - } - - @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule(); - - @DirtiesContext - @Test - @Title("altering the cheatcode after unlocking would stop others from cheating") - public void givenGameStageCleared_whenCheatAndHack_thenAnotherCheatFail() { - fetchCodeAndCheat(); - cheatSteps.aStageRemains(); - - cheatSteps.letsHack(); - - fetchCodeAndCheat(); - cheatSteps.noStageRemains(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithServiceIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithServiceIntegrationTest.java deleted file mode 100644 index ad8a00ec90..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamCheatWithServiceIntegrationTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCodeServiceInjectionSteps; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.thucydides.core.annotations.Steps; -import net.thucydides.core.annotations.Title; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * @author aiet - */ -@RunWith(SerenityRunner.class) -public class KonamCheatWithServiceIntegrationTest { - - @Steps private KonamiCodeServiceInjectionSteps cheatSteps; - - @Test - @Title("hidden stage should be unlocked after cheating (mockmvc)") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - cheatSteps.gameStageCleared(); - cheatSteps.fetchLatestCheatcode(); - cheatSteps.cheatWithLatestcode(); - cheatSteps.aStageRemains(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationMethodRulesIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationMethodRulesIntegrationTest.java deleted file mode 100644 index 634ac92fd9..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationMethodRulesIntegrationTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCheatSteps; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.serenitybdd.junit.spring.integration.SpringIntegrationMethodRule; -import net.thucydides.core.annotations.Steps; -import net.thucydides.core.annotations.Title; -import org.junit.*; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.test.context.ContextConfiguration; - -/** - * Unit test for simple App. - */ -@RunWith(SerenityRunner.class) -@ContextConfiguration(locations = "classpath:konami-cheat-beans.xml") -public class KonamiCheatWithIntegrationMethodRulesIntegrationTest { - - private static Logger LOG = LoggerFactory.getLogger(KonamiCheatWithIntegrationMethodRulesIntegrationTest.class); - - @BeforeClass - public static void initClass() { - LOG.info("static chaincode before test class: {}", staticCheatCode); - } - - @AfterClass - public static void destroyClass() { - LOG.info("static chaincode after test class: {}", staticCheatCode); - } - - @Before - public void init() { - staticCheatCode = cheatCode; - LOG.info("cheatcode before test: {}", cheatCode); - } - - @After - public void destroy() { - LOG.info("cheatcode after test: {}", cheatCode); - } - - @Rule public SpringIntegrationMethodRule springMethodIntegration = new SpringIntegrationMethodRule(); - - @Steps private KonamiCheatSteps konamiCheatSteps; - - @Value("#{konami_props['code']}") private String cheatCode; - - private static String staticCheatCode; - - @Test - @Title("hidden stage should be unlocked after cheating (rule integration)") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - konamiCheatSteps.gameStageCleared(); - konamiCheatSteps.cheatWith(cheatCode); - konamiCheatSteps.aStageRemains(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationRunnerIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationRunnerIntegrationTest.java deleted file mode 100644 index 81c1571cc5..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCheatWithIntegrationRunnerIntegrationTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCheatSteps; -import net.serenitybdd.junit.spring.integration.SpringIntegrationSerenityRunner; -import net.thucydides.core.annotations.Steps; -import net.thucydides.core.annotations.Title; -import org.junit.*; -import org.junit.runner.RunWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.test.context.ContextConfiguration; - -/** - * Unit test for simple App. - */ -@RunWith(SpringIntegrationSerenityRunner.class) -@ContextConfiguration(locations = "classpath:konami-cheat-beans.xml") -public class KonamiCheatWithIntegrationRunnerIntegrationTest { - - private static Logger LOG = LoggerFactory.getLogger(KonamiCheatWithIntegrationRunnerIntegrationTest.class); - - @BeforeClass - public static void initClass() { - LOG.info("static chaincode before test class: {}", staticCheatCode); - } - - @AfterClass - public static void destroyClass() { - LOG.info("static chaincode after test class: {}", staticCheatCode); - } - - @Before - public void init() { - staticCheatCode = cheatCode; - LOG.info("cheatcode before test: {}", cheatCode); - } - - @After - public void destroy() { - LOG.info("cheatcode after test: {}", cheatCode); - } - - @Steps private KonamiCheatSteps konamiCheatSteps; - - @Value("#{konami_props['code']}") private String cheatCode; - - private static String staticCheatCode; - - @Test - @Title("hidden stage should be unlocked after cheating (with integration runner)") - public void givenGameStageCleared_whenCheat_thenHiddenStageUnlocked() { - konamiCheatSteps.gameStageCleared(); - konamiCheatSteps.cheatWith(cheatCode); - konamiCheatSteps.aStageRemains(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeMockMvcIntegrationTest.java b/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeMockMvcIntegrationTest.java deleted file mode 100644 index 12514f8d4a..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/KonamiCodeMockMvcIntegrationTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.baeldung.serenity.spring; - -import com.baeldung.serenity.spring.steps.KonamiCodeRestSteps; -import io.restassured.module.mockmvc.RestAssuredMockMvc; -import net.serenitybdd.junit.runners.SerenityRunner; -import net.thucydides.core.annotations.Steps; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** - * @author aiet - */ -@RunWith(SerenityRunner.class) -public class KonamiCodeMockMvcIntegrationTest { - - @Before - public void init() { - RestAssuredMockMvc.standaloneSetup(new KonamiCodeController()); - } - - @Steps KonamiCodeRestSteps steps; - - @Test - public void givenOfficialClassicCheatcode_whenCheat_ThenTheCodeShouldDoTheTrick() throws Exception { - steps.givenClassicCheatCode(); - steps.whenCheat(); - steps.thenClassicCodeCanDoTheTrick(); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java b/libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java new file mode 100644 index 0000000000..42a532da42 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/RandomNumberUtil.java @@ -0,0 +1,13 @@ +package com.baeldung.serenity.spring; + +import org.apache.commons.lang3.RandomUtils; + +/** + * @author aiet + */ +public class RandomNumberUtil { + + public static int randomInt() { + return RandomUtils.nextInt(1, 10); + } +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java new file mode 100644 index 0000000000..2bf6b0e6d6 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderConstructorDependencySteps.java @@ -0,0 +1,44 @@ +package com.baeldung.serenity.spring.steps; + +import com.baeldung.serenity.spring.AdderService; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * @author aiet + */ +public class AdderConstructorDependencySteps { + + private AdderService adderService; + + public AdderConstructorDependencySteps(AdderService adderService) { + this.adderService = adderService; + } + + private int givenNumber; + private int base; + private int sum; + + public void givenBaseAndAdder(int base, int adder) { + this.base = base; + adderService.baseNum(base); + this.givenNumber = adder; + } + + public void whenAdd() { + sum = adderService.add(givenNumber); + } + + public void summedUp() { + assertEquals(base + givenNumber, sum); + } + + public void sumWrong() { + assertNotEquals(base + givenNumber, sum); + } + + public void whenAccumulate() { + sum = adderService.accumulate(givenNumber); + } +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java new file mode 100644 index 0000000000..0d77ed0849 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderRestSteps.java @@ -0,0 +1,46 @@ +package com.baeldung.serenity.spring.steps; + +import io.restassured.module.mockmvc.response.MockMvcResponse; +import net.thucydides.core.annotations.Step; + +import java.io.UnsupportedEncodingException; + +import static io.restassured.module.mockmvc.RestAssuredMockMvc.given; +import static org.hamcrest.core.IsEqual.equalTo; + +/** + * @author aiet + */ +public class AdderRestSteps { + + private MockMvcResponse mockMvcResponse; + private int currentNum; + + @Step("get the current number") + public void givenCurrentNumber() throws UnsupportedEncodingException { + currentNum = Integer.valueOf(given() + .when() + .get("/adder/current") + .mvcResult() + .getResponse() + .getContentAsString()); + } + + @Step("adding {0}") + public void whenAddNumber(int num) { + mockMvcResponse = given() + .queryParam("num", num) + .when() + .post("/adder"); + currentNum += num; + } + + @Step("got the sum") + public void thenSummedUp() { + mockMvcResponse + .then() + .statusCode(200) + .body(equalTo(currentNum + "")); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java new file mode 100644 index 0000000000..b8c2854bf0 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderServiceSteps.java @@ -0,0 +1,44 @@ +package com.baeldung.serenity.spring.steps; + +import com.baeldung.serenity.spring.AdderService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * @author aiet + */ +@ContextConfiguration(classes = AdderService.class) +public class AdderServiceSteps { + + @Autowired private AdderService adderService; + + private int givenNumber; + private int base; + private int sum; + + public void givenBaseAndAdder(int base, int adder) { + this.base = base; + adderService.baseNum(base); + this.givenNumber = adder; + } + + public void whenAdd() { + sum = adderService.add(givenNumber); + } + + public void summedUp() { + assertEquals(base + givenNumber, sum); + } + + public void sumWrong() { + assertNotEquals(base + givenNumber, sum); + } + + public void whenAccumulate() { + sum = adderService.accumulate(givenNumber); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java new file mode 100644 index 0000000000..6d8d26673b --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/steps/AdderSteps.java @@ -0,0 +1,29 @@ +package com.baeldung.serenity.spring.steps; + +import net.thucydides.core.annotations.Step; + +import static com.baeldung.serenity.spring.RandomNumberUtil.randomInt; + +/** + * @author aiet + */ +public class AdderSteps { + + int currentNumber; + int sum; + + @Step("given current number") + public void givenNumber() { + currentNumber = randomInt(); + } + + @Step("add up {0}") + public void whenAdd(int adder) { + sum = currentNumber + adder; + } + + @Step("summed up") + public void thenSummedUp() { + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCheatSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCheatSteps.java deleted file mode 100644 index 0bb408bda0..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCheatSteps.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.serenity.spring.steps; - -import net.thucydides.core.annotations.Step; - -import static org.junit.Assert.assertEquals; - -/** - * @author aiet - */ -public class KonamiCheatSteps { - - @Step("all stages of the game are cleared") - public void gameStageCleared() { - } - - @Step("input the classic 'Konami Code': {0} ") - public void cheatWith(String cheatcode) { - assertEquals("cheatcode wrong", "↑↑↓↓â†â†’â†â†’BA", cheatcode); - } - - @Step("there is still a stage left") - public void aStageRemains() { - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeConstructorDependencySteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeConstructorDependencySteps.java deleted file mode 100644 index 2bec25b58f..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeConstructorDependencySteps.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.baeldung.serenity.spring.steps; - -import com.baeldung.serenity.spring.KonamiCodeService; -import net.thucydides.core.annotations.Step; -import org.apache.commons.lang3.RandomStringUtils; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.*; - -/** - * @author aiet - */ -public class KonamiCodeConstructorDependencySteps { - - private String latestCheatcode; - private boolean cheatSuccess; - - private KonamiCodeService konamiCodeService; - - public KonamiCodeConstructorDependencySteps(KonamiCodeService konamiCodeService) { - this.konamiCodeService = konamiCodeService; - } - - @Step("fetch latest cheat code") - public void fetchLatestCheatcode() { - latestCheatcode = konamiCodeService.getClassicCode(); - } - - @Step("cheat with latest code") - public void cheatWithLatestcode() { - cheatSuccess = konamiCodeService.cheatWith(latestCheatcode); - } - - @Step("all stages of the game are cleared") - public void gameStageCleared() { - konamiCodeService.clearStage(); - } - - @Step("there is still a stage left") - public void aStageRemains() { - assertTrue("cheatcode wrong", cheatSuccess); - assertThat(konamiCodeService.stageLeft(), equalTo(1)); - } - - // @Rule public SpringIntegrationMethodRule methodRule = new SpringIntegrationMethodRule(); - - // @DirtiesContext - @Step - public void letsHack() { - konamiCodeService.alterClassicCode(RandomStringUtils.random(4)); - } - - @Step("there is no stage left") - public void noStageRemains() { - assertFalse(cheatSuccess); - assertThat(konamiCodeService.stageLeft(), equalTo(0)); - } -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeRestSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeRestSteps.java deleted file mode 100644 index 3f06d42414..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeRestSteps.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.baeldung.serenity.spring.steps; - -import io.restassured.module.mockmvc.response.MockMvcResponse; -import net.thucydides.core.annotations.Step; - -import java.io.UnsupportedEncodingException; - -import static io.restassured.module.mockmvc.RestAssuredMockMvc.given; -import static org.hamcrest.core.IsEqual.equalTo; - -/** - * @author aiet - */ -public class KonamiCodeRestSteps { - - MockMvcResponse mockMvcResponse; - String cheatcode; - - @Step("get the classic cheat code") - public void givenClassicCheatCode() throws UnsupportedEncodingException { - cheatcode = given() - .when() - .get("/konamicode/classic") - .mvcResult() - .getResponse() - .getContentAsString(); - } - - @Step("check if the cheat code works") - public void whenCheat() { - mockMvcResponse = given() - .queryParam("cheatcode", cheatcode) - .when() - .get("/konamicode/cheatable"); - } - - @Step("classic cheat code matches") - public void thenClassicCodeCanDoTheTrick() { - mockMvcResponse - .then() - .statusCode(200) - .body(equalTo("true")); - } - - @Step("all stage cleared") - public void stageCleared() { - given() - .queryParam("action", "clear") - .when() - .put("/konamicode/stages"); - given() - .when() - .get("/konamicode/stages") - .then() - .body(equalTo("0")); - } - - @Step("one more stage to play") - public void thenMoreStages() { - given() - .when() - .get("/konamicode/stages") - .then() - .body(equalTo("1")); - } - -} - diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeServiceInjectionSteps.java b/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeServiceInjectionSteps.java deleted file mode 100644 index b57186ba14..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/steps/KonamiCodeServiceInjectionSteps.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.baeldung.serenity.spring.steps; - -import com.baeldung.serenity.spring.KonamiCodeService; -import net.thucydides.core.annotations.Step; -import org.apache.commons.lang3.RandomStringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; - -import static org.hamcrest.core.IsEqual.equalTo; -import static org.junit.Assert.*; - -/** - * @author aiet - */ -@ContextConfiguration(classes = KonamiCodeService.class) -public class KonamiCodeServiceInjectionSteps { - - private String latestCheatcode; - private boolean cheatSuccess; - - @Autowired private KonamiCodeService konamiCodeService; - - @Step("fetch latest cheat code") - public void fetchLatestCheatcode() { - latestCheatcode = konamiCodeService.getClassicCode(); - } - - @Step("cheat with latest code") - public void cheatWithLatestcode() { - cheatSuccess = konamiCodeService.cheatWith(latestCheatcode); - } - - @Step("all stages of the game are cleared") - public void gameStageCleared() { - konamiCodeService.clearStage(); - } - - @Step("there is still a stage left") - public void aStageRemains() { - assertTrue("cheatcode wrong", cheatSuccess); - assertThat(konamiCodeService.stageLeft(), equalTo(1)); - } - - @Step("altering default cheat code") - public void letsHack() { - konamiCodeService.alterClassicCode(RandomStringUtils.random(4)); - } - - @Step("there is no stage left") - public void noStageRemains() { - assertFalse(cheatSuccess); - assertThat(konamiCodeService.stageLeft(), equalTo(0)); - } - -} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java b/libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java new file mode 100644 index 0000000000..b9fa8f1ae0 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/serenity/spring/stories/AdderStory.java @@ -0,0 +1,31 @@ +package com.baeldung.serenity.spring.stories; + +import com.baeldung.serenity.spring.steps.AdderRestSteps; +import net.thucydides.core.annotations.Steps; +import org.jbehave.core.annotations.Given; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; + +/** + * @author aiet + */ +public class AdderStory { + + @Steps AdderRestSteps restSteps; + + @Given("a number") + public void givenANumber() throws Exception { + restSteps.givenCurrentNumber(); + } + + @When("I submit another number $num to adder") + public void whenISubmitToAdderWithNumber(int num) { + restSteps.whenAddNumber(num); + } + + @Then("I get a sum of the numbers") + public void thenIGetTheSum() { + restSteps.thenSummedUp(); + } + +} diff --git a/libraries/src/test/java/com/baeldung/serenity/spring/stories/KonamiCodeStory.java b/libraries/src/test/java/com/baeldung/serenity/spring/stories/KonamiCodeStory.java deleted file mode 100644 index 090eb63215..0000000000 --- a/libraries/src/test/java/com/baeldung/serenity/spring/stories/KonamiCodeStory.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.serenity.spring.stories; - -import com.baeldung.serenity.spring.steps.KonamiCodeRestSteps; -import net.thucydides.core.annotations.Steps; -import org.jbehave.core.annotations.Given; -import org.jbehave.core.annotations.Then; -import org.jbehave.core.annotations.When; - -/** - * @author aiet - */ -public class KonamiCodeStory { - - @Steps KonamiCodeRestSteps restSteps; - - @Given("game stage cleared") - public void givenStageCleared(){ - restSteps.stageCleared(); - } - - @Given("KONAMI cheat code") - public void givenKONAMICheatCode() throws Exception{ - restSteps.givenClassicCheatCode(); - } - - @When("I input the cheat code") - public void whenIInputTheCheatCode() { - restSteps.whenCheat(); - } - - @Then("a hidden stage will be unlocked") - public void thenAHiddenStageWillBeUnlocked() { - restSteps.thenClassicCodeCanDoTheTrick(); - restSteps.thenMoreStages(); - } - -} diff --git a/libraries/src/test/resources/konami-cheat-beans.xml b/libraries/src/test/resources/adder-beans.xml similarity index 82% rename from libraries/src/test/resources/konami-cheat-beans.xml rename to libraries/src/test/resources/adder-beans.xml index 221d058337..2fbdbd378f 100644 --- a/libraries/src/test/resources/konami-cheat-beans.xml +++ b/libraries/src/test/resources/adder-beans.xml @@ -3,11 +3,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> - - - ↑↑↓↓â†â†’â†â†’BA + + + 4 - + diff --git a/libraries/src/test/resources/stories/spring/adder_test.story b/libraries/src/test/resources/stories/spring/adder_test.story new file mode 100644 index 0000000000..e8de2cf076 --- /dev/null +++ b/libraries/src/test/resources/stories/spring/adder_test.story @@ -0,0 +1,11 @@ +Meta: + +Narrative: +As user +I want to add a number +So that I can have the sum + +Scenario: A user can submit a number to adder and get current sum +Given a number +When I submit another number 5 to adder +Then I get a sum of the numbers \ No newline at end of file diff --git a/libraries/src/test/resources/stories/spring/konami_code_test.story b/libraries/src/test/resources/stories/spring/konami_code_test.story deleted file mode 100644 index bba8ad7ade..0000000000 --- a/libraries/src/test/resources/stories/spring/konami_code_test.story +++ /dev/null @@ -1,12 +0,0 @@ -Meta: - -Narrative: -As a KONAMI player -I want to cheat -So that I can unlock hidden stages of the game - -Scenario: A KONAMI player can use the cheatcode to unlock hidden stages -Given game stage cleared -And KONAMI cheat code -When I input the cheat code -Then a hidden stage will be unlocked \ No newline at end of file From 3b1337598f40b3c0bf1ceaa168389465b6ddb8e3 Mon Sep 17 00:00:00 2001 From: Mansi Date: Tue, 23 May 2017 08:28:17 +0530 Subject: [PATCH 20/78] BAEL-823 Iterating over enum values in Java (#1886) * Example Code For Evaluation Article This is an example code for the evaluation article on "Different Types of Bean Injection in Spring" * Added unit tests * Minor changes to application context * BAEL-823 Iterating over enum values in Java * Removed code committed for evaluation article --- .../java/enumiteration/DaysOfWeekEnum.java | 31 +++++++++++++++++++ .../enumiteration/EnumIterationExamples.java | 18 +++++++++++ 2 files changed, 49 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/java/enumiteration/DaysOfWeekEnum.java create mode 100644 core-java/src/main/java/com/baeldung/java/enumiteration/EnumIterationExamples.java diff --git a/core-java/src/main/java/com/baeldung/java/enumiteration/DaysOfWeekEnum.java b/core-java/src/main/java/com/baeldung/java/enumiteration/DaysOfWeekEnum.java new file mode 100644 index 0000000000..89e718adf3 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/enumiteration/DaysOfWeekEnum.java @@ -0,0 +1,31 @@ +package com.baeldung.java.enumiteration; + +import java.util.stream.Stream; + +public enum DaysOfWeekEnum { + SUNDAY("off"), + MONDAY("working"), + TUESDAY("working"), + WEDNESDAY("working"), + THURSDAY("working"), + FRIDAY("working"), + SATURDAY("off"); + + private String typeOfDay; + + DaysOfWeekEnum(String typeOfDay) { + this.typeOfDay = typeOfDay; + } + + public String getTypeOfDay() { + return typeOfDay; + } + + public void setTypeOfDay(String typeOfDay) { + this.typeOfDay = typeOfDay; + } + + public static Stream stream() { + return Stream.of(DaysOfWeekEnum.values()); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/enumiteration/EnumIterationExamples.java b/core-java/src/main/java/com/baeldung/java/enumiteration/EnumIterationExamples.java new file mode 100644 index 0000000000..2d874fa650 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/enumiteration/EnumIterationExamples.java @@ -0,0 +1,18 @@ +package com.baeldung.java.enumiteration; + +import java.util.EnumSet; + +public class EnumIterationExamples { + public static void main(String[] args) { + System.out.println("Enum iteration using forEach:"); + EnumSet.allOf(DaysOfWeekEnum.class).forEach(day -> System.out.println(day)); + + System.out.println("Enum iteration using Stream:"); + DaysOfWeekEnum.stream().filter(d -> d.getTypeOfDay().equals("off")).forEach(System.out::println); + + System.out.println("Enum iteration using for loop:"); + for (DaysOfWeekEnum day : DaysOfWeekEnum.values()) { + System.out.println(day); + } + } +} From 4ded9c02f7e12929f43f330a71c99196270c4899 Mon Sep 17 00:00:00 2001 From: Daniele Demichelis Date: Tue, 23 May 2017 08:47:18 +0200 Subject: [PATCH 21/78] Bael 556 - spring remoting with jms (#1900) * Burlap & Hessian server added * Burlap & Hessian client work * Fixed main * Fixed formatting * Spring Remote example based on Burlap & Hessian runs in a JUnit test * Fixed main * Fixed formatting * Spring Remote example based on Burlap & Hessian runs in a JUnit test * Spring Remote example based on Burlap & Hessian runs in a JUnit test * Burlap & Hessian client work * Fixed main * Fixed main * Fixed formatting * Fixed formatting * Spring Remote example based on Burlap & Hessian runs in a JUnit test * Spring Remote example based on Burlap & Hessian runs in a JUnit test * Fixed POM * first step, compile * works! * works with proper list of trusted packages * works the SpringBoot style * Fixed indentation. --- spring-remoting/pom.xml | 1 + spring-remoting/remoting-jms/pom.xml | 19 +++++++ .../remoting-jms/remoting-jms-client/pom.xml | 35 +++++++++++++ .../java/com/baeldung/client/JmsClient.java | 39 ++++++++++++++ .../src/main/resources/application.properties | 10 ++++ .../remoting-jms/remoting-jms-server/pom.xml | 40 +++++++++++++++ .../server/CabBookingServiceImpl.java | 16 ++++++ .../java/com/baeldung/server/JmsServer.java | 51 +++++++++++++++++++ .../src/main/resources/application.properties | 10 ++++ 9 files changed, 221 insertions(+) create mode 100644 spring-remoting/remoting-jms/pom.xml create mode 100644 spring-remoting/remoting-jms/remoting-jms-client/pom.xml create mode 100644 spring-remoting/remoting-jms/remoting-jms-client/src/main/java/com/baeldung/client/JmsClient.java create mode 100644 spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/application.properties create mode 100644 spring-remoting/remoting-jms/remoting-jms-server/pom.xml create mode 100644 spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java create mode 100644 spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/JmsServer.java create mode 100644 spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/application.properties diff --git a/spring-remoting/pom.xml b/spring-remoting/pom.xml index 8acb38bd44..0b751d1fc9 100644 --- a/spring-remoting/pom.xml +++ b/spring-remoting/pom.xml @@ -32,6 +32,7 @@ remoting-http remoting-hessian-burlap remoting-amqp + remoting-jms \ No newline at end of file diff --git a/spring-remoting/remoting-jms/pom.xml b/spring-remoting/remoting-jms/pom.xml new file mode 100644 index 0000000000..fe36431423 --- /dev/null +++ b/spring-remoting/remoting-jms/pom.xml @@ -0,0 +1,19 @@ + + + + spring-remoting + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + pom + + remoting-jms-client + remoting-jms-server + + remoting-jms + + + \ No newline at end of file diff --git a/spring-remoting/remoting-jms/remoting-jms-client/pom.xml b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml new file mode 100644 index 0000000000..01b7bea657 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-client/pom.xml @@ -0,0 +1,35 @@ + + + + remoting-jms + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + remoting-jms-client + + + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-activemq + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + com.baeldung + api + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-jms/remoting-jms-client/src/main/java/com/baeldung/client/JmsClient.java b/spring-remoting/remoting-jms/remoting-jms-client/src/main/java/com/baeldung/client/JmsClient.java new file mode 100644 index 0000000000..0c5d728f07 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-client/src/main/java/com/baeldung/client/JmsClient.java @@ -0,0 +1,39 @@ +package com.baeldung.client; + +import com.baeldung.api.Booking; +import com.baeldung.api.BookingException; +import com.baeldung.api.CabBookingService; +import org.apache.activemq.command.ActiveMQQueue; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.jms.remoting.JmsInvokerProxyFactoryBean; + +import javax.jms.ConnectionFactory; +import javax.jms.Queue; + +@SpringBootApplication +public class JmsClient { + + @Bean Queue queue() { + return new ActiveMQQueue("remotingQueue"); +} + + @Bean FactoryBean invoker(ConnectionFactory factory, Queue queue) { + JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean(); + factoryBean.setConnectionFactory(factory); + factoryBean.setServiceInterface(CabBookingService.class); + factoryBean.setQueue(queue); + return factoryBean; + } + + public static void main(String[] args) throws BookingException { + CabBookingService service = SpringApplication.run(JmsClient.class, args).getBean(CabBookingService.class); + System.out.println("here"); + Booking bookingOutcome = service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"); + System.out.println("there"); + System.out.println(bookingOutcome); + } + +} diff --git a/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/application.properties b/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/application.properties new file mode 100644 index 0000000000..738b030a59 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-client/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.activemq.broker-url=tcp://127.0.0.1:61616 +spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.baeldung.api + +# Logging +logging.pattern.console=%d{mm:ss.SSS} %-5p [%-31t] [%-54logger{0}] %marker%m%ex{full} - %logger - %F:%L%n +logging.level.root=WARN +logging.level.org.apache.activemq=DEBUG +logging.level.org.springframework.jms=DEBUG +logging.level.org.springframework=WARN + diff --git a/spring-remoting/remoting-jms/remoting-jms-server/pom.xml b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml new file mode 100644 index 0000000000..8feac4df57 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/pom.xml @@ -0,0 +1,40 @@ + + + + remoting-jms + com.baeldung + 1.0-SNAPSHOT + + 4.0.0 + + remoting-jms-server + + + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-activemq + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + com.baeldung + api + + + com.baeldung + api + ${project.version} + + + + \ No newline at end of file diff --git a/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java b/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java new file mode 100644 index 0000000000..55ec9c5733 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/CabBookingServiceImpl.java @@ -0,0 +1,16 @@ +package com.baeldung.server; + +import com.baeldung.api.Booking; +import com.baeldung.api.BookingException; +import com.baeldung.api.CabBookingService; + +import static java.lang.Math.random; +import static java.util.UUID.randomUUID; + +public class CabBookingServiceImpl implements CabBookingService { + + @Override public Booking bookRide(String pickUpLocation) throws BookingException { + if (random() < 0.3) throw new BookingException("Cab unavailable"); + return new Booking(randomUUID().toString()); + } +} diff --git a/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/JmsServer.java b/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/JmsServer.java new file mode 100644 index 0000000000..8572718042 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/src/main/java/com/baeldung/server/JmsServer.java @@ -0,0 +1,51 @@ +package com.baeldung.server; + +import com.baeldung.api.CabBookingService; +import org.apache.activemq.command.ActiveMQQueue; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.jms.listener.SimpleMessageListenerContainer; +import org.springframework.jms.remoting.JmsInvokerServiceExporter; + +import javax.jms.ConnectionFactory; +import javax.jms.Queue; + +@SpringBootApplication public class JmsServer { + + /* + This server needs to be connected to an ActiveMQ server. + To quickly spin up an ActiveMQ server, you can use Docker. + + docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3 + */ + + @Bean CabBookingService bookingService() { + return new CabBookingServiceImpl(); + } + + @Bean Queue queue() { + return new ActiveMQQueue("remotingQueue"); +} + + @Bean JmsInvokerServiceExporter exporter(CabBookingService implementation) { + JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter(); + exporter.setServiceInterface(CabBookingService.class); + exporter.setService(implementation); + return exporter; + } + + @Bean SimpleMessageListenerContainer listener(ConnectionFactory factory, JmsInvokerServiceExporter exporter) { + SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(); + container.setConnectionFactory(factory); + container.setDestinationName("remotingQueue"); + container.setConcurrentConsumers(1); + container.setMessageListener(exporter); + return container; + } + + public static void main(String[] args) { + SpringApplication.run(JmsServer.class, args); + } + +} diff --git a/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/application.properties b/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/application.properties new file mode 100644 index 0000000000..738b030a59 --- /dev/null +++ b/spring-remoting/remoting-jms/remoting-jms-server/src/main/resources/application.properties @@ -0,0 +1,10 @@ +spring.activemq.broker-url=tcp://127.0.0.1:61616 +spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.baeldung.api + +# Logging +logging.pattern.console=%d{mm:ss.SSS} %-5p [%-31t] [%-54logger{0}] %marker%m%ex{full} - %logger - %F:%L%n +logging.level.root=WARN +logging.level.org.apache.activemq=DEBUG +logging.level.org.springframework.jms=DEBUG +logging.level.org.springframework=WARN + From 9a2827f84e7782e806c45d58b7c0d4748b27d57a Mon Sep 17 00:00:00 2001 From: Pritam Banerjee Date: Tue, 23 May 2017 03:32:06 -0700 Subject: [PATCH 22/78] BAEL-725: Map Iteration --- .../baeldung/map/iteration/MapIteration.java | 57 ++++++++++++++++ .../map/iteration/MapIterationTest.java | 68 +++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java create mode 100644 core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java diff --git a/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java b/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java new file mode 100644 index 0000000000..3b2a213aa0 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java @@ -0,0 +1,57 @@ +package com.baeldung.map.iteration; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; + +public class MapIteration { + + public ArrayList iterateUsingEntrySet(Map map) { + ArrayList mapKeyValueList = new ArrayList(); + for (Map.Entry entry : map.entrySet()) { + mapKeyValueList.add(entry.getKey() + ":" + entry.getValue()); + } + return mapKeyValueList; + } + + public ArrayList iterateUsingLambda(Map map) { + ArrayList mapKeyValueList = new ArrayList(); + map.forEach((k, v) -> mapKeyValueList.add(k + ":" + v)); + return mapKeyValueList; + } + + public ArrayList iterateUsingIteratorAndEntry(Map map) { + ArrayList mapKeyValueList = new ArrayList(); + Iterator> iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry pair = iterator.next(); + mapKeyValueList.add(pair.getKey() + ":" + pair.getValue()); + } + + return mapKeyValueList; + } + + public ArrayList iterateUsingKeySetAndForeach(Map map) { + ArrayList mapKeyValueList = new ArrayList(); + for (String key : map.keySet()) { + mapKeyValueList.add(key + ":" + map.get(key)); + } + return mapKeyValueList; + } + + public ArrayList iterateUsingStreamAPI(Map map) { + ArrayList mapKeyValueList = new ArrayList(); + map.entrySet().stream().forEach(e -> mapKeyValueList.add(e.getKey() + ":" + e.getValue())); + return mapKeyValueList; + } + + public ArrayList iterateKeys(Map map) { + ArrayList mapKeyList = new ArrayList(); + for (String key : map.keySet()) { + mapKeyList.add(key); + } + return mapKeyList; + } + +} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java b/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java new file mode 100644 index 0000000000..5953c118fd --- /dev/null +++ b/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java @@ -0,0 +1,68 @@ +package com.baeldung.map.iteration; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class MapIterationTest { + + public static Map testMap = new HashMap(); + public static String testString1 = "One:1"; + public static String testString2 = "Two:2"; + public static String testString3 = "Three:3"; + + @BeforeClass + public static void createTestData() { + testMap.put("One", 1); + testMap.put("Three", 3); + testMap.put("Two", 2); + } + + @Test + public void iterateUsingEntrySet_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateUsingEntrySet(testMap); + assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); + } + + @Test + public void iterateUsingLambda_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateUsingLambda(testMap); + assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); + } + + @Test + public void iterateUsingIteratorAndEntry_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateUsingIteratorAndEntry(testMap); + assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); + } + + @Test + public void iterateUsingKeySetAndForeach_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateUsingKeySetAndForeach(testMap); + assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); + } + + @Test + public void iterateUsingStreamAPI_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateUsingStreamAPI(testMap); + assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); + } + + @Test + public void iterateKeys_test() { + MapIteration mapIteration = new MapIteration(); + ArrayList list = mapIteration.iterateKeys(testMap); + assertTrue((list.contains("One")) && (list.contains("Two")) && (list.contains("Three"))); + } + +} From 4393cdc0f63c52b9307132a9d3e90dd3065441b4 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Tue, 23 May 2017 07:58:17 -0500 Subject: [PATCH 23/78] BAEL-886: Updated README (#1902) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 1cc99a3a6b..1d1e63f36a 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -103,3 +103,4 @@ - [Call Methods at Runtime Using Java Reflection](http://www.baeldung.com/java-method-reflection) - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) +- [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) From 14aea0f12943ad1846b5f58c95b3f7163efca486 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Tue, 23 May 2017 18:11:52 +0200 Subject: [PATCH 24/78] Update .travis.yml (#1901) --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 502c234c72..3a953a2e7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,12 @@ language: java before_install: - - export MAVEN_OPTS="-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit" - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc install: travis_wait 60 mvn -q test -fae sudo: required -before_script: - - echo "MAVEN_OPTS='-Xmx2048M -Xss128M -XX:+CMSClassUnloadingEnabled -XX:+UseG1GC -XX:-UseGCOverheadLimit'" > ~/.mavenrc - jdk: - oraclejdk8 From cc2142b2a161f3317edbe306574344b0514426a2 Mon Sep 17 00:00:00 2001 From: lor6 Date: Tue, 23 May 2017 21:50:00 +0300 Subject: [PATCH 25/78] twelvemonkeys example (#1903) --- image-processing/pom.xml | 10 ++++ .../twelvemonkeys/TwelveMonkeysExample.java | 47 ++++++++++++++++++ .../src/main/resources/Penguin.ico | Bin 0 -> 168290 bytes 3 files changed, 57 insertions(+) create mode 100644 image-processing/src/main/java/com/baeldung/imageprocessing/twelvemonkeys/TwelveMonkeysExample.java create mode 100644 image-processing/src/main/resources/Penguin.ico diff --git a/image-processing/pom.xml b/image-processing/pom.xml index ccb3238a7e..2e4063964e 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -40,6 +40,16 @@ commons-logging + + + com.twelvemonkeys.imageio + imageio-core + 3.3.2 + + + com.twelvemonkeys.imageio + imageio-bmp + 3.3.2 diff --git a/image-processing/src/main/java/com/baeldung/imageprocessing/twelvemonkeys/TwelveMonkeysExample.java b/image-processing/src/main/java/com/baeldung/imageprocessing/twelvemonkeys/TwelveMonkeysExample.java new file mode 100644 index 0000000000..78c7b6a99b --- /dev/null +++ b/image-processing/src/main/java/com/baeldung/imageprocessing/twelvemonkeys/TwelveMonkeysExample.java @@ -0,0 +1,47 @@ +package com.baeldung.imageprocessing.twelvemonkeys; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class TwelveMonkeysExample { + public static void main(String[] args) throws IOException { + BufferedImage image = loadImage(); + drawRectangle(image); + displayImage(image); + } + + private static BufferedImage loadImage() throws IOException { + String imagePath = TwelveMonkeysExample.class.getClassLoader().getResource("Penguin.ico").getPath(); + return ImageIO.read(new File(imagePath)); + } + + private static void drawRectangle(BufferedImage image) { + Graphics2D g = (Graphics2D) image.getGraphics(); + g.setStroke(new BasicStroke(3)); + g.setColor(Color.BLUE); + g.drawRect(10, 10, image.getWidth() - 20, image.getHeight() - 20); + } + + private static void displayImage(BufferedImage image) { + JLabel picLabel = new JLabel(new ImageIcon(image)); + + JPanel jPanel = new JPanel(); + jPanel.add(picLabel); + + JFrame f = new JFrame(); + f.setSize(new Dimension(200, 200)); + f.add(jPanel); + f.setVisible(true); + } +} diff --git a/image-processing/src/main/resources/Penguin.ico b/image-processing/src/main/resources/Penguin.ico new file mode 100644 index 0000000000000000000000000000000000000000..a6df5d71a86428c01de70065146b890f299165b5 GIT binary patch literal 168290 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 )m7ehxEs7q#Ox@T- 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%0A6U-s+G$RLH8&R$Yvu~;5o_z!aX#A50E>r2mDwe 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 literal 0 HcmV?d00001 From 2bfc5bd979677c04d057a14cc8e7d31aa7d51d57 Mon Sep 17 00:00:00 2001 From: parthkaria Date: Wed, 24 May 2017 01:10:46 +0530 Subject: [PATCH 26/78] BAEL-831 Updated examples (#1904) * Dependency Injection examples Dependency Injection examples for evaluation article * Junit test cases added for dependency injection Junit test cases added for dependency injection * ClassNotFoundException vs NoClassDefFoundError Example to reproduce ClassNotFoundException & NoClassDefFoundError * JUnit test cases for ClassNotFoundException & NoClassDefFoundError test cases to reproduce ClassNotFoundException & NoClassDefFoundError * Deleting exampls for evaluation article * BAEL-831 Examples for ClassNotFoundException & NoClassDefFoundError * BAEL-831 Removed wrapper class * Removing evaluation article example * BAEL-831 removed wrapper class --- .../ClassNotFoundExceptionExample.java | 7 ------- .../classnotfoundexception/ClassNotFoundExceptionTest.java | 3 +-- 2 files changed, 1 insertion(+), 9 deletions(-) delete mode 100644 core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java diff --git a/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java b/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java deleted file mode 100644 index 26d306d03f..0000000000 --- a/core-java/src/main/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionExample.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.baeldung.classnotfoundexception; - -public class ClassNotFoundExceptionExample { - public void loadDrivers() throws ClassNotFoundException { - Class.forName("oracle.jdbc.driver.OracleDriver"); - } -} diff --git a/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java b/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java index 2a16b7effd..a6104e635b 100644 --- a/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java +++ b/core-java/src/test/java/com/baeldung/classnotfoundexception/ClassNotFoundExceptionTest.java @@ -6,7 +6,6 @@ public class ClassNotFoundExceptionTest { @Test(expected = ClassNotFoundException.class) public void givenNoDriversInClassPath_whenLoadDrivers_thenClassNotFoundException() throws ClassNotFoundException { - ClassNotFoundExceptionExample test = new ClassNotFoundExceptionExample(); - test.loadDrivers(); + Class.forName("oracle.jdbc.driver.OracleDriver"); } } From e02050387ced5beee52b48753ba236b1d7bc538f Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:42:58 +0300 Subject: [PATCH 27/78] Update README.md (#1925) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 1d1e63f36a..c21c8f35ec 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,3 +104,4 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) From 3177e3b3af087f81b1cbad7f02bd36d1d1db5e83 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:44:14 +0300 Subject: [PATCH 28/78] Update README.md (#1924) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index c21c8f35ec..0369e88439 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,4 +104,5 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) From ff870c986813764df9f72a67961d1dd725c1630a Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:44:49 +0300 Subject: [PATCH 29/78] Update README.md (#1923) --- core-java/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-java/README.md b/core-java/README.md index 0369e88439..04b5d92407 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,5 +104,7 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) + From e8037caa9dfa12d612ceb5e51561f27099ef9cd6 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:45:22 +0300 Subject: [PATCH 30/78] Update README.md (#1922) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 04b5d92407..1ef4f86e59 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,6 +104,7 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) From 41af122b7f0e8ba064b52aad26ff77000a68c64f Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:46:01 +0300 Subject: [PATCH 31/78] Update README.md (#1921) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 1ef4f86e59..3ed43f6fd2 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,6 +104,7 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) From 633f5b067d30ad347e85e2dfb03d718ab3f8a71f Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:46:30 +0300 Subject: [PATCH 32/78] Update README.md (#1920) --- libraries/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/README.md b/libraries/README.md index 1cfa7be86c..ca47332441 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -9,7 +9,7 @@ - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Intro to JaVer](http://www.baeldung.com/javers) - +- [Intro to JaVer](http://www.baeldung.com/serenity-bdd) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. From 3cd52788b4934fc6a9faec19cbf7c769191b23ef Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:46:43 +0300 Subject: [PATCH 33/78] Update README.MD (#1916) --- spring-boot/README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot/README.MD b/spring-boot/README.MD index a1168106cb..c28851ab7b 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -21,3 +21,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Custom Information in Spring Boot Info Endpoint](http://www.baeldung.com/spring-boot-info-actuator-custom) - [Using @JsonComponent in Spring Boot](http://www.baeldung.com/spring-boot-jsoncomponent) - [Create a Custom Auto-Configuration with Spring Boot](http://www.baeldung.com/spring-boot-custom-auto-configuration) +- [Guide to @ConfigurationProperties in Spring Boot](http://www.baeldung.com/configuration-properties-in-spring-boot) From eaa7d78222e2569a8cd26c5cdb3177daf3d8914a Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:46:54 +0300 Subject: [PATCH 34/78] Update README.md (#1913) --- jee7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/jee7/README.md b/jee7/README.md index fdd260468c..71163d6640 100644 --- a/jee7/README.md +++ b/jee7/README.md @@ -3,3 +3,4 @@ - [JSON Processing in Java EE 7](http://www.baeldung.com/jee7-json) - [Converters, Listeners and Validators in Java EE 7](http://www.baeldung.com/java-ee7-converter-listener-validator) - [Introduction to JAX-WS](http://www.baeldung.com/jax-ws) +- [A Guide to Java EE Web-Related Annotations](http://www.baeldung.com/javaee-web-annotations) From 1083fd41ede5bee38f1a51884557bc3ee3a35eb8 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:47:03 +0300 Subject: [PATCH 35/78] Update README.md (#1912) --- kotlin/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/kotlin/README.md b/kotlin/README.md index 950f6460d5..57d16e0415 100644 --- a/kotlin/README.md +++ b/kotlin/README.md @@ -5,3 +5,4 @@ - [Comprehensive Guide to Null Safety in Kotlin](http://www.baeldung.com/kotlin-null-safety) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Difference Between “==†and “===†in Kotlin]() +- [Generics in Kotlin](http://www.baeldung.com/kotlin-generics) From d0d4344c2fca357ac862f0913df2f01fca8a8956 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:47:39 +0300 Subject: [PATCH 36/78] Update README.md (#1919) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 3ed43f6fd2..550ad96295 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,6 +104,7 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) From 48e5fabb0507e417a3db8d77e1c292f806904ae3 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:48:16 +0300 Subject: [PATCH 37/78] Update README.MD (#1918) --- spring-boot/README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot/README.MD b/spring-boot/README.MD index c28851ab7b..4199b43e9a 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -21,4 +21,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Custom Information in Spring Boot Info Endpoint](http://www.baeldung.com/spring-boot-info-actuator-custom) - [Using @JsonComponent in Spring Boot](http://www.baeldung.com/spring-boot-jsoncomponent) - [Create a Custom Auto-Configuration with Spring Boot](http://www.baeldung.com/spring-boot-custom-auto-configuration) +- [Testing in Spring Boot](http://www.baeldung.com/spring-boot-testing) - [Guide to @ConfigurationProperties in Spring Boot](http://www.baeldung.com/configuration-properties-in-spring-boot) From 3b8e516447094ba2b4a881ed4e1dbbc2207b91d6 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:48:29 +0300 Subject: [PATCH 38/78] Update README.md (#1917) --- spring-cloud/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud/README.md b/spring-cloud/README.md index 2ffb3a86d0..1b793144b1 100644 --- a/spring-cloud/README.md +++ b/spring-cloud/README.md @@ -18,3 +18,4 @@ ### Relevant Articles: - [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon) + [An Introduction to Spring Cloud Zookeeper](http://www.baeldung.com/spring-cloud-zookeeper) From d98ba10f486aff0cc161990fad083f88f12a6bab Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:49:01 +0300 Subject: [PATCH 39/78] Update README.md (#1915) --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 550ad96295..1de57c9311 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -104,6 +104,7 @@ - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) - [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) - [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) From 86ccb23a1a2b181df57f3425da3d7207954854b3 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:49:28 +0300 Subject: [PATCH 40/78] Update README.md (#1914) --- libraries/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/README.md b/libraries/README.md index ca47332441..c405cc90d8 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -9,6 +9,7 @@ - [Introduction to Apache Flink with Java](http://www.baeldung.com/apache-flink) - [Introduction to JSONassert](http://www.baeldung.com/jsonassert) - [Intro to JaVer](http://www.baeldung.com/javers) +- [Introduction to Apache Commons Math](http://www.baeldung.com/apache-commons-math) - [Intro to JaVer](http://www.baeldung.com/serenity-bdd) The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own. From 4807b6f080b4ee7473f1e6fb2f795650c16e581d Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 19:49:38 +0300 Subject: [PATCH 41/78] Update README.md (#1911) --- guava21/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/guava21/README.md b/guava21/README.md index 8725352d69..2a54416e41 100644 --- a/guava21/README.md +++ b/guava21/README.md @@ -1,2 +1,3 @@ ### Relevant articles: - [New Stream, Comparator and Collector Functionality in Guava 21](http://www.baeldung.com/guava-21-new) +- [New in Guava 21 common.util.concurrent](http://www.baeldung.com/guava-21-util-concurrent) From 550ad9c57e42f2eec34116ec56a309e7419cf2b9 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Wed, 24 May 2017 18:49:57 +0200 Subject: [PATCH 42/78] Update pom.xml (#1910) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3663d1308a..6ae5440a3e 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ selenium-junit-testng solr spark-java - spring-5 + spring-akka spring-amqp spring-all From d31b661415b784a4b98d6975c1ac5226fb094bec Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 21:19:39 +0300 Subject: [PATCH 43/78] Create README.md --- spring-amqp-simple/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 spring-amqp-simple/README.md diff --git a/spring-amqp-simple/README.md b/spring-amqp-simple/README.md new file mode 100644 index 0000000000..a176247d4c --- /dev/null +++ b/spring-amqp-simple/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [RabbitMQ Message Dispatching with Spring AMQP](http://www.baeldung.com/rabbitmq-spring-amqp) From bddc05ae79a21676bf4e15e83ea553c6ced985d0 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 21:20:57 +0300 Subject: [PATCH 44/78] Create README.md --- spring-boot-custom-starter/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 spring-boot-custom-starter/README.md diff --git a/spring-boot-custom-starter/README.md b/spring-boot-custom-starter/README.md new file mode 100644 index 0000000000..5b05394d6e --- /dev/null +++ b/spring-boot-custom-starter/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Creating a Custom Starter with Spring Boot](http://www.baeldung.com/spring-boot-custom-starter) From dd3b537d91a55a2dea6c135ccf723afc009e1bf2 Mon Sep 17 00:00:00 2001 From: MMonik Date: Wed, 24 May 2017 21:21:59 +0300 Subject: [PATCH 45/78] Create README.md --- mybatis/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 mybatis/README.md diff --git a/mybatis/README.md b/mybatis/README.md new file mode 100644 index 0000000000..7c366aeab6 --- /dev/null +++ b/mybatis/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Quick Guide to MyBatis](http://www.baeldung.com/mybatis) From 513c1c5e6975d68fb88df390dda95cf3dc2429d5 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Wed, 24 May 2017 22:13:42 +0200 Subject: [PATCH 46/78] Update pom.xml (#1929) * Update pom.xml * Update pom.xml --- pom.xml | 2 +- spring-5/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6ae5440a3e..5216eb306b 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ selenium-junit-testng solr spark-java - + spring-5 spring-akka spring-amqp spring-all diff --git a/spring-5/pom.xml b/spring-5/pom.xml index 63014d6e51..605dbe39e1 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.M1 From a2e2192494535b7c34f97a56bc28af4ee9b17bee Mon Sep 17 00:00:00 2001 From: Alex Vargas Date: Wed, 24 May 2017 14:23:49 -0700 Subject: [PATCH 47/78] Code example for article BAEL-818 (#1909) * Quartz example for article: Introduction to Quartz * Adding new module for Java Quartz * Removing Quartz code from jee7 module * Fixing folder structure --- java-quartz/pom.xml | 31 + .../baeldung/java_quartz/QuartzExample.java | 42 + .../com/baeldung/java_quartz/SimpleJob.java | 13 + .../com/baeldung/java_quartz/AppTest.java | 38 + jee7/pom.xml | 720 +++++++++--------- 5 files changed, 484 insertions(+), 360 deletions(-) create mode 100644 java-quartz/pom.xml create mode 100644 java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java create mode 100644 java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java create mode 100644 java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java diff --git a/java-quartz/pom.xml b/java-quartz/pom.xml new file mode 100644 index 0000000000..51b9d56a7b --- /dev/null +++ b/java-quartz/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + com.baeldung + java-quartz + 0.0.1-SNAPSHOT + jar + + java-quartz + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.quartz-scheduler + quartz + 2.3.0 + + + + diff --git a/java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java b/java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java new file mode 100644 index 0000000000..89cd2680e2 --- /dev/null +++ b/java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java @@ -0,0 +1,42 @@ +package com.baeldung.java_quartz; + +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SchedulerFactory; +import org.quartz.SimpleScheduleBuilder; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.impl.StdSchedulerFactory; + +public class QuartzExample { + + public static void main(String args[]) { + + SchedulerFactory schedFact = new StdSchedulerFactory(); + try { + + Scheduler sched = schedFact.getScheduler(); + + JobDetail job = JobBuilder.newJob(SimpleJob.class) + .withIdentity("myJob", "group1") + .build(); + + Trigger trigger = TriggerBuilder.newTrigger() + .withIdentity("myTrigger", "group1") + .startNow() + .withSchedule(SimpleScheduleBuilder.simpleSchedule() + .withIntervalInSeconds(40) + .repeatForever()) + .build(); + + sched.scheduleJob(job, trigger); + sched.start(); + + } catch (SchedulerException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java b/java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java new file mode 100644 index 0000000000..a9e677c24f --- /dev/null +++ b/java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java @@ -0,0 +1,13 @@ +package com.baeldung.java_quartz; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +public class SimpleJob implements Job { + + public void execute(JobExecutionContext arg0) throws JobExecutionException { + System.out.println("This is a quartz job!"); + } + +} \ No newline at end of file diff --git a/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java b/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java new file mode 100644 index 0000000000..68754c2c15 --- /dev/null +++ b/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java @@ -0,0 +1,38 @@ +package com.baeldung.java_quartz; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/jee7/pom.xml b/jee7/pom.xml index fe7c5e4c11..e633d2df3d 100644 --- a/jee7/pom.xml +++ b/jee7/pom.xml @@ -1,381 +1,381 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - com.baeldung - jee7 - 1.0-SNAPSHOT - JavaEE 7 Arquillian Archetype Sample + com.baeldung + jee7 + 1.0-SNAPSHOT + JavaEE 7 Arquillian Archetype Sample - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - 1.8 - 3.0.0 + + 1.8 + 3.0.0 - 7.0 - 1.1.11.Final - 8.2.1.Final - 1.7.0 - 1.4.6.Final - 3.0.19.Final - 4.1.1 - 1.0.4 - 1.13 - 2.25 - 1.0.0.Final + 7.0 + 1.1.11.Final + 8.2.1.Final + 1.7.0 + 1.4.6.Final + 3.0.19.Final + 4.1.1 + 1.0.4 + 1.13 + 2.25 + 1.0.0.Final - 2.6 - + 2.6 + - - ${maven.min.version} - + + ${maven.min.version} + - - - - org.jboss.arquillian - arquillian-bom - ${arquillian_core.version} - import - pom - - - org.jboss.arquillian.extension - arquillian-drone-bom - 2.0.1.Final - pom - import - - - + + + + org.jboss.arquillian + arquillian-bom + ${arquillian_core.version} + import + pom + + + org.jboss.arquillian.extension + arquillian-drone-bom + 2.0.1.Final + pom + import + + + - - - javax - javaee-api - ${javaee_api.version} - provided - - - - org.jboss.arquillian.junit - arquillian-junit-container - test - + - org.jboss.arquillian.graphene - graphene-webdriver - 2.1.0.Final - pom - test - - - com.jayway.awaitility - awaitility - ${awaitility.version} - test - + javax + javaee-api + ${javaee_api.version} + provided + - - org.jboss.shrinkwrap.resolver - shrinkwrap-resolver-impl-maven - test - jar - - - - org.jboss.shrinkwrap.resolver - shrinkwrap-resolver-impl-maven-archive - test - - - org.apache.httpcomponents - httpclient - 4.5 - - - commons-io - commons-io - 2.4 - - - com.sun.faces - jsf-api - 2.2.14 - - - com.sun.faces - jsf-impl - 2.2.14 - - - javax.servlet - jstl - 1.2 - - - javax.servlet - javax.servlet-api - 3.1.0 - - javax.servlet.jsp - jsp-api - 2.2 - provided + org.jboss.arquillian.junit + arquillian-junit-container + test - taglibs - standard - 1.1.2 - - + org.jboss.arquillian.graphene + graphene-webdriver + 2.1.0.Final + pom + test + + + com.jayway.awaitility + awaitility + ${awaitility.version} + test + - - - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - - - + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-impl-maven + test + jar + - + + org.jboss.shrinkwrap.resolver + shrinkwrap-resolver-impl-maven-archive + test + + + org.apache.httpcomponents + httpclient + 4.5 + + + commons-io + commons-io + 2.4 + + + com.sun.faces + jsf-api + 2.2.14 + + + com.sun.faces + jsf-impl + 2.2.14 + + + javax.servlet + jstl + 1.2 + + + javax.servlet + javax.servlet-api + 3.1.0 + + + javax.servlet.jsp + jsp-api + 2.2 + provided + + + taglibs + standard + 1.1.2 + + - - wildfly-managed-arquillian - - true - - - standalone-full.xml - ${project.build.directory}/wildfly-${version.wildfly} - - - - io.undertow - undertow-websockets-jsr - ${undertow-websockets-jsr.version} - test - - - org.jboss.resteasy - resteasy-client - ${resteasy.version} - test - - - org.jboss.resteasy - resteasy-jaxb-provider - ${resteasy.version} - test - - - org.jboss.resteasy - resteasy-json-p-provider - ${resteasy.version} - test - - - org.wildfly - wildfly-arquillian-container-managed - ${wildfly.version} - test - - - - - - - maven-dependency-plugin - 2.8 - - ${maven.test.skip} - - - - unpack - process-test-classes - - unpack - - - - - org.wildfly - wildfly-dist - ${wildfly.version} - zip - false - ${project.build.directory} - - - - - - - - maven-surefire-plugin - 2.17 - - - ${project.build.directory}/wildfly-${wildfly.version} - - - - - - - - - wildfly-remote-arquillian - - - io.undertow - undertow-websockets-jsr - ${undertow-websockets-jsr.version} - test - - - org.jboss.resteasy - resteasy-client - ${resteasy.version} - test - - - org.jboss.resteasy - resteasy-jaxb-provider - ${resteasy.version} - test - - - org.jboss.resteasy - resteasy-json-p-provider - ${resteasy.version} - test - - - org.wildfly - wildfly-arquillian-container-remote - ${wildfly.version} - test - - - - - glassfish-embedded-arquillian - - - org.glassfish.main.extras - glassfish-embedded-all - ${glassfish-embedded-all.version} - test - - - org.glassfish - javax.json - ${javax.json.version} - test - - - org.glassfish.tyrus - tyrus-client - ${tyrus.version} - test - - - org.glassfish.tyrus - tyrus-container-grizzly-client - ${tyrus.version} - test - - - org.glassfish.jersey.core - jersey-client - ${jersey.version} - test - - - org.jboss.arquillian.container - arquillian-glassfish-embedded-3.1 - ${arquillian-glassfish.version} - test - - - - - glassfish-remote-arquillian - - - org.glassfish - javax.json - ${javax.json.version} - test - - - org.glassfish.tyrus - tyrus-client - ${tyrus.version} - test - - - org.glassfish.tyrus - tyrus-container-grizzly-client - ${tyrus.version} - test - - - org.glassfish.jersey.core - jersey-client - ${jersey.version} - test - - - org.glassfish.jersey.media - jersey-media-json-jackson - ${jersey.version} - test - - - org.glassfish.jersey.media - jersey-media-json-processing - ${jersey.version} - test - - - org.jboss.arquillian.container - arquillian-glassfish-remote-3.1 - ${arquillian-glassfish.version} - test - - - - - webdriver-chrome - - true - - - chrome - - + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin.version} + + false + + + + - - webdriver-firefox - - firefox - + + + + wildfly-managed-arquillian + + true + + + standalone-full.xml + ${project.build.directory}/wildfly-${version.wildfly} + + + + io.undertow + undertow-websockets-jsr + ${undertow-websockets-jsr.version} + test + + + org.jboss.resteasy + resteasy-client + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-jaxb-provider + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-json-p-provider + ${resteasy.version} + test + + + org.wildfly + wildfly-arquillian-container-managed + ${wildfly.version} + test + + + + + + + maven-dependency-plugin + 2.8 + + ${maven.test.skip} + + + + unpack + process-test-classes + + unpack + + + + + org.wildfly + wildfly-dist + ${wildfly.version} + zip + false + ${project.build.directory} + + + + + + + + maven-surefire-plugin + 2.17 + + + ${project.build.directory}/wildfly-${wildfly.version} + + + + + + - + + wildfly-remote-arquillian + + + io.undertow + undertow-websockets-jsr + ${undertow-websockets-jsr.version} + test + + + org.jboss.resteasy + resteasy-client + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-jaxb-provider + ${resteasy.version} + test + + + org.jboss.resteasy + resteasy-json-p-provider + ${resteasy.version} + test + + + org.wildfly + wildfly-arquillian-container-remote + ${wildfly.version} + test + + + + + glassfish-embedded-arquillian + + + org.glassfish.main.extras + glassfish-embedded-all + ${glassfish-embedded-all.version} + test + + + org.glassfish + javax.json + ${javax.json.version} + test + + + org.glassfish.tyrus + tyrus-client + ${tyrus.version} + test + + + org.glassfish.tyrus + tyrus-container-grizzly-client + ${tyrus.version} + test + + + org.glassfish.jersey.core + jersey-client + ${jersey.version} + test + + + org.jboss.arquillian.container + arquillian-glassfish-embedded-3.1 + ${arquillian-glassfish.version} + test + + + + + glassfish-remote-arquillian + + + org.glassfish + javax.json + ${javax.json.version} + test + + + org.glassfish.tyrus + tyrus-client + ${tyrus.version} + test + + + org.glassfish.tyrus + tyrus-container-grizzly-client + ${tyrus.version} + test + + + org.glassfish.jersey.core + jersey-client + ${jersey.version} + test + + + org.glassfish.jersey.media + jersey-media-json-jackson + ${jersey.version} + test + + + org.glassfish.jersey.media + jersey-media-json-processing + ${jersey.version} + test + + + org.jboss.arquillian.container + arquillian-glassfish-remote-3.1 + ${arquillian-glassfish.version} + test + + + + + webdriver-chrome + + true + + + chrome + + + + + webdriver-firefox + + firefox + + + From 772038390f5833c9acd367bf80211aeccb6b4eaa Mon Sep 17 00:00:00 2001 From: Alex Vargas Date: Thu, 25 May 2017 14:45:53 -0700 Subject: [PATCH 48/78] Code snippets for article BAEL-818 (#1934) * Quartz example for article: Introduction to Quartz * Adding new module for Java Quartz * Removing Quartz code from jee7 module * Fixing folder structure * Removing java-quartz module and adding code snippets in libraries module --- java-quartz/pom.xml | 31 --------------- .../com/baeldung/java_quartz/AppTest.java | 38 ------------------- libraries/pom.xml | 5 +++ .../com/baeldung/quartz}/QuartzExample.java | 2 +- .../java/com/baeldung/quartz}/SimpleJob.java | 2 +- 5 files changed, 7 insertions(+), 71 deletions(-) delete mode 100644 java-quartz/pom.xml delete mode 100644 java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java rename {java-quartz/src/main/java/com/baeldung/java_quartz => libraries/src/main/java/com/baeldung/quartz}/QuartzExample.java (97%) rename {java-quartz/src/main/java/com/baeldung/java_quartz => libraries/src/main/java/com/baeldung/quartz}/SimpleJob.java (89%) diff --git a/java-quartz/pom.xml b/java-quartz/pom.xml deleted file mode 100644 index 51b9d56a7b..0000000000 --- a/java-quartz/pom.xml +++ /dev/null @@ -1,31 +0,0 @@ - - 4.0.0 - - com.baeldung - java-quartz - 0.0.1-SNAPSHOT - jar - - java-quartz - http://maven.apache.org - - - UTF-8 - - - - - junit - junit - 3.8.1 - test - - - org.quartz-scheduler - quartz - 2.3.0 - - - - diff --git a/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java b/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java deleted file mode 100644 index 68754c2c15..0000000000 --- a/java-quartz/src/test/java/com/baeldung/java_quartz/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.baeldung.java_quartz; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} diff --git a/libraries/pom.xml b/libraries/pom.xml index 6d41902db7..95948a83dd 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -269,6 +269,11 @@ h2 1.4.195 + + org.quartz-scheduler + quartz + 2.3.0 + 0.7.0 diff --git a/java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java b/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java similarity index 97% rename from java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java rename to libraries/src/main/java/com/baeldung/quartz/QuartzExample.java index 89cd2680e2..1e37fc028b 100644 --- a/java-quartz/src/main/java/com/baeldung/java_quartz/QuartzExample.java +++ b/libraries/src/main/java/com/baeldung/quartz/QuartzExample.java @@ -1,4 +1,4 @@ -package com.baeldung.java_quartz; +package com.baeldung.quartz; import org.quartz.JobBuilder; import org.quartz.JobDetail; diff --git a/java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java b/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java similarity index 89% rename from java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java rename to libraries/src/main/java/com/baeldung/quartz/SimpleJob.java index a9e677c24f..370d698d13 100644 --- a/java-quartz/src/main/java/com/baeldung/java_quartz/SimpleJob.java +++ b/libraries/src/main/java/com/baeldung/quartz/SimpleJob.java @@ -1,4 +1,4 @@ -package com.baeldung.java_quartz; +package com.baeldung.quartz; import org.quartz.Job; import org.quartz.JobExecutionContext; From c9cd50d58133377c743a8657bb5fceacf70c7df9 Mon Sep 17 00:00:00 2001 From: amilabanuka Date: Fri, 26 May 2017 08:39:08 +0800 Subject: [PATCH 49/78] BAEL-919 (#1931) Added the JUnitParams intorduction classes --- libraries/pom.xml | 7 +++ .../junitparams/SafeAdditionUtil.java | 15 +++++ .../junitparams/SafeAdditionUtilTest.java | 55 +++++++++++++++++++ .../junitparams/TestDataProvider.java | 13 +++++ .../resources/JunitParamsTestParameters.csv | 4 ++ 5 files changed, 94 insertions(+) create mode 100644 libraries/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java create mode 100644 libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java create mode 100644 libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java create mode 100644 libraries/src/test/resources/JunitParamsTestParameters.csv diff --git a/libraries/pom.xml b/libraries/pom.xml index 95948a83dd..3d99c53779 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -269,6 +269,12 @@ h2 1.4.195 + + pl.pragmatists + JUnitParams + ${jUnitParams.version} + test + org.quartz-scheduler quartz @@ -297,6 +303,7 @@ 1.24.0 1.1.3-rc.5 1.4.0 + 1.1.0 diff --git a/libraries/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java b/libraries/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java new file mode 100644 index 0000000000..a2c1573dca --- /dev/null +++ b/libraries/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java @@ -0,0 +1,15 @@ +package com.baeldung.junitparams; + +public class SafeAdditionUtil { + + public int safeAdd(int a, int b) { + long result = ((long) a) + b; + if (result > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else if (result < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + return (int) result; + } + +} diff --git a/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java new file mode 100644 index 0000000000..c9141a6e57 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java @@ -0,0 +1,55 @@ +package com.baeldung.junitparams; + +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import junitparams.FileParameters; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; + +@RunWith(JUnitParamsRunner.class) +public class SafeAdditionUtilTest { + + private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); + + @Test + @Parameters({ "1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15" }) + public void whenCalledWithAnnotationProvidedParams_thenSafeAddAndReturn(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + @Test + @Parameters(method = "parametersToTestAdd") + public void whenCalledWithNamedMethod_thendSafeAddAndReturn(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + private Object[] parametersToTestAdd() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + } + + @Test + @Parameters + public void whenCalledWithnoParam_thenLoadByNameSafeAddAndReturn(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + private Object[] parametersForWhenCalledWithnoParam_thenLoadByNameSafeAddAndReturn() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + } + + @Test + @Parameters(source = TestDataProvider.class) + public void whenCalledWithNamedClass_thenSafeAddAndReturn(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + @Test + @FileParameters("src/test/resources/JunitParamsTestParameters.csv") + public void whenCalledWithCsvFile_thenSafeAddAndReturn(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + +} diff --git a/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java b/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java new file mode 100644 index 0000000000..d318345a56 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/junitparams/TestDataProvider.java @@ -0,0 +1,13 @@ +package com.baeldung.junitparams; + +public class TestDataProvider { + + public static Object[] provideBasicData() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { 15, -5, 10 }, new Object[] { -5, -10, -15 } }; + } + + public static Object[] provideEdgeCaseData() { + return new Object[] { new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -2, Integer.MIN_VALUE }, }; + } + +} diff --git a/libraries/src/test/resources/JunitParamsTestParameters.csv b/libraries/src/test/resources/JunitParamsTestParameters.csv new file mode 100644 index 0000000000..84eb5a0b23 --- /dev/null +++ b/libraries/src/test/resources/JunitParamsTestParameters.csv @@ -0,0 +1,4 @@ +1,2,3 +-10, 30, 20 +15, -5, 10 +-5, -10, -15 \ No newline at end of file From e52d858914a0cf387c4ab34867c4fe72c7007ace Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Fri, 26 May 2017 09:10:52 +0200 Subject: [PATCH 50/78] Update pom.xml (#1935) --- libraries/pom.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 3d99c53779..9c10a13b7b 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -225,12 +225,7 @@ org.datanucleus datanucleus-maven-plugin 5.0.2 - - - com.h2database - h2 - 1.4.194 - + org.datanucleus datanucleus-xml From 8e709d587dbc38ce56cbb83c010162ead5476a6c Mon Sep 17 00:00:00 2001 From: Sunil Mogadati Date: Fri, 26 May 2017 07:26:55 -0600 Subject: [PATCH 51/78] Update README.MD to include Multiple Authentication Providers (#1936) --- spring-security-mvc-boot/README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-mvc-boot/README.MD b/spring-security-mvc-boot/README.MD index 70b0f23cbb..feda6efcd7 100644 --- a/spring-security-mvc-boot/README.MD +++ b/spring-security-mvc-boot/README.MD @@ -7,3 +7,4 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Spring Security: Authentication with a Database-backed UserDetailsService](http://www.baeldung.com/spring-security-authentication-with-a-database) - [Two Login Pages with Spring Security](http://www.baeldung.com/spring-security-two-login-pages) - [Multiple Entry Points in Spring Security](http://www.baeldung.com/spring-security-multiple-entry-points) +- [Multiple Authentication Providers in Spring Security](http://www.baeldung.com/spring-security-multiple-auth-providers) From 49724d1691e3e7d07fcecd625f91a23be0518947 Mon Sep 17 00:00:00 2001 From: amilabanuka Date: Fri, 26 May 2017 23:47:50 +0800 Subject: [PATCH 52/78] BAEL-919: Introduction to JUnitParams (#1938) * BAEL-919 Added the JUnitParams intorduction classes * BAEL-919 Added the JUnitParams intorduction classes * Reverting the adding to libraries folder --- libraries/pom.xml | 1 + testing/pom.xml | 7 +++ .../junitparams/SafeAdditionUtil.java | 15 ++++++ .../junitparams/SafeAdditionUtilTest.java | 54 +++++++++++++++++++ .../junitparams/TestDataProvider.java | 13 +++++ .../resources/JunitParamsTestParameters.csv | 4 ++ 6 files changed, 94 insertions(+) create mode 100644 testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java create mode 100644 testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java create mode 100644 testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java create mode 100644 testing/src/test/resources/JunitParamsTestParameters.csv diff --git a/libraries/pom.xml b/libraries/pom.xml index 9c10a13b7b..a4b554365d 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -275,6 +275,7 @@ quartz 2.3.0 + 0.7.0 diff --git a/testing/pom.xml b/testing/pom.xml index a0bc5b99cf..8c6898ac67 100644 --- a/testing/pom.xml +++ b/testing/pom.xml @@ -64,6 +64,12 @@ ${truth.version} test + + pl.pragmatists + JUnitParams + ${jUnitParams.version} + test + @@ -130,5 +136,6 @@ 3.1.0 3.6.1 0.32 + 1.1.0 diff --git a/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java b/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java new file mode 100644 index 0000000000..a2c1573dca --- /dev/null +++ b/testing/src/main/java/com/baeldung/junitparams/SafeAdditionUtil.java @@ -0,0 +1,15 @@ +package com.baeldung.junitparams; + +public class SafeAdditionUtil { + + public int safeAdd(int a, int b) { + long result = ((long) a) + b; + if (result > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } else if (result < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + return (int) result; + } + +} diff --git a/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java b/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java new file mode 100644 index 0000000000..8ab49309cd --- /dev/null +++ b/testing/src/test/java/com/baeldung/junitparams/SafeAdditionUtilTest.java @@ -0,0 +1,54 @@ +package com.baeldung.junitparams; + +import static org.junit.Assert.assertEquals; + +import junitparams.FileParameters; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(JUnitParamsRunner.class) +public class SafeAdditionUtilTest { + + private SafeAdditionUtil serviceUnderTest = new SafeAdditionUtil(); + + @Test + @Parameters({ "1, 2, 3", "-10, 30, 20", "15, -5, 10", "-5, -10, -15" }) + public void whenWithAnnotationProvidedParams_thenSafeAdd(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + @Test + @Parameters(method = "parametersToTestAdd") + public void whenWithNamedMethod_thendSafeAdd(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + private Object[] parametersToTestAdd() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + } + + @Test + @Parameters + public void whenWithnoParam_thenLoadByNameSafeAdd(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + private Object[] parametersForWhenWithnoParam_thenLoadByNameSafeAdd() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -8, Integer.MIN_VALUE } }; + } + + @Test + @Parameters(source = TestDataProvider.class) + public void whenWithNamedClass_thenSafeAdd(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + + @Test + @FileParameters("src/test/resources/JunitParamsTestParameters.csv") + public void whenWithCsvFile_thenSafeAdd(int a, int b, int expectedValue) { + assertEquals(expectedValue, serviceUnderTest.safeAdd(a, b)); + } + +} diff --git a/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java b/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java new file mode 100644 index 0000000000..d318345a56 --- /dev/null +++ b/testing/src/test/java/com/baeldung/junitparams/TestDataProvider.java @@ -0,0 +1,13 @@ +package com.baeldung.junitparams; + +public class TestDataProvider { + + public static Object[] provideBasicData() { + return new Object[] { new Object[] { 1, 2, 3 }, new Object[] { -10, 30, 20 }, new Object[] { 15, -5, 10 }, new Object[] { -5, -10, -15 } }; + } + + public static Object[] provideEdgeCaseData() { + return new Object[] { new Object[] { Integer.MAX_VALUE, 2, Integer.MAX_VALUE }, new Object[] { Integer.MIN_VALUE, -2, Integer.MIN_VALUE }, }; + } + +} diff --git a/testing/src/test/resources/JunitParamsTestParameters.csv b/testing/src/test/resources/JunitParamsTestParameters.csv new file mode 100644 index 0000000000..84eb5a0b23 --- /dev/null +++ b/testing/src/test/resources/JunitParamsTestParameters.csv @@ -0,0 +1,4 @@ +1,2,3 +-10, 30, 20 +15, -5, 10 +-5, -10, -15 \ No newline at end of file From b9b642c6a9b2c05ac8f663b8c0b882a9ac14e2e3 Mon Sep 17 00:00:00 2001 From: Yasin Date: Sat, 27 May 2017 01:47:42 +0530 Subject: [PATCH 53/78] BAEL-900 Guide to dynamic tests in Junit 5 (#1932) * BAEL-900 Guide to dynamic tests in Junit 5 * BAEL-900 Guide to Dynamic Tests in Junit 5 * Revert "BAEL-900 Guide to Dynamic Tests in Junit 5" This reverts commit d0d45c9067223347da20d0f2c80de391fcade38e. * BAEL-900 Guide to Dynamic Tests in Junit 5 * BAEL-900 Guide to dynamic tests in Junit 5 * removed unnecessary annotation * BAEL-900 unused imports removed --- .../com/baeldung/DynamicTestsExample.java | 26 +++++++++++++ .../java/com/baeldung/helpers/Employee.java | 38 +++++++++++++++++++ .../com/baeldung/helpers/EmployeeDao.java | 16 ++++++++ 3 files changed, 80 insertions(+) create mode 100644 junit5/src/test/java/com/baeldung/helpers/Employee.java create mode 100644 junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java diff --git a/junit5/src/test/java/com/baeldung/DynamicTestsExample.java b/junit5/src/test/java/com/baeldung/DynamicTestsExample.java index ce1f8b16a7..6a97f2347b 100644 --- a/junit5/src/test/java/com/baeldung/DynamicTestsExample.java +++ b/junit5/src/test/java/com/baeldung/DynamicTestsExample.java @@ -18,6 +18,9 @@ import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.function.ThrowingConsumer; +import com.baeldung.helpers.Employee; +import com.baeldung.helpers.EmployeeDao; + public class DynamicTestsExample { @TestFactory @@ -111,6 +114,29 @@ public class DynamicTestsExample { } + @TestFactory + Stream dynamicTestsForEmployeeWorkflows() { + List inputList = + Arrays.asList(new Employee(1, "Fred"), new Employee(2), new Employee(3, "John")); + + EmployeeDao dao = new EmployeeDao(); + Stream saveEmployeeStream = inputList.stream().map(emp -> + DynamicTest.dynamicTest("saveEmployee: " + emp.toString(), () -> { + Employee returned = dao.save(emp.getId()); + assertEquals(returned.getId(), emp.getId()); + })); + + Stream saveEmployeeWithFirstNameStream + = inputList.stream().filter(emp -> !emp.getFirstName().isEmpty()) + .map(emp -> DynamicTest.dynamicTest("saveEmployeeWithName" + emp.toString(), () -> { + Employee returned = dao.save(emp.getId(), emp.getFirstName()); + assertEquals(returned.getId(), emp.getId()); + assertEquals(returned.getFirstName(), emp.getFirstName()); + })); + + return Stream.concat(saveEmployeeStream, saveEmployeeWithFirstNameStream); + } + class DomainNameResolver { private Map ipByDomainName = new HashMap<>(); diff --git a/junit5/src/test/java/com/baeldung/helpers/Employee.java b/junit5/src/test/java/com/baeldung/helpers/Employee.java new file mode 100644 index 0000000000..7fa724e4a8 --- /dev/null +++ b/junit5/src/test/java/com/baeldung/helpers/Employee.java @@ -0,0 +1,38 @@ +package com.baeldung.helpers; + +public class Employee { + + private long id; + private String firstName; + + public Employee(long id) { + this.id = id; + this.firstName = ""; + } + + public Employee(long id, String firstName) { + this.id = id; + this.firstName = firstName; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + @Override + public String toString() { + return "Employee [id=" + id + ", firstName=" + firstName + "]"; + } +} diff --git a/junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java b/junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java new file mode 100644 index 0000000000..b23e5bf5e3 --- /dev/null +++ b/junit5/src/test/java/com/baeldung/helpers/EmployeeDao.java @@ -0,0 +1,16 @@ +package com.baeldung.helpers; + +public class EmployeeDao { + + public Employee save(long id) { + return new Employee(id); + } + + public Employee save(long id, String firstName) { + return new Employee(id, firstName); + } + + public Employee update(Employee employee) { + return employee; + } +} From 7bbfde57e16f7a3de1e7e59ca0ddbbb571b5c1ca Mon Sep 17 00:00:00 2001 From: tschiman Date: Fri, 26 May 2017 18:04:48 -0600 Subject: [PATCH 54/78] BAEL-755 Kotlin and Spring Boot 2.x tutorial --- pom.xml | 1 + spring-boot-kotlin/pom.xml | 137 ++++++++++++++++++ .../springbootkotlin/HelloController.kt | 24 +++ .../baeldung/springbootkotlin/HelloPoko.kt | 3 + .../baeldung/springbootkotlin/HelloService.kt | 10 ++ .../springbootkotlin/KotlinDemoApplication.kt | 11 ++ .../src/main/resource/application.properties | 0 .../KotlinDemoApplicationTests.kt | 52 +++++++ 8 files changed, 238 insertions(+) create mode 100644 spring-boot-kotlin/pom.xml create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloService.kt create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/KotlinDemoApplication.kt create mode 100644 spring-boot-kotlin/src/main/resource/application.properties create mode 100644 spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt diff --git a/pom.xml b/pom.xml index 3663d1308a..d54ac5a2b8 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,7 @@ spring-apache-camel spring-batch spring-boot + spring-boot-kotlin spring-cloud-data-flow spring-cloud spring-core diff --git a/spring-boot-kotlin/pom.xml b/spring-boot-kotlin/pom.xml new file mode 100644 index 0000000000..c882daa816 --- /dev/null +++ b/spring-boot-kotlin/pom.xml @@ -0,0 +1,137 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.BUILD-SNAPSHOT + + + +spring-boot-kotlin +1.0.0-SNAPSHOT + + + true + UTF-8 + UTF-8 + 1.8 + 1.1.2 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + + + com.fasterxml.jackson.module + jackson-module-kotlin + 2.8.7 + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + org.springframework.boot + spring-boot-maven-plugin + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + + spring + + 1.8 + + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + org.jetbrains.kotlin + kotlin-maven-allopen + ${kotlin.version} + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt new file mode 100644 index 0000000000..622271211b --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt @@ -0,0 +1,24 @@ +package com.baeldung.springbootkotlin + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +class HelloController @Autowired constructor(val helloService: HelloService) { + + @GetMapping("/hello") + fun helloKotlin(): String { + return "hello world" + } + + @GetMapping("/hello-service") + fun helloKotlinService(): String { + return helloService.getHello() + } + + @GetMapping("/hello-poko") + fun helloPoko(): HelloPoko { + return HelloPoko("Hello from the poko") + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt new file mode 100644 index 0000000000..7e9c50e073 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt @@ -0,0 +1,3 @@ +package com.baeldung.springbootkotlin + +data class HelloPoko constructor(val greeting: String) diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloService.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloService.kt new file mode 100644 index 0000000000..c988b64e05 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloService.kt @@ -0,0 +1,10 @@ +package com.baeldung.springbootkotlin + +import org.springframework.stereotype.Service + +@Service +class HelloService { + fun getHello(): String { + return "hello service" + } +} \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/KotlinDemoApplication.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/KotlinDemoApplication.kt new file mode 100644 index 0000000000..dbe5694b6d --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/KotlinDemoApplication.kt @@ -0,0 +1,11 @@ +package com.baeldung.springbootkotlin + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication + +@SpringBootApplication +class KotlinDemoApplication + +fun main(args: Array) { + SpringApplication.run(KotlinDemoApplication::class.java, *args) +} diff --git a/spring-boot-kotlin/src/main/resource/application.properties b/spring-boot-kotlin/src/main/resource/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt new file mode 100644 index 0000000000..c6d9146edd --- /dev/null +++ b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt @@ -0,0 +1,52 @@ +package com.example.kotlindemo + +import com.baeldung.springbootkotlin.HelloPoko +import com.baeldung.springbootkotlin.KotlinDemoApplication +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.boot.test.web.client.TestRestTemplate +import org.springframework.http.HttpStatus +import org.springframework.test.context.junit4.SpringRunner + +@RunWith(SpringRunner::class) +@SpringBootTest(classes = arrayOf(KotlinDemoApplication::class), webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +class KotlinDemoApplicationTests { + + @Autowired + val testRestTemplate: TestRestTemplate? = null + + @Test + fun contextLoads() { + } + + @Test + fun testHelloController() { + var result = testRestTemplate?.getForEntity("/hello", String::class.java) + + Assert.assertNotNull(result) + Assert.assertEquals(result?.statusCode, HttpStatus.OK) + Assert.assertEquals(result?.body, "hello world") + } + + @Test + fun testHelloService() { + var result = testRestTemplate?.getForEntity("/hello-service", String::class.java) + + Assert.assertNotNull(result) + Assert.assertEquals(result?.statusCode, HttpStatus.OK) + Assert.assertEquals(result?.body, "hello service") + } + + @Test + fun testHelloPoko() { + var result = testRestTemplate?.getForEntity("/hello-poko", HelloPoko::class.java) + + Assert.assertNotNull(result) + Assert.assertEquals(result?.statusCode, HttpStatus.OK) + Assert.assertEquals(result?.body, HelloPoko("Hello from the poko")) + } + +} From 0ce35bb11e9e66af4764eac142821fc227f6bb1d Mon Sep 17 00:00:00 2001 From: Yasin Date: Sat, 27 May 2017 19:18:20 +0530 Subject: [PATCH 55/78] BAEL-900 Input generator simplified (#1941) * BAEL-900 Guide to dynamic tests in Junit 5 * BAEL-900 Guide to Dynamic Tests in Junit 5 * Revert "BAEL-900 Guide to Dynamic Tests in Junit 5" This reverts commit d0d45c9067223347da20d0f2c80de391fcade38e. * BAEL-900 Guide to Dynamic Tests in Junit 5 * BAEL-900 Guide to dynamic tests in Junit 5 * removed unnecessary annotation * BAEL-900 unused imports removed * BAEL-900 simplified input generator code --- .../com/baeldung/DynamicTestsExample.java | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/junit5/src/test/java/com/baeldung/DynamicTestsExample.java b/junit5/src/test/java/com/baeldung/DynamicTestsExample.java index 6a97f2347b..fd6bb3e0a8 100644 --- a/junit5/src/test/java/com/baeldung/DynamicTestsExample.java +++ b/junit5/src/test/java/com/baeldung/DynamicTestsExample.java @@ -3,7 +3,6 @@ package com.baeldung; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -56,32 +55,12 @@ public class DynamicTestsExample { // sample input and output List inputList = - new ArrayList<>(Arrays.asList("www.somedomain.com", "www.anotherdomain.com", "www.yetanotherdomain.com")); + Arrays.asList("www.somedomain.com", "www.anotherdomain.com", "www.yetanotherdomain.com"); List outputList = - new ArrayList<>(Arrays.asList("154.174.10.56", "211.152.104.132", "178.144.120.156")); + Arrays.asList("154.174.10.56", "211.152.104.132", "178.144.120.156"); // input generator that generates inputs using inputList - Iterator inputGenerator = new Iterator() { - - String current; - int size = inputList.size(); - int index = 0; - - @Override - public boolean hasNext() { - if(index == size) { - return false; - } - current = inputList.get(index); - index++; - return true; - } - - @Override - public String next() { - return current; - } - }; + Iterator inputGenerator = inputList.iterator(); // a display name generator that creates a different name based on the input Function displayNameGenerator = (input) -> "Resolving: " + input; From 7c6536685ce557165a16b137fad6d7e179f898d2 Mon Sep 17 00:00:00 2001 From: Grzegorz Piwowarek Date: Sat, 27 May 2017 20:13:30 +0200 Subject: [PATCH 56/78] Extract a Random instance to a variable (#1942) --- .../main/java/com/baeldung/string/StringHelper.java | 10 +++++----- .../java/org/baeldung/java/JavaRandomUnitTest.java | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/string/StringHelper.java b/core-java/src/main/java/com/baeldung/string/StringHelper.java index ad2a0b3419..dac0d1272e 100644 --- a/core-java/src/main/java/com/baeldung/string/StringHelper.java +++ b/core-java/src/main/java/com/baeldung/string/StringHelper.java @@ -2,23 +2,23 @@ package com.baeldung.string; import java.util.Optional; -public class StringHelper { - public static String removeLastChar(String s) { +class StringHelper { + static String removeLastChar(String s) { return (s == null || s.length() == 0) ? s : (s.substring(0, s.length() - 1)); } - public static String removeLastCharRegex(String s) { + static String removeLastCharRegex(String s) { return (s == null) ? s : s.replaceAll(".$", ""); } - public static String removeLastCharOptional(String s) { + static String removeLastCharOptional(String s) { return Optional.ofNullable(s) .filter(str -> str.length() != 0) .map(str -> str.substring(0, str.length() - 1)) .orElse(s); } - public static String removeLastCharRegexOptional(String s) { + static String removeLastCharRegexOptional(String s) { return Optional.ofNullable(s) .map(str -> str.replaceAll(".$", "")) .orElse(s); diff --git a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java b/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java index f058e5d862..a11659547e 100644 --- a/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java +++ b/core-java/src/test/java/org/baeldung/java/JavaRandomUnitTest.java @@ -167,9 +167,11 @@ public class JavaRandomUnitTest { final int leftLimit = 97; // letter 'a' final int rightLimit = 122; // letter 'z' final int targetStringLength = 10; + final Random random = new Random(); final StringBuilder buffer = new StringBuilder(targetStringLength); + for (int i = 0; i < targetStringLength; i++) { - final int randomLimitedInt = leftLimit + (int) (new Random().nextFloat() * (rightLimit - leftLimit + 1)); + final int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1)); buffer.append((char) randomLimitedInt); } final String generatedString = buffer.toString(); From 99c7a91587f746033b6578fd94ff3080df74cd13 Mon Sep 17 00:00:00 2001 From: Anand kumar Date: Sun, 28 May 2017 15:36:56 +0530 Subject: [PATCH 57/78] guide to uuid generation in java (#1879) * guide to uuid generation in java * updated readme.md --- core-java/README.md | 2 +- .../java/com/baeldung/uuid/UUIDGenerator.java | 118 ++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java diff --git a/core-java/README.md b/core-java/README.md index 1de57c9311..6dd43fe6d9 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -102,6 +102,7 @@ - [How to Perform a Simple HTTP Request in Java](http://www.baeldung.com/java-http-request) - [Call Methods at Runtime Using Java Reflection](http://www.baeldung.com/java-method-reflection) - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) +- [Guide to UUID in JAVA] (http://www.baeldung.com/guide-to-uuid-in-java) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) - [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) @@ -111,4 +112,3 @@ - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) - diff --git a/core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java b/core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java new file mode 100644 index 0000000000..23baf5d5b4 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/uuid/UUIDGenerator.java @@ -0,0 +1,118 @@ +package com.baeldung.uuid; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; + +public class UUIDGenerator { + + /** + * These are predefined UUID for name spaces + */ + private static final String NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; + private static final String NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; + private static final String NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8"; + private static final String NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8"; + + private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); + + public static void main(String[] args) { + try { + System.out.println("Type 3 : " + generateType3UUID(NAMESPACE_DNS, "google.com")); + System.out.println("Type 4 : " + generateType4UUID()); + System.out.println("Type 5 : " + generateType5UUID(NAMESPACE_URL, "google.com")); + System.out.println("Unique key : " + generateUniqueKeysWithUUIDAndMessageDigest()); + } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + /** + * Type 4 UUID Generation + */ + public static UUID generateType4UUID() { + UUID uuid = UUID.randomUUID(); + return uuid; + } + + /** + * Type 3 UUID Generation + * + * @throws UnsupportedEncodingException + */ + public static UUID generateType3UUID(String namespace, String name) throws UnsupportedEncodingException { + String source = namespace + name; + byte[] bytes = source.getBytes("UTF-8"); + UUID uuid = UUID.nameUUIDFromBytes(bytes); + return uuid; + } + + /** + * Type 5 UUID Generation + * + * @throws UnsupportedEncodingException + */ + public static UUID generateType5UUID(String namespace, String name) throws UnsupportedEncodingException { + String source = namespace + name; + byte[] bytes = source.getBytes("UTF-8"); + UUID uuid = type5UUIDFromBytes(bytes); + return uuid; + } + + + public static UUID type5UUIDFromBytes(byte[] name) { + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException nsae) { + throw new InternalError("MD5 not supported", nsae); + } + byte[] bytes = md.digest(name); + bytes[6] &= 0x0f; /* clear version */ + bytes[6] |= 0x50; /* set to version 5 */ + bytes[8] &= 0x3f; /* clear variant */ + bytes[8] |= 0x80; /* set to IETF variant */ + return constructType5UUID(bytes); + } + + private static UUID constructType5UUID(byte[] data) { + long msb = 0; + long lsb = 0; + assert data.length == 16 : "data must be 16 bytes in length"; + + for (int i=0; i<8; i++) + msb = (msb << 8) | (data[i] & 0xff); + + for (int i=8; i<16; i++) + lsb = (lsb << 8) | (data[i] & 0xff); + return new UUID(msb, lsb); + } + + + /** + * Unique Keys Generation Using Message Digest and Type 4 UUID + * + * @throws NoSuchAlgorithmException + * @throws UnsupportedEncodingException + */ + public static String generateUniqueKeysWithUUIDAndMessageDigest() throws NoSuchAlgorithmException, UnsupportedEncodingException { + MessageDigest salt = MessageDigest.getInstance("SHA-256"); + salt.update(UUID.randomUUID() + .toString() + .getBytes("UTF-8")); + String digest = bytesToHex(salt.digest()); + return digest; + } + + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + +} From 8c8c01ebbb121ee67ec0cfcf9921655caf8b30e3 Mon Sep 17 00:00:00 2001 From: Syed Ali Raza Date: Sun, 28 May 2017 15:07:15 +0500 Subject: [PATCH 58/78] BAEL-833: How to get last element of a Stream in Java? (#1930) * Different Types of Bean Injection in Spring * Fixed code formatting and test names for "Different Types of Bean Injection in Spring" * BAEL-833: How to get last element of a Stream in Java? * BAEL-833: Updated based on review from editor --- .../java/com/baeldung/stream/StreamApi.java | 24 +++++++++++ .../com/baeldung/stream/StreamApiTest.java | 43 +++++++++++++++++++ .../baeldung/beaninjection/FileReader.java | 19 ++++++++ .../com/baeldung/beaninjection/FtpReader.java | 28 ++++++++++++ .../com/baeldung/beaninjection/Location.java | 17 ++++++++ .../ReaderApplicationConfig.java | 15 +++++++ .../baeldung/beaninjection/ReaderManager.java | 33 ++++++++++++++ .../baeldung/beaninjection/ReaderService.java | 14 ++++++ .../src/main/resources/injectiontypes.xml | 15 +++++++ .../beaninjection/FileReaderTest.java | 24 +++++++++++ .../baeldung/beaninjection/FtpReaderTest.java | 25 +++++++++++ .../beaninjection/ReaderManagerTest.java | 25 +++++++++++ .../beaninjection/ReaderServiceTest.java | 24 +++++++++++ 13 files changed, 306 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/stream/StreamApi.java create mode 100644 core-java/src/test/java/com/baeldung/stream/StreamApiTest.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/FileReader.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/FtpReader.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/Location.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/ReaderApplicationConfig.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/ReaderManager.java create mode 100644 spring-core/src/main/java/com/baeldung/beaninjection/ReaderService.java create mode 100644 spring-core/src/main/resources/injectiontypes.xml create mode 100644 spring-core/src/test/java/com/baeldung/beaninjection/FileReaderTest.java create mode 100644 spring-core/src/test/java/com/baeldung/beaninjection/FtpReaderTest.java create mode 100644 spring-core/src/test/java/com/baeldung/beaninjection/ReaderManagerTest.java create mode 100644 spring-core/src/test/java/com/baeldung/beaninjection/ReaderServiceTest.java diff --git a/core-java/src/main/java/com/baeldung/stream/StreamApi.java b/core-java/src/main/java/com/baeldung/stream/StreamApi.java new file mode 100644 index 0000000000..ec792314d2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/stream/StreamApi.java @@ -0,0 +1,24 @@ +package com.baeldung.stream; + +import java.util.List; +import java.util.stream.Stream; + +public class StreamApi { + + public String getLastElementUsingReduce(List valueList) { + Stream stream = valueList.stream(); + return stream.reduce((first, second) -> second).orElse(null); + } + + public Integer getInfiniteStreamLastElementUsingReduce() { + Stream stream = Stream.iterate(0, i -> i + 1); + return stream.limit(20).reduce((first, second) -> second).orElse(null); + } + + public String getLastElementUsingSkip(List valueList) { + long count = valueList.stream().count(); + Stream stream = valueList.stream(); + return stream.skip(count - 1).findFirst().orElse(null); + } + +} diff --git a/core-java/src/test/java/com/baeldung/stream/StreamApiTest.java b/core-java/src/test/java/com/baeldung/stream/StreamApiTest.java new file mode 100644 index 0000000000..af52b3ee69 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stream/StreamApiTest.java @@ -0,0 +1,43 @@ +package com.baeldung.stream; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +public class StreamApiTest { + private StreamApi streamApi = new StreamApi(); + + @Test + public void givenList_whenGetLastElementUsingReduce_thenReturnLastElement() { + List valueList = new ArrayList(); + valueList.add("Joe"); + valueList.add("John"); + valueList.add("Sean"); + + String last = streamApi.getLastElementUsingReduce(valueList); + + assertEquals("Sean", last); + } + + @Test + public void givenInfiniteStream_whenGetInfiniteStreamLastElementUsingReduce_thenReturnLastElement() { + Integer last = streamApi.getInfiniteStreamLastElementUsingReduce(); + assertEquals(new Integer(19), last); + } + + @Test + public void givenListAndCount_whenGetLastElementUsingSkip_thenReturnLastElement() { + List valueList = new ArrayList(); + valueList.add("Joe"); + valueList.add("John"); + valueList.add("Sean"); + + String last = streamApi.getLastElementUsingSkip(valueList); + + assertEquals("Sean", last); + } + +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/FileReader.java b/spring-core/src/main/java/com/baeldung/beaninjection/FileReader.java new file mode 100644 index 0000000000..7ea64e2ce6 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/FileReader.java @@ -0,0 +1,19 @@ +package com.baeldung.beaninjection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class FileReader { + + @Autowired + private Location location; + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/FtpReader.java b/spring-core/src/main/java/com/baeldung/beaninjection/FtpReader.java new file mode 100644 index 0000000000..259710ce94 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/FtpReader.java @@ -0,0 +1,28 @@ +package com.baeldung.beaninjection; + +public class FtpReader { + private String ftpHost = null; + private Integer ftpPort = null; + + // Constructor with arguments + public FtpReader(String host, Integer port) { + this.ftpHost = host; + this.ftpPort = port; + } + + public String getFtpHost() { + return ftpHost; + } + + public void setFtpHost(String ftpHost) { + this.ftpHost = ftpHost; + } + + public Integer getFtpPort() { + return ftpPort; + } + + public void setFtpPort(Integer ftpPort) { + this.ftpPort = ftpPort; + } +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/Location.java b/spring-core/src/main/java/com/baeldung/beaninjection/Location.java new file mode 100644 index 0000000000..9ecab83ef6 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/Location.java @@ -0,0 +1,17 @@ +package com.baeldung.beaninjection; + +import org.springframework.stereotype.Component; + +@Component +public class Location { + private String filePath; + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/ReaderApplicationConfig.java b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderApplicationConfig.java new file mode 100644 index 0000000000..cf4d91b1f5 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderApplicationConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.beaninjection; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan(basePackages = { "com.baeldung.beaninjection" }) +public class ReaderApplicationConfig { + + @Bean + public FtpReader exampleDAO() { + return new FtpReader("localhost", 21); + } +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/ReaderManager.java b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderManager.java new file mode 100644 index 0000000000..155f2d6eea --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderManager.java @@ -0,0 +1,33 @@ +package com.baeldung.beaninjection; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ReaderManager { + private FileReader fileReader; + private FtpReader ftpReader; + + @Autowired + public ReaderManager(FtpReader ftpReader) { + this.ftpReader = ftpReader; + } + + @Autowired + public void setFileReader(FileReader fileReader) { + this.fileReader = fileReader; + } + + public FileReader getFileReader() { + return fileReader; + } + + public void setFtpReader(FtpReader ftpReader) { + this.ftpReader = ftpReader; + } + + public FtpReader getFtpReader() { + return ftpReader; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/beaninjection/ReaderService.java b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderService.java new file mode 100644 index 0000000000..60bdac61e5 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/beaninjection/ReaderService.java @@ -0,0 +1,14 @@ +package com.baeldung.beaninjection; + +public class ReaderService { + private FtpReader ftpReader; + + public void setFtpReader(FtpReader reader) { + this.ftpReader = reader; + } + + public FtpReader getFtpReader() { + return ftpReader; + } + +} diff --git a/spring-core/src/main/resources/injectiontypes.xml b/spring-core/src/main/resources/injectiontypes.xml new file mode 100644 index 0000000000..9dad1e300a --- /dev/null +++ b/spring-core/src/main/resources/injectiontypes.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/beaninjection/FileReaderTest.java b/spring-core/src/test/java/com/baeldung/beaninjection/FileReaderTest.java new file mode 100644 index 0000000000..f843fddd4d --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/beaninjection/FileReaderTest.java @@ -0,0 +1,24 @@ +package com.baeldung.beaninjection; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ReaderApplicationConfig.class) +public class FileReaderTest { + + @Autowired + private ApplicationContext context; + + @Test + public void testAutowiredAnnotation_WhenField_ThenInjected() { + FileReader service = context.getBean(FileReader.class); + assertNotNull(service.getLocation()); + } +} diff --git a/spring-core/src/test/java/com/baeldung/beaninjection/FtpReaderTest.java b/spring-core/src/test/java/com/baeldung/beaninjection/FtpReaderTest.java new file mode 100644 index 0000000000..a11afff9ea --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/beaninjection/FtpReaderTest.java @@ -0,0 +1,25 @@ +package com.baeldung.beaninjection; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:injectiontypes.xml") +public class FtpReaderTest { + + @Autowired + private ApplicationContext context; + + @Test + public void testXMLBeanConfig_WhenConstructorArguments_ThenInjected() { + FtpReader service = context.getBean(FtpReader.class); + assertNotNull(service.getFtpHost()); + assertNotNull(service.getFtpPort()); + } +} diff --git a/spring-core/src/test/java/com/baeldung/beaninjection/ReaderManagerTest.java b/spring-core/src/test/java/com/baeldung/beaninjection/ReaderManagerTest.java new file mode 100644 index 0000000000..7d85c0bf07 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/beaninjection/ReaderManagerTest.java @@ -0,0 +1,25 @@ +package com.baeldung.beaninjection; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = ReaderApplicationConfig.class) +public class ReaderManagerTest { + + @Autowired + private ApplicationContext context; + + @Test + public void testAutowiredAnnotation_WhenConstructorAndSetter_ThenInjected() { + ReaderManager service = context.getBean(ReaderManager.class); + assertNotNull(service.getFtpReader()); + assertNotNull(service.getFileReader()); + } +} diff --git a/spring-core/src/test/java/com/baeldung/beaninjection/ReaderServiceTest.java b/spring-core/src/test/java/com/baeldung/beaninjection/ReaderServiceTest.java new file mode 100644 index 0000000000..da4684ad4e --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/beaninjection/ReaderServiceTest.java @@ -0,0 +1,24 @@ +package com.baeldung.beaninjection; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:injectiontypes.xml") +public class ReaderServiceTest { + + @Autowired + private ApplicationContext context; + + @Test + public void testXMLBeanConfig_WhenSetter_ThenInjected() { + ReaderService service = context.getBean(ReaderService.class); + assertNotNull(service.getFtpReader()); + } +} From efd2c2bd341d11205dc16aaf2da386cf2b38e229 Mon Sep 17 00:00:00 2001 From: Parth Joshi Date: Sun, 28 May 2017 22:13:31 +0530 Subject: [PATCH 59/78] Hibernate5 multitenancy changing to hibernate.properties config file. (#1881) * First commit for Hibernate 5 Multitenancy tutorial * Changes to fix the code. * Added hibernate begin transaction code. * Changes to solve the multitenancy issue. * Changes to integrate h2 * Changing configs to solve the error * Changes to solve h2 error... * Changes to fix H2 error. * Cleaned POM.xml and changed entity name * Changes table name to supplier * Removed MySql Dep from pom.xml. * Changes as per comment in the PR... * Removed try-catch from test functions. * Removing the hibernate xml config. * Changed the formatting as per the formatter. * Clean up after merge. * # WARNING: head commit changed in the meantime Merge remote-tracking branch 'upstream/master' into hibernate5-multitenancy Conflicts: hibernate5/pom.xml pom.xml --- hibernate5/pom.xml | 33 +++++++ .../hibernate/HibernateMultiTenantUtil.java | 72 ++++++++++------ .../src/main/resources/hibernate.cfg.xml | 14 --- .../src/main/resources/hibernate.properties | 8 ++ .../MultiTenantHibernateIntegrationTest.java | 86 ++++++++++--------- hibernate5/src/test/java/hibernate.properties | 8 ++ 6 files changed, 141 insertions(+), 80 deletions(-) delete mode 100644 hibernate5/src/main/resources/hibernate.cfg.xml create mode 100644 hibernate5/src/main/resources/hibernate.properties create mode 100644 hibernate5/src/test/java/hibernate.properties diff --git a/hibernate5/pom.xml b/hibernate5/pom.xml index 63e0799281..c501b7f11d 100644 --- a/hibernate5/pom.xml +++ b/hibernate5/pom.xml @@ -15,6 +15,8 @@ http://maven.apache.org UTF-8 + + 3.6.0 @@ -22,6 +24,11 @@ hibernate-core 5.2.9.Final + + junit + junit + 4.12 + com.h2database h2 @@ -37,6 +44,32 @@ + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java index c3e7b621d0..5a10b2ba56 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateMultiTenantUtil.java @@ -1,5 +1,9 @@ package com.baeldung.hibernate; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -20,44 +24,56 @@ import com.baeldung.hibernate.pojo.Supplier; public class HibernateMultiTenantUtil { private static SessionFactory sessionFactory; private static Map connectionProviderMap = new HashMap<>(); - private static final String[] tenantDBNames = { "mydb1","mydb2"}; + private static final String[] tenantDBNames = { "mydb1", "mydb2" }; - public static SessionFactory getSessionFactory() throws UnsupportedTenancyException { + public static SessionFactory getSessionFactory() throws UnsupportedTenancyException, IOException { if (sessionFactory == null) { - Configuration configuration = new Configuration().configure(); - ServiceRegistry serviceRegistry = configureServiceRegistry(configuration); - sessionFactory = makeSessionFactory (serviceRegistry); -// sessionFactory = configuration.buildSessionFactory(serviceRegistry); - - + // Configuration configuration = new Configuration().configure(); + ServiceRegistry serviceRegistry = configureServiceRegistry(); + sessionFactory = makeSessionFactory(serviceRegistry); + } return sessionFactory; } private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) { - MetadataSources metadataSources = new MetadataSources( serviceRegistry ); - for(Class annotatedClasses : getAnnotatedClasses()) { - metadataSources.addAnnotatedClass( annotatedClasses ); + MetadataSources metadataSources = new MetadataSources(serviceRegistry); + for (Class annotatedClasses : getAnnotatedClasses()) { + metadataSources.addAnnotatedClass(annotatedClasses); } Metadata metadata = metadataSources.buildMetadata(); - return metadata.getSessionFactoryBuilder().build(); - + return metadata.getSessionFactoryBuilder() + .build(); + } private static Class[] getAnnotatedClasses() { - return new Class[] { - Supplier.class - }; + return new Class[] { Supplier.class }; } - private static ServiceRegistry configureServiceRegistry(Configuration configuration) throws UnsupportedTenancyException { - Properties properties = configuration.getProperties(); + private static ServiceRegistry configureServiceRegistry() throws UnsupportedTenancyException, IOException { + + // Properties properties = configuration.getProperties(); + Properties properties = getProperties(); connectionProviderMap = setUpConnectionProviders(properties, tenantDBNames); properties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, new ConfigurableMultiTenantConnectionProvider(connectionProviderMap)); - return new StandardServiceRegistryBuilder().applySettings(properties).build(); + return new StandardServiceRegistryBuilder().applySettings(properties) + .build(); + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource("hibernate.properties"); + FileInputStream inputStream = new FileInputStream(propertiesURL.getFile()); + properties.load(inputStream); + System.out.println("LOADED PROPERTIES FROM hibernate.properties"); + + return properties; } private static Map setUpConnectionProviders(Properties properties, String[] tenantNames) throws UnsupportedTenancyException { @@ -66,23 +82,27 @@ public class HibernateMultiTenantUtil { DriverManagerConnectionProviderImpl connectionProvider = new DriverManagerConnectionProviderImpl(); String tenantStrategy = properties.getProperty("hibernate.multiTenancy"); - System.out.println("Strategy:"+tenantStrategy); + System.out.println("Strategy:" + tenantStrategy); properties.put(Environment.URL, tenantUrl(properties.getProperty(Environment.URL), tenant, tenantStrategy)); - System.out.println("URL:"+properties.getProperty(Environment.URL)); + System.out.println("URL:" + properties.getProperty(Environment.URL)); connectionProvider.configure(properties); - System.out.println("Tenant:"+tenant); + System.out.println("Tenant:" + tenant); providerMap.put(tenant, connectionProvider); - + } System.out.println("Added connections for:"); - providerMap.keySet().stream().forEach(System.out::println); + providerMap.keySet() + .stream() + .forEach(System.out::println); return providerMap; } private static Object tenantUrl(String originalUrl, String tenant, String tenantStrategy) throws UnsupportedTenancyException { - if (tenantStrategy.toUpperCase().equals("DATABASE")) { + if (tenantStrategy.toUpperCase() + .equals("DATABASE")) { return originalUrl.replace(DEFAULT_DB_NAME, tenant); - } else if (tenantStrategy.toUpperCase().equals("SCHEMA")) { + } else if (tenantStrategy.toUpperCase() + .equals("SCHEMA")) { return originalUrl + String.format(SCHEMA_TOKEN, tenant); } else { throw new UnsupportedTenancyException("Not yet supported"); diff --git a/hibernate5/src/main/resources/hibernate.cfg.xml b/hibernate5/src/main/resources/hibernate.cfg.xml deleted file mode 100644 index 26be05f931..0000000000 --- a/hibernate5/src/main/resources/hibernate.cfg.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - org.h2.Driver - jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 - sa - - org.hibernate.dialect.H2Dialect - DATABASE - - diff --git a/hibernate5/src/main/resources/hibernate.properties b/hibernate5/src/main/resources/hibernate.properties new file mode 100644 index 0000000000..a8f927a280 --- /dev/null +++ b/hibernate5/src/main/resources/hibernate.properties @@ -0,0 +1,8 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.multiTenancy=DATABASE diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/MultiTenantHibernateIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/MultiTenantHibernateIntegrationTest.java index 8f2e88ac3d..610617cb8d 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/MultiTenantHibernateIntegrationTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/MultiTenantHibernateIntegrationTest.java @@ -1,65 +1,71 @@ package com.baeldung.hibernate; -import com.baeldung.hibernate.pojo.Supplier; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.junit.Test; import static org.junit.Assert.assertNotEquals; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.pojo.Supplier; public class MultiTenantHibernateIntegrationTest { @Test - public void givenDBMode_whenFetchingSuppliers_thenComparingFromDbs () { - SessionFactory sessionFactory; - try { - sessionFactory = HibernateMultiTenantUtil.getSessionFactory(); - - Session db1Session = sessionFactory - .withOptions().tenantIdentifier("mydb1").openSession(); - - initDb1(db1Session); - - Transaction transaction = db1Session.getTransaction(); - transaction.begin(); - Supplier supplierFromDB1 = (Supplier)db1Session.createCriteria(Supplier.class).list().get(0); - transaction.commit(); - - Session db2Session = sessionFactory - .withOptions().tenantIdentifier("mydb2").openSession(); - - initDb2(db2Session); - db2Session.getTransaction().begin(); - Supplier supplierFromDB2 = (Supplier) db2Session.createCriteria(Supplier.class).list().get(0); - db2Session.getTransaction().commit(); - - System.out.println(supplierFromDB1); - System.out.println(supplierFromDB2); - - assertNotEquals(supplierFromDB1, supplierFromDB2); - } catch (UnsupportedTenancyException e) { - e.printStackTrace(); - } + public void givenDBMode_whenFetchingSuppliers_thenComparingFromDbs() throws UnsupportedTenancyException, IOException { + SessionFactory sessionFactory = HibernateMultiTenantUtil.getSessionFactory(); + + Session db1Session = sessionFactory.withOptions().tenantIdentifier("mydb1").openSession(); + + initDb1(db1Session); + + Transaction transaction = db1Session.getTransaction(); + transaction.begin(); + Supplier supplierFromDB1 = (Supplier) db1Session.createCriteria(Supplier.class).list().get(0); + transaction.commit(); + + Session db2Session = sessionFactory.withOptions().tenantIdentifier("mydb2").openSession(); + + initDb2(db2Session); + db2Session.getTransaction().begin(); + Supplier supplierFromDB2 = (Supplier) db2Session.createCriteria(Supplier.class).list().get(0); + db2Session.getTransaction().commit(); + + System.out.println(supplierFromDB1); + System.out.println(supplierFromDB2); + + assertNotEquals(supplierFromDB1, supplierFromDB2); + } - - private void initDb1(Session db1Session) { System.out.println("Init DB1"); Transaction transaction = db1Session.getTransaction(); transaction.begin(); db1Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate(); - db1Session.createSQLQuery("create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))").executeUpdate(); + db1Session + .createSQLQuery( + "create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))") + .executeUpdate(); db1Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'John', 'USA')").executeUpdate(); transaction.commit(); } - + private void initDb2(Session db2Session) { System.out.println("Init DB2"); Transaction transaction = db2Session.getTransaction(); transaction.begin(); db2Session.createSQLQuery("DROP ALL OBJECTS").executeUpdate(); - db2Session.createSQLQuery("create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))").executeUpdate(); + db2Session + .createSQLQuery( + "create table Supplier (id integer generated by default as identity, country varchar(255), name varchar(255), primary key (id))") + .executeUpdate(); db2Session.createSQLQuery("insert into Supplier (id, country, name) values (null, 'Miller', 'UK')").executeUpdate(); transaction.commit(); } diff --git a/hibernate5/src/test/java/hibernate.properties b/hibernate5/src/test/java/hibernate.properties new file mode 100644 index 0000000000..a8f927a280 --- /dev/null +++ b/hibernate5/src/test/java/hibernate.properties @@ -0,0 +1,8 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.multiTenancy=DATABASE From 994ac4ddbf1bb86eee71751ad33c71b40c6c5e2b Mon Sep 17 00:00:00 2001 From: Chandravadan S Date: Mon, 29 May 2017 12:04:13 +0530 Subject: [PATCH 60/78] Dining Philosophers Problem (#1944) --- .../DiningPhilosophers.java | 29 +++++++++++++++ .../diningphilosophers/Philosopher.java | 36 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/DiningPhilosophers.java create mode 100644 core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java diff --git a/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/DiningPhilosophers.java b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/DiningPhilosophers.java new file mode 100644 index 0000000000..7a077432f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/DiningPhilosophers.java @@ -0,0 +1,29 @@ +package com.baeldung.concurrent.diningphilosophers; + +public class DiningPhilosophers { + + public static void main(String[] args) throws Exception { + + Philosopher[] philosophers = new Philosopher[5]; + Object[] forks = new Object[philosophers.length]; + + for (int i = 0; i < forks.length; i++) { + forks[i] = new Object(); + } + + for (int i = 0; i < philosophers.length; i++) { + + Object leftFork = forks[i]; + Object rightFork = forks[(i + 1) % forks.length]; + + if (i == philosophers.length - 1) { + philosophers[i] = new Philosopher(rightFork, leftFork); // The last philosopher picks up the right fork first + } else { + philosophers[i] = new Philosopher(leftFork, rightFork); + } + + Thread t = new Thread(philosophers[i], "Philosopher " + (i + 1)); + t.start(); + } + } +} diff --git a/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java new file mode 100644 index 0000000000..3f1eacd276 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/concurrent/diningphilosophers/Philosopher.java @@ -0,0 +1,36 @@ +package com.baeldung.concurrent.diningphilosophers; + +public class Philosopher implements Runnable { + + private final Object leftFork; + private final Object rightFork; + + public Philosopher(Object left, Object right) { + this.leftFork = left; + this.rightFork = right; + } + + private void doAction(String action) throws InterruptedException { + System.out.println(Thread.currentThread().getName() + " " + action); + Thread.sleep(((int) (Math.random() * 100))); + } + + @Override public void run() { + try { + while (true) { + doAction(System.nanoTime() + ": Thinking"); // thinking + synchronized (leftFork) { + doAction(System.nanoTime() + ": Picked up left fork"); + synchronized (rightFork) { + doAction(System.nanoTime() + ": Picked up right fork - eating"); // eating + doAction(System.nanoTime() + ": Put down right fork"); + } + doAction(System.nanoTime() + ": Put down left fork. Returning to thinking"); + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + } +} \ No newline at end of file From b135086d0710c68846df9749cd84537206b009e4 Mon Sep 17 00:00:00 2001 From: Wim Deblauwe Date: Mon, 29 May 2017 10:30:25 +0200 Subject: [PATCH 61/78] BAEL-885 - How to merge two Java streams? (#1884) Added examples using: * JDK8 * StreamEx library * JOOl library --- libraries/pom.xml | 10 ++++ .../baeldung/stream/JoolMergeStreamsTest.java | 35 ++++++++++++ .../com/baeldung/stream/MergeStreamsTest.java | 53 +++++++++++++++++++ .../stream/StreamExMergeStreamsTest.java | 51 ++++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java create mode 100644 libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java create mode 100644 libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java diff --git a/libraries/pom.xml b/libraries/pom.xml index a4b554365d..ff1997e969 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -276,6 +276,16 @@ 2.3.0 + + one.util + streamex + 0.6.5 + + + org.jooq + jool + 0.9.12 + 0.7.0 diff --git a/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java new file mode 100644 index 0000000000..e73861d8af --- /dev/null +++ b/libraries/src/test/java/com/baeldung/stream/JoolMergeStreamsTest.java @@ -0,0 +1,35 @@ +package com.baeldung.stream; + +import org.jooq.lambda.Seq; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; + +import static junit.framework.TestCase.assertEquals; + +public class JoolMergeStreamsTest { + @Test + public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { + Seq seq1 = Seq.of(1, 3, 5); + Seq seq2 = Seq.of(2, 4, 6); + + Seq resultingSeq = seq1.append(seq2); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), + resultingSeq.toList()); + } + + @Test + public void givenThreeStreams_whenAppendingAndPrependingStreams_thenResultingStreamContainsElementsFromAllStreams() { + Seq seq = Seq.of("foo", "bar"); + Seq openingBracketSeq = Seq.of("["); + Seq closingBracketSeq = Seq.of("]"); + + Seq resultingStream = seq.append(closingBracketSeq) + .prepend(openingBracketSeq); + + Assert.assertEquals(Arrays.asList("[", "foo", "bar", "]"), + resultingStream.toList()); + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java new file mode 100644 index 0000000000..217d2b5b64 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/stream/MergeStreamsTest.java @@ -0,0 +1,53 @@ +package com.baeldung.stream; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.Assert.assertEquals; + +public class MergeStreamsTest { + + @Test + public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { + Stream stream1 = Stream.of(1, 3, 5); + Stream stream2 = Stream.of(2, 4, 6); + + Stream resultingStream = Stream.concat(stream1, + stream2); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), + resultingStream.collect(Collectors.toList())); + } + + @Test + public void givenThreeStreams_whenMergingStreams_thenResultingStreamContainsElementsFromAllStreams() { + Stream stream1 = Stream.of(1, 3, 5); + Stream stream2 = Stream.of(2, 4, 6); + Stream stream3 = Stream.of(18, 15, 36); + + Stream resultingStream = Stream.concat(Stream.concat(stream1, + stream2), + stream3); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36), + resultingStream.collect(Collectors.toList())); + } + + @Test + public void givenFourStreams_whenMergingStreams_thenResultingStreamContainsElementsFromAllStreams() { + Stream stream1 = Stream.of(1, 3, 5); + Stream stream2 = Stream.of(2, 4, 6); + Stream stream3 = Stream.of(18, 15, 36); + Stream stream4 = Stream.of(99); + + Stream resultingStream = Stream.of(stream1, stream2, stream3, stream4).flatMap(Function.identity()); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), + resultingStream.collect(Collectors.toList())); + + } +} \ No newline at end of file diff --git a/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java new file mode 100644 index 0000000000..a964d76e8a --- /dev/null +++ b/libraries/src/test/java/com/baeldung/stream/StreamExMergeStreamsTest.java @@ -0,0 +1,51 @@ +package com.baeldung.stream; + +import one.util.streamex.StreamEx; +import org.junit.Test; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +public class StreamExMergeStreamsTest { + + @Test + public void givenTwoStreams_whenMergingStreams_thenResultingStreamContainsElementsFromBothStreams() { + StreamEx stream1 = StreamEx.of(1, 3, 5); + StreamEx stream2 = StreamEx.of(2, 4, 6); + + StreamEx resultingStream = stream1.append(stream2); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6), + resultingStream.toList()); + } + + @Test + public void givenFourStreams_whenMergingStreams_thenResultingStreamContainsElementsFromAllStreams() { + StreamEx stream1 = StreamEx.of(1, 3, 5); + StreamEx stream2 = StreamEx.of(2, 4, 6); + StreamEx stream3 = StreamEx.of(18, 15, 36); + StreamEx stream4 = StreamEx.of(99); + + StreamEx resultingStream = stream1.append(stream2) + .append(stream3) + .append(stream4); + + assertEquals(Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99), + resultingStream.toList()); + + } + + @Test + public void givenThreeStreams_whenAppendingAndPrependingStreams_thenResultingStreamContainsElementsFromAllStreams() { + StreamEx stream1 = StreamEx.of("foo", "bar"); + StreamEx openingBracketStream = StreamEx.of("["); + StreamEx closingBracketStream = StreamEx.of("]"); + + StreamEx resultingStream = stream1.append(closingBracketStream) + .prepend(openingBracketStream); + + assertEquals(Arrays.asList("[", "foo", "bar", "]"), + resultingStream.toList()); + } +} From fe841fe53b97fd0338553a9f8eb98999ec0547e9 Mon Sep 17 00:00:00 2001 From: asif-anwar Date: Mon, 29 May 2017 16:13:41 +0400 Subject: [PATCH 62/78] spring-5-mvc (#1946) * Spring5 MVC Project * Spring5 MVC Project --- pom.xml | 1 + spring-5-mvc/.gitignore | 20 +++ spring-5-mvc/pom.xml | 154 ++++++++++++++++++ .../java/com/baeldung/Spring5Application.java | 13 ++ .../src/main/java/com/baeldung/model/Foo.java | 84 ++++++++++ .../baeldung/persistence/DataSetupBean.java | 26 +++ .../baeldung/persistence/FooRepository.java | 10 ++ .../java/com/baeldung/web/FooController.java | 66 ++++++++ .../src/main/resources/application.properties | 6 + spring-5-mvc/src/main/webapp/WEB-INF/web.xml | 21 +++ .../test/java/com/baeldung/test/LiveTest.java | 54 ++++++ .../Spring5ApplicationIntegrationTest.java | 18 ++ .../src/test/resources/baeldung-weekly.png | Bin 0 -> 22275 bytes 13 files changed, 473 insertions(+) create mode 100644 spring-5-mvc/.gitignore create mode 100644 spring-5-mvc/pom.xml create mode 100644 spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java create mode 100644 spring-5-mvc/src/main/java/com/baeldung/model/Foo.java create mode 100644 spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java create mode 100644 spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java create mode 100644 spring-5-mvc/src/main/java/com/baeldung/web/FooController.java create mode 100644 spring-5-mvc/src/main/resources/application.properties create mode 100644 spring-5-mvc/src/main/webapp/WEB-INF/web.xml create mode 100644 spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java create mode 100644 spring-5-mvc/src/test/java/com/baeldung/test/Spring5ApplicationIntegrationTest.java create mode 100644 spring-5-mvc/src/test/resources/baeldung-weekly.png diff --git a/pom.xml b/pom.xml index d1b27bc9c9..e6e11326d7 100644 --- a/pom.xml +++ b/pom.xml @@ -122,6 +122,7 @@ solr spark-java spring-5 + spring-5-mvc spring-akka spring-amqp spring-all diff --git a/spring-5-mvc/.gitignore b/spring-5-mvc/.gitignore new file mode 100644 index 0000000000..b7b5c734f2 --- /dev/null +++ b/spring-5-mvc/.gitignore @@ -0,0 +1,20 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +.settings/ +.classpath +.project +target/ + +*.iml +.idea + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/spring-5-mvc/pom.xml b/spring-5-mvc/pom.xml new file mode 100644 index 0000000000..b8c341afde --- /dev/null +++ b/spring-5-mvc/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + + com.baeldung + spring-5-mvc + 0.0.1-SNAPSHOT + jar + + spring-5-mvc + spring 5 MVC sample project about new features + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M1 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + + + + org.apache.commons + commons-lang3 + + + org.slf4j + slf4j-api + + + org.slf4j + jcl-over-slf4j + + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + com.h2database + h2 + runtime + + + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + + junit + junit + test + + + + com.jayway.restassured + rest-assured + ${rest-assured.version} + test + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + false + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + 2.9.0 + UTF-8 + UTF-8 + 1.8 + + + diff --git a/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java b/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java new file mode 100644 index 0000000000..41b5c1eed1 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/Spring5Application.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Spring5Application { + + public static void main(String[] args) { + SpringApplication.run(Spring5Application.class, args); + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java new file mode 100644 index 0000000000..a9ffee14da --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/model/Foo.java @@ -0,0 +1,84 @@ +package com.baeldung.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Foo { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + private String name; + + public Foo() { + super(); + } + + public Foo(final String name) { + super(); + + this.name = name; + } + + public Foo(final long id, final String name) { + super(); + + this.id = id; + this.name = name; + } + + // API + + public String getName() { + return name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public void setName(final String name) { + this.name = name; + } + + // + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Foo other = (Foo) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "Foo [name=" + name + "]"; + } + +} \ No newline at end of file diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java new file mode 100644 index 0000000000..cf78977961 --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/persistence/DataSetupBean.java @@ -0,0 +1,26 @@ +package com.baeldung.persistence; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; + +import java.util.stream.IntStream; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.baeldung.model.Foo; + +@Component +public class DataSetupBean implements InitializingBean { + + @Autowired + private FooRepository repo; + + // + + @Override + public void afterPropertiesSet() throws Exception { + IntStream.range(1, 5).forEach(i -> repo.save(new Foo(randomAlphabetic(8)))); + } + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java b/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java new file mode 100644 index 0000000000..3c70f38fce --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/persistence/FooRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import com.baeldung.model.Foo; + +public interface FooRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java b/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java new file mode 100644 index 0000000000..d03cebb4fd --- /dev/null +++ b/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java @@ -0,0 +1,66 @@ +package com.baeldung.web; + +import java.util.List; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +import com.baeldung.model.Foo; +import com.baeldung.persistence.FooRepository; + +@RestController("/foos") +public class FooController { + + @Autowired + private FooRepository repo; + + // API - read + + @GetMapping("/foos/{id}") + @Validated + public Foo findById(@PathVariable @Min(0) final long id) { + return repo.findById(id).orElse(null); + } + + @GetMapping + public List findAll() { + return repo.findAll(); + } + + @GetMapping(params = { "page", "size" }) + @Validated + public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) { + return repo.findAll(PageRequest.of(page, size)).getContent(); + } + + // API - write + + @PutMapping("/foos/{id}") + @ResponseStatus(HttpStatus.OK) + public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) { + return foo; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public void create( @RequestBody final Foo foo) { + if (null == foo || null == foo.getName()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST," 'name' is required"); + } + repo.save(foo); + } +} diff --git a/spring-5-mvc/src/main/resources/application.properties b/spring-5-mvc/src/main/resources/application.properties new file mode 100644 index 0000000000..886ea1978b --- /dev/null +++ b/spring-5-mvc/src/main/resources/application.properties @@ -0,0 +1,6 @@ +server.port=8081 + +security.user.name=user +security.user.password=pass + +logging.level.root=INFO \ No newline at end of file diff --git a/spring-5-mvc/src/main/webapp/WEB-INF/web.xml b/spring-5-mvc/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..bfcf43dad2 --- /dev/null +++ b/spring-5-mvc/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + Spring Functional Application + + + functional + com.baeldung.functional.RootServlet + 1 + true + + + functional + / + + + + \ No newline at end of file diff --git a/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java b/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java new file mode 100644 index 0000000000..637913541c --- /dev/null +++ b/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java @@ -0,0 +1,54 @@ +package com.baeldung.test; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.http.MediaType; + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.response.Response; +import com.jayway.restassured.specification.RequestSpecification; + +public class LiveTest { + + private static String APP_ROOT = "http://localhost:8081"; + + + @Test + public void givenUser_whenPostWithNullName_then400BadRequest() { + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceWithNullName()).post(APP_ROOT + "/user"); + assertEquals(400, response.getStatusCode()); + } + + @Test + public void givenUser_whenResourceCreated_then201Created() { + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceString()).post(APP_ROOT + "/user"); + assertEquals(201, response.getStatusCode()); + } + + /*@Test + public void givenUser_whenGetAllFoos_thenOK() { + final Response response = givenAuth("user", "pass").get(APP_ROOT + "/foos"); + assertEquals(200, response.getStatusCode()); + }*/ + + + + // + + private final String resourceWithNullName() { + final String roleData = "{\"name\":null}"; + return roleData; + } + + private final String resourceString() { + final String roleData = "{\"name\":\"" + randomAlphabetic(8) + "\"}"; + return roleData; + } + + private final RequestSpecification givenAuth(String username, String password) { + return RestAssured.given().auth().preemptive().basic(username, password); + } + +} \ No newline at end of file diff --git a/spring-5-mvc/src/test/java/com/baeldung/test/Spring5ApplicationIntegrationTest.java b/spring-5-mvc/src/test/java/com/baeldung/test/Spring5ApplicationIntegrationTest.java new file mode 100644 index 0000000000..c3790333ff --- /dev/null +++ b/spring-5-mvc/src/test/java/com/baeldung/test/Spring5ApplicationIntegrationTest.java @@ -0,0 +1,18 @@ +package com.baeldung.test; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.Spring5Application; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = Spring5Application.class) +public class Spring5ApplicationIntegrationTest { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-5-mvc/src/test/resources/baeldung-weekly.png b/spring-5-mvc/src/test/resources/baeldung-weekly.png new file mode 100644 index 0000000000000000000000000000000000000000..5a27d61dae718016a947083e01411ed1bc14f90e GIT binary patch literal 22275 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 Date: Mon, 29 May 2017 17:47:39 +0530 Subject: [PATCH 63/78] BAEL-839 Delete as no longer needed --- .../com/baeldung/regexp/EscapingChars.java | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 core-java/src/main/java/com/baeldung/regexp/EscapingChars.java diff --git a/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java b/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java deleted file mode 100644 index 3268339a15..0000000000 --- a/core-java/src/main/java/com/baeldung/regexp/EscapingChars.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.baeldung.regexp; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class EscapingChars { - public boolean isMatching(String input, String pattern) { - return input.matches(pattern); - } - - public int splitAndCountWords(String input, String pattern) { - return input.split(pattern).length; - } - - public int splitAndCountWordsUsingQuoteMethod(String input, String pattern) { - return input.split(Pattern.quote(pattern)).length; - } - - public String changeCurrencySymbol(String input, String pattern, - String correctStr) { - Pattern p = Pattern.compile(pattern); - Matcher m = p.matcher(input); - return m.replaceAll(correctStr); - } -} From 4586d471a1942834c8aaad8c0dd0681f3a91ba97 Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 29 May 2017 17:55:10 +0530 Subject: [PATCH 64/78] BAEL-839 changes in all test methods --- .../baeldung/regexp/EscapingCharsTest.java | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java index 1e2293955a..49d349f69f 100644 --- a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java +++ b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java @@ -11,57 +11,59 @@ public class EscapingCharsTest { public void givenRegexWithDot_whenMatchingStr_thenMatches() { String strInput = "foof"; String strRegex = "foo."; - EscapingChars e = new EscapingChars(); - - assertEquals(true, e.isMatching(strInput, strRegex)); + + assertEquals(true, strInput.matches(strRegex)); } - + @Test public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching() { String strInput = "foof"; String strRegex = "foo\\."; - EscapingChars e = new EscapingChars(); - - assertEquals(false, e.isMatching(strInput, strRegex)); + + assertEquals(false, strInput.matches(strRegex)); } - + @Test public void givenRegexWithPipeEscaped_whenSplitStr_thenSplits() { String strInput = "foo|bar|hello|world"; String strRegex = "\\Q|\\E"; - EscapingChars e = new EscapingChars(); - - assertEquals(4, e.splitAndCountWords(strInput, strRegex)); + + assertEquals(4, strInput.split(strRegex).length); } - + @Test public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits() { String strInput = "foo|bar|hello|world"; String strRegex = "|"; - EscapingChars e = new EscapingChars(); - - assertEquals(4, e.splitAndCountWordsUsingQuoteMethod(strInput, strRegex)); + + assertEquals(4,strInput.split(Pattern.quote(strRegex)).length); } - + @Test public void givenRegexWithDollar_whenReplacing_thenNotReplace() { - String strInput = "I gave $50 to my brother.He bought candy for $35. Now he has $15 left."; + String strInput = "I gave $50 to my brother." + + "He bought candy for $35. Now he has $15 left."; String strRegex = "$"; - String strReplacement = "�"; - String output = "I gave �50 to my brother.He bought candy for �35. Now he has �15 left."; - EscapingChars e = new EscapingChars(); - - assertThat(output, not(equalTo(e.changeCurrencySymbol(strInput, strRegex, strReplacement)))); + String strReplacement = "£"; + String output = "I gave £50 to my brother." + + "He bought candy for £35. Now he has £15 left."; + Pattern p = Pattern.compile(strRegex); + Matcher m = p.matcher(strInput); + + assertThat(output, not(equalTo(m.replaceAll(strReplacement)))); } - + @Test public void givenRegexWithDollarEsc_whenReplacing_thenReplace() { - String strInput = "I gave $50 to my brother. He bought candy for $35. Now he has $15 left."; + String strInput = "I gave $50 to my brother." + + "He bought candy for $35. Now he has $15 left."; String strRegex = "\\$"; - String strReplacement = "�"; - String output = "I gave �50 to my brother. He bought candy for �35. Now he has �15 left."; - EscapingChars e = new EscapingChars(); - - assertEquals(output, e.changeCurrencySymbol(strInput, strRegex, strReplacement)); + String strReplacement = "£"; + String output = "I gave £50 to my brother." + + "He bought candy for £35. Now he has £15 left."; + Pattern p = Pattern.compile(strRegex); + Matcher m = p.matcher(strInput); + + assertEquals(output,m.replaceAll(strReplacement)); } } From 4eeaf5b7902238ffbf76dcb3fadf632740cb1af1 Mon Sep 17 00:00:00 2001 From: buddhini81 Date: Mon, 29 May 2017 18:30:53 +0530 Subject: [PATCH 65/78] BAEL-839 - Add the missing imports --- .../src/test/java/com/baeldung/regexp/EscapingCharsTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java index 49d349f69f..f8dbde4c4f 100644 --- a/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java +++ b/core-java/src/test/java/com/baeldung/regexp/EscapingCharsTest.java @@ -3,6 +3,8 @@ package com.baeldung.regexp; import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.junit.Test; From 8f3039b292b66140e91b0f44bb96764b0f6d6876 Mon Sep 17 00:00:00 2001 From: asif-anwar Date: Mon, 29 May 2017 20:58:25 +0400 Subject: [PATCH 66/78] spring-5-mvc (#1952) --- .../java/com/baeldung/web/FooController.java | 132 +++++++++--------- .../test/java/com/baeldung/test/LiveTest.java | 6 +- .../src/test/resources/baeldung-weekly.png | Bin 22275 -> 0 bytes 3 files changed, 69 insertions(+), 69 deletions(-) delete mode 100644 spring-5-mvc/src/test/resources/baeldung-weekly.png diff --git a/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java b/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java index d03cebb4fd..137864cddd 100644 --- a/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java +++ b/spring-5-mvc/src/main/java/com/baeldung/web/FooController.java @@ -1,66 +1,66 @@ -package com.baeldung.web; - -import java.util.List; - -import javax.validation.constraints.Max; -import javax.validation.constraints.Min; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.PageRequest; -import org.springframework.http.HttpStatus; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.server.ResponseStatusException; - -import com.baeldung.model.Foo; -import com.baeldung.persistence.FooRepository; - -@RestController("/foos") -public class FooController { - - @Autowired - private FooRepository repo; - - // API - read - - @GetMapping("/foos/{id}") - @Validated - public Foo findById(@PathVariable @Min(0) final long id) { - return repo.findById(id).orElse(null); - } - - @GetMapping - public List findAll() { - return repo.findAll(); - } - - @GetMapping(params = { "page", "size" }) - @Validated - public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) { - return repo.findAll(PageRequest.of(page, size)).getContent(); - } - - // API - write - - @PutMapping("/foos/{id}") - @ResponseStatus(HttpStatus.OK) - public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) { - return foo; - } - - @PostMapping - @ResponseStatus(HttpStatus.CREATED) - public void create( @RequestBody final Foo foo) { - if (null == foo || null == foo.getName()) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST," 'name' is required"); - } - repo.save(foo); - } -} +package com.baeldung.web; + +import java.util.List; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +import com.baeldung.model.Foo; +import com.baeldung.persistence.FooRepository; + +@RestController +public class FooController { + + @Autowired + private FooRepository repo; + + // API - read + + @GetMapping("/foos/{id}") + @Validated + public Foo findById(@PathVariable @Min(0) final long id) { + return repo.findById(id).orElse(null); + } + + @GetMapping("/foos") + public List findAll() { + return repo.findAll(); + } + + @GetMapping( value="/foos", params = { "page", "size" }) + @Validated + public List findPaginated(@RequestParam("page") @Min(0) final int page, @Max(100) @RequestParam("size") final int size) { + return repo.findAll(PageRequest.of(page, size)).getContent(); + } + + // API - write + + @PutMapping("/foos/{id}") + @ResponseStatus(HttpStatus.OK) + public Foo update(@PathVariable("id") final String id, @RequestBody final Foo foo) { + return foo; + } + + @PostMapping("/foos") + @ResponseStatus(HttpStatus.CREATED) + public void create( @RequestBody final Foo foo) { + if (null == foo || null == foo.getName()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST," 'name' is required"); + } + repo.save(foo); + } +} \ No newline at end of file diff --git a/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java b/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java index 637913541c..f6dd921b25 100644 --- a/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java +++ b/spring-5-mvc/src/test/java/com/baeldung/test/LiveTest.java @@ -16,14 +16,14 @@ public class LiveTest { @Test - public void givenUser_whenPostWithNullName_then400BadRequest() { - final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceWithNullName()).post(APP_ROOT + "/user"); + public void givenUser_whenResourceCreatedWithNullName_then400BadRequest() { + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceWithNullName()).post(APP_ROOT + "/foos"); assertEquals(400, response.getStatusCode()); } @Test public void givenUser_whenResourceCreated_then201Created() { - final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceString()).post(APP_ROOT + "/user"); + final Response response = givenAuth("user", "pass").contentType(MediaType.APPLICATION_JSON.toString()).body(resourceString()).post(APP_ROOT + "/foos"); assertEquals(201, response.getStatusCode()); } diff --git a/spring-5-mvc/src/test/resources/baeldung-weekly.png b/spring-5-mvc/src/test/resources/baeldung-weekly.png deleted file mode 100644 index 5a27d61dae718016a947083e01411ed1bc14f90e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22275 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 Date: Mon, 29 May 2017 22:21:03 +0200 Subject: [PATCH 67/78] BAEL-923 init class not managed by Spring with Spring Bean (#1906) * adam.zawada@gmail.com - Different Types of Bean Injection in Spring * adam.zawada@gmail.com - Different Types of Bean Injection in Spring switch to Java based configuration * BAEL-895 calculate the period/duration between two dates in Java 8 * clean old PR * BAEL-923 How to inject a value from properties to a class not managed by Spring? * clean PR * BAEL-923 init class not managed by Spring with Spring Bean * clean previous PR * added mockito spring boot for test dependency --- spring-core/pom.xml | 7 ++++ .../value/ClassNotManagedBySpring.java | 28 +++++++++++++ .../com/baeldung/value/InitializerBean.java | 21 ++++++++++ .../src/main/resources/application.properties | 2 + .../value/ClassNotManagedBySpringTest.java | 40 +++++++++++++++++++ 5 files changed, 98 insertions(+) create mode 100644 spring-core/src/main/java/com/baeldung/value/ClassNotManagedBySpring.java create mode 100644 spring-core/src/main/java/com/baeldung/value/InitializerBean.java create mode 100644 spring-core/src/main/resources/application.properties create mode 100644 spring-core/src/test/java/com/baeldung/value/ClassNotManagedBySpringTest.java diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 16984a387b..70002bf3c1 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -58,6 +58,12 @@ lombok ${lombok.version} + + org.springframework.boot + spring-boot-test + ${mockito.spring.boot.version} + test + @@ -112,6 +118,7 @@ 1.10.19 + 1.4.4.RELEASE 4.3.4.RELEASE 1 20.0 diff --git a/spring-core/src/main/java/com/baeldung/value/ClassNotManagedBySpring.java b/spring-core/src/main/java/com/baeldung/value/ClassNotManagedBySpring.java new file mode 100644 index 0000000000..0329769d3c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/value/ClassNotManagedBySpring.java @@ -0,0 +1,28 @@ +package com.baeldung.value; + +public class ClassNotManagedBySpring { + + private String customVariable; + private String anotherCustomVariable; + + public ClassNotManagedBySpring(String someInitialValue, String anotherManagedValue) { + this.customVariable = someInitialValue; + this.anotherCustomVariable = anotherManagedValue; + } + + public String getCustomVariable() { + return customVariable; + } + + public void setCustomVariable(String customVariable) { + this.customVariable = customVariable; + } + + public String getAnotherCustomVariable() { + return anotherCustomVariable; + } + + public void setAnotherCustomVariable(String anotherCustomVariable) { + this.anotherCustomVariable = anotherCustomVariable; + } +} diff --git a/spring-core/src/main/java/com/baeldung/value/InitializerBean.java b/spring-core/src/main/java/com/baeldung/value/InitializerBean.java new file mode 100644 index 0000000000..8c8634c767 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/value/InitializerBean.java @@ -0,0 +1,21 @@ +package com.baeldung.value; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class InitializerBean { + + private String someInitialValue; + private String anotherManagedValue; + + public InitializerBean(@Value("someInitialValue") String someInitialValue, @Value("anotherValue") String anotherManagedValue) { + this.someInitialValue = someInitialValue; + this.anotherManagedValue = anotherManagedValue; + } + + public ClassNotManagedBySpring initClass() { + return new ClassNotManagedBySpring(this.someInitialValue, this.anotherManagedValue); + } + +} diff --git a/spring-core/src/main/resources/application.properties b/spring-core/src/main/resources/application.properties new file mode 100644 index 0000000000..fdc6536237 --- /dev/null +++ b/spring-core/src/main/resources/application.properties @@ -0,0 +1,2 @@ +someInitialValue=This is only sample value +anotherValue=Another configured value \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/value/ClassNotManagedBySpringTest.java b/spring-core/src/test/java/com/baeldung/value/ClassNotManagedBySpringTest.java new file mode 100644 index 0000000000..d07d490642 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/value/ClassNotManagedBySpringTest.java @@ -0,0 +1,40 @@ +package com.baeldung.value; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.junit4.SpringRunner; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.Mockito.when; + +@RunWith(SpringRunner.class) +public class ClassNotManagedBySpringTest { + + @MockBean + private InitializerBean initializerBean; + + @Before + public void init() { + when(initializerBean.initClass()) + .thenReturn(new ClassNotManagedBySpring("This is only sample value", "Another configured value")); + } + + @Test + public void givenInitializerBean_whenInvokedInitClass_shouldInitialize() throws Exception { + + //given + ClassNotManagedBySpring classNotManagedBySpring = initializerBean.initClass(); + + //when + String initializedValue = classNotManagedBySpring.getCustomVariable(); + String anotherCustomVariable = classNotManagedBySpring.getAnotherCustomVariable(); + + //then + assertEquals("This is only sample value", initializedValue); + assertEquals("Another configured value", anotherCustomVariable); + + } + +} \ No newline at end of file From ec041202ae55e467e7074bce97f5dbea95b77d53 Mon Sep 17 00:00:00 2001 From: Pritam Banerjee Date: Tue, 30 May 2017 01:53:54 -0700 Subject: [PATCH 68/78] Fixed EJB --- .../baeldung/map/iteration/MapIteration.java | 57 ---------------- .../map/iteration/MapIterationTest.java | 68 ------------------- 2 files changed, 125 deletions(-) delete mode 100644 core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java delete mode 100644 core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java diff --git a/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java b/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java deleted file mode 100644 index 3b2a213aa0..0000000000 --- a/core-java/src/main/java/com/baeldung/map/iteration/MapIteration.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.baeldung.map.iteration; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; - -public class MapIteration { - - public ArrayList iterateUsingEntrySet(Map map) { - ArrayList mapKeyValueList = new ArrayList(); - for (Map.Entry entry : map.entrySet()) { - mapKeyValueList.add(entry.getKey() + ":" + entry.getValue()); - } - return mapKeyValueList; - } - - public ArrayList iterateUsingLambda(Map map) { - ArrayList mapKeyValueList = new ArrayList(); - map.forEach((k, v) -> mapKeyValueList.add(k + ":" + v)); - return mapKeyValueList; - } - - public ArrayList iterateUsingIteratorAndEntry(Map map) { - ArrayList mapKeyValueList = new ArrayList(); - Iterator> iterator = map.entrySet().iterator(); - - while (iterator.hasNext()) { - Map.Entry pair = iterator.next(); - mapKeyValueList.add(pair.getKey() + ":" + pair.getValue()); - } - - return mapKeyValueList; - } - - public ArrayList iterateUsingKeySetAndForeach(Map map) { - ArrayList mapKeyValueList = new ArrayList(); - for (String key : map.keySet()) { - mapKeyValueList.add(key + ":" + map.get(key)); - } - return mapKeyValueList; - } - - public ArrayList iterateUsingStreamAPI(Map map) { - ArrayList mapKeyValueList = new ArrayList(); - map.entrySet().stream().forEach(e -> mapKeyValueList.add(e.getKey() + ":" + e.getValue())); - return mapKeyValueList; - } - - public ArrayList iterateKeys(Map map) { - ArrayList mapKeyList = new ArrayList(); - for (String key : map.keySet()) { - mapKeyList.add(key); - } - return mapKeyList; - } - -} \ No newline at end of file diff --git a/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java b/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java deleted file mode 100644 index 5953c118fd..0000000000 --- a/core-java/src/test/java/com/baeldung/map/iteration/MapIterationTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.baeldung.map.iteration; - -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; - -public class MapIterationTest { - - public static Map testMap = new HashMap(); - public static String testString1 = "One:1"; - public static String testString2 = "Two:2"; - public static String testString3 = "Three:3"; - - @BeforeClass - public static void createTestData() { - testMap.put("One", 1); - testMap.put("Three", 3); - testMap.put("Two", 2); - } - - @Test - public void iterateUsingEntrySet_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateUsingEntrySet(testMap); - assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); - } - - @Test - public void iterateUsingLambda_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateUsingLambda(testMap); - assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); - } - - @Test - public void iterateUsingIteratorAndEntry_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateUsingIteratorAndEntry(testMap); - assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); - } - - @Test - public void iterateUsingKeySetAndForeach_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateUsingKeySetAndForeach(testMap); - assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); - } - - @Test - public void iterateUsingStreamAPI_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateUsingStreamAPI(testMap); - assertTrue((list.contains(testString1)) && (list.contains(testString2)) && (list.contains(testString3))); - } - - @Test - public void iterateKeys_test() { - MapIteration mapIteration = new MapIteration(); - ArrayList list = mapIteration.iterateKeys(testMap); - assertTrue((list.contains("One")) && (list.contains("Two")) && (list.contains("Three"))); - } - -} From 33653d82c253de53af18d82e04314e82420ef226 Mon Sep 17 00:00:00 2001 From: yetanotherallisonf Date: Tue, 30 May 2017 14:57:41 -0500 Subject: [PATCH 69/78] Update README.md (#1907) --- core-java/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-java/README.md b/core-java/README.md index 6dd43fe6d9..6c671a632d 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -105,6 +105,7 @@ - [Guide to UUID in JAVA] (http://www.baeldung.com/guide-to-uuid-in-java) - [Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java](http://www.baeldung.com/java-path) - [How to Add a Single Element to a Stream](http://www.baeldung.com/java-stream-append-prepend) +- [Iterating Over Enum Values in Java](http://www.baeldung.com/java-enum-iteration) - [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) - [Guide to the Java TransferQueue](http://www.baeldung.com/java-transfer-queue) - [Kotlin Java Interoperability](http://www.baeldung.com/kotlin-java-interoperability) @@ -112,3 +113,4 @@ - [Difference Between Wait and Sleep in Java](http://www.baeldung.com/java-wait-and-sleep) - [LongAdder and LongAccumulator in Java](http://www.baeldung.com/java-longadder-and-longaccumulator) - [Using Java MappedByteBuffer](http://www.baeldung.com/java-mapped-byte-buffer) + From fb3c480fa46ac93db4a9e17ac634186bcddfdfe3 Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Tue, 30 May 2017 14:58:07 -0500 Subject: [PATCH 70/78] BAEL-917: README (#1908) * BAEL-886: Updated README * BAEL-917 Testing with Google Truth Updated README --- testing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/README.md b/testing/README.md index fd94279fdf..e9208bfbf3 100644 --- a/testing/README.md +++ b/testing/README.md @@ -9,4 +9,4 @@ - [AssertJ for Guava](http://www.baeldung.com/assertJ-for-guava) - [Introduction to AssertJ](http://www.baeldung.com/introduction-to-assertj) - [Cucumber and Scenario Outline](http://www.baeldung.com/cucumber-scenario-outline) - +- [Testing with Google Truth](http://www.baeldung.com/google-truth) From 98e768c8638ca313fdf49f90457aa2d3e7954532 Mon Sep 17 00:00:00 2001 From: Danil Kornishev Date: Wed, 31 May 2017 13:39:35 -0400 Subject: [PATCH 71/78] Structurizr (#1927) * Structurizr * Structurizr --- structurizr/pom.xml | 54 ++++++ .../structurizr/StructurizrSimple.java | 155 ++++++++++++++++++ .../structurizr/spring/GenericComponent.java | 7 + .../structurizr/spring/PaymentController.java | 14 ++ .../structurizr/spring/PaymentRepository.java | 7 + 5 files changed, 237 insertions(+) create mode 100644 structurizr/pom.xml create mode 100644 structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java create mode 100644 structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java create mode 100644 structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java create mode 100644 structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java diff --git a/structurizr/pom.xml b/structurizr/pom.xml new file mode 100644 index 0000000000..1656bb10ec --- /dev/null +++ b/structurizr/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + com.baeldung + structurizr + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + 1.8 + 1.8 + + + + + com.structurizr + structurizr-core + 1.0.0-RC3 + + + com.structurizr + structurizr-spring + 1.0.0-RC3 + + + com.structurizr + structurizr-client + 0.6.0 + + + org.springframework + spring-context + 4.3.8.RELEASE + + + + + + + false + + central + bintray + http://jcenter.bintray.com + + + \ No newline at end of file diff --git a/structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java b/structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java new file mode 100644 index 0000000000..6eb0c7de73 --- /dev/null +++ b/structurizr/src/main/java/com/baeldung/structurizr/StructurizrSimple.java @@ -0,0 +1,155 @@ +package com.baeldung.structurizr; + +import java.io.File; +import java.io.StringWriter; + +import com.structurizr.Workspace; +import com.structurizr.api.StructurizrClient; +import com.structurizr.api.StructurizrClientException; +import com.structurizr.componentfinder.ComponentFinder; +import com.structurizr.componentfinder.ReferencedTypesSupportingTypesStrategy; +import com.structurizr.componentfinder.SourceCodeComponentFinderStrategy; +import com.structurizr.componentfinder.SpringComponentFinderStrategy; +import com.structurizr.io.WorkspaceWriterException; +import com.structurizr.io.plantuml.PlantUMLWriter; +import com.structurizr.model.Component; +import com.structurizr.model.Container; +import com.structurizr.model.Model; +import com.structurizr.model.Person; +import com.structurizr.model.SoftwareSystem; +import com.structurizr.model.Tags; +import com.structurizr.view.ComponentView; +import com.structurizr.view.ContainerView; +import com.structurizr.view.Routing; +import com.structurizr.view.Shape; +import com.structurizr.view.Styles; +import com.structurizr.view.SystemContextView; +import com.structurizr.view.View; +import com.structurizr.view.ViewSet; + +public class StructurizrSimple { + + public static final String PAYMENT_TERMINAL = "Payment Terminal"; + public static final String FRAUD_DETECTOR = "Fraud Detector"; + public static final String SOFTWARE_SYSTEM_VIEW = "SoftwareSystemView"; + public static final String CONTAINER_VIEW = "ContainerView"; + public static final String COMPONENT_VIEW = "ComponentView"; + public static final String JVM2_COMPONENT_VIEW = "JVM2ComponentView"; + + public static void main(String[] args) throws Exception { + Workspace workspace = getSoftwareSystem(); + + addContainers(workspace); + addComponents(workspace); + addSpringComponents(workspace); + exportToPlantUml(workspace.getViews().getViewWithKey(SOFTWARE_SYSTEM_VIEW)); + exportToPlantUml(workspace.getViews().getViewWithKey(CONTAINER_VIEW)); + exportToPlantUml(workspace.getViews().getViewWithKey(COMPONENT_VIEW)); + + exportToPlantUml(workspace.getViews().getViewWithKey(JVM2_COMPONENT_VIEW)); + + addStyles(workspace.getViews()); + //uploadToExternal(workspace); + } + + private static void addSpringComponents(Workspace workspace) throws Exception { + Container jvm2 = workspace.getModel().getSoftwareSystemWithName(PAYMENT_TERMINAL).getContainerWithName("JVM-2"); + findComponents(jvm2); + + ComponentView view = workspace.getViews().createComponentView(jvm2, JVM2_COMPONENT_VIEW, "JVM2ComponentView"); + view.addAllComponents(); + + } + + private static void findComponents(Container jvm) throws Exception { + ComponentFinder componentFinder = new ComponentFinder( + jvm, + "com.baeldung.structurizr", + new SpringComponentFinderStrategy( + new ReferencedTypesSupportingTypesStrategy() + ), + new SourceCodeComponentFinderStrategy(new File("."), 150)); + + componentFinder.findComponents(); + } + + private static void addComponents(Workspace workspace) { + Model model = workspace.getModel(); + + SoftwareSystem paymentTerminal = model.getSoftwareSystemWithName(PAYMENT_TERMINAL); + Container jvm1 = paymentTerminal.getContainerWithName("JVM-1"); + + Component jaxrs = jvm1.addComponent("jaxrs-jersey", "restful webservice implementation", "rest"); + Component gemfire = jvm1.addComponent("gemfire", "Clustered Cache Gemfire", "cache"); + Component hibernate = jvm1.addComponent("hibernate", "Data Access Layer", "jpa"); + + jaxrs.uses(gemfire, ""); + gemfire.uses(hibernate, ""); + + ComponentView componentView = workspace.getViews().createComponentView(jvm1, COMPONENT_VIEW, "JVM Components"); + componentView.addAllComponents(); + } + + private static void addContainers(Workspace workspace) { + Model model = workspace.getModel(); + + SoftwareSystem paymentTerminal = model.getSoftwareSystemWithName(PAYMENT_TERMINAL); + Container f5 = paymentTerminal.addContainer("Payment Load Balancer", "Payment Load Balancer", "F5"); + Container jvm1 = paymentTerminal.addContainer("JVM-1", "JVM-1", "Java Virtual Machine"); + Container jvm2 = paymentTerminal.addContainer("JVM-2", "JVM-2", "Java Virtual Machine"); + Container jvm3 = paymentTerminal.addContainer("JVM-3", "JVM-3", "Java Virtual Machine"); + Container oracle = paymentTerminal.addContainer("oracleDB", "Oracle Database", "RDBMS"); + + f5.uses(jvm1, "route"); + f5.uses(jvm2, "route"); + f5.uses(jvm3, "route"); + + jvm1.uses(oracle, "storage"); + jvm2.uses(oracle, "storage"); + jvm3.uses(oracle, "storage"); + + ContainerView view = workspace.getViews().createContainerView(paymentTerminal, CONTAINER_VIEW, "Container View"); + view.addAllContainers(); + } + + private static void uploadToExternal(Workspace workspace) throws StructurizrClientException { + StructurizrClient client = new StructurizrClient("e94bc0c9-76ef-41b0-8de7-82afc1010d04", "78d555dd-2a31-487c-952c-50508f1da495"); + client.putWorkspace(32961L, workspace); + } + + private static void exportToPlantUml(View view) throws WorkspaceWriterException { + StringWriter stringWriter = new StringWriter(); + PlantUMLWriter plantUMLWriter = new PlantUMLWriter(); + plantUMLWriter.write(view, stringWriter); + System.out.println(stringWriter.toString()); + } + + private static Workspace getSoftwareSystem() { + Workspace workspace = new Workspace("Payment Gateway", "Payment Gateway"); + Model model = workspace.getModel(); + + Person user = model.addPerson("Merchant", "Merchant"); + SoftwareSystem paymentTerminal = model.addSoftwareSystem(PAYMENT_TERMINAL, "Payment Terminal"); + user.uses(paymentTerminal, "Makes payment"); + SoftwareSystem fraudDetector = model.addSoftwareSystem(FRAUD_DETECTOR, "Fraud Detector"); + paymentTerminal.uses(fraudDetector, "Obtains fraud score"); + + ViewSet viewSet = workspace.getViews(); + + SystemContextView contextView = viewSet.createSystemContextView(workspace.getModel().getSoftwareSystemWithName(PAYMENT_TERMINAL), SOFTWARE_SYSTEM_VIEW, "Payment Gateway Diagram"); + contextView.addAllElements(); + + return workspace; + } + + private static void addStyles(ViewSet viewSet) { + Styles styles = viewSet.getConfiguration().getStyles(); + styles.addElementStyle(Tags.ELEMENT).color("#000000"); + styles.addElementStyle(Tags.PERSON).background("#ffbf00").shape(Shape.Person); + styles.addElementStyle(Tags.CONTAINER).background("#facc2E"); + styles.addRelationshipStyle(Tags.RELATIONSHIP).routing(Routing.Orthogonal); + + styles.addRelationshipStyle(Tags.ASYNCHRONOUS).dashed(true); + styles.addRelationshipStyle(Tags.SYNCHRONOUS).dashed(false); + } +} diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java b/structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java new file mode 100644 index 0000000000..56f2d52ce0 --- /dev/null +++ b/structurizr/src/main/java/com/baeldung/structurizr/spring/GenericComponent.java @@ -0,0 +1,7 @@ +package com.baeldung.structurizr.spring; + +import org.springframework.stereotype.Component; + +@Component +public class GenericComponent { +} diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java b/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java new file mode 100644 index 0000000000..89a58b9885 --- /dev/null +++ b/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentController.java @@ -0,0 +1,14 @@ +package com.baeldung.structurizr.spring; + +import org.springframework.stereotype.Controller; + +import javax.annotation.Resource; + +@Controller +public class PaymentController { + @Resource + private PaymentRepository repository; + + @Resource + private GenericComponent component; +} diff --git a/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java b/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java new file mode 100644 index 0000000000..78b00495b6 --- /dev/null +++ b/structurizr/src/main/java/com/baeldung/structurizr/spring/PaymentRepository.java @@ -0,0 +1,7 @@ +package com.baeldung.structurizr.spring; + +import org.springframework.stereotype.Repository; + +@Repository +public class PaymentRepository { +} From 0b108e387daa6ece90c921a5f2a20e471e645403 Mon Sep 17 00:00:00 2001 From: Tomasz Lelek Date: Wed, 31 May 2017 20:21:01 +0200 Subject: [PATCH 72/78] BAEL-949 java9 optional test (#1960) --- .../com/baeldung/java9/Java9OptionalTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java diff --git a/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java new file mode 100644 index 0000000000..cd0efb028d --- /dev/null +++ b/core-java-9/src/test/java/com/baeldung/java9/Java9OptionalTest.java @@ -0,0 +1,85 @@ +package com.baeldung.java9; + +public class Java9OptionalTest { + @Test + public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() { + //given + Optional value = Optional.of("a"); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).hasSameElementsAs(List.of("A")); + } + + @Test + public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() { + //given + Optional value = Optional.empty(); + + //when + List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList()); + + //then + assertThat(collect).isEmpty(); + } + + @Test + public void givenOptional_whenPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.of("properValue"); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(1); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(0); + } + + @Test + public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() { + //given + Optional value = Optional.empty(); + AtomicInteger successCounter = new AtomicInteger(0); + AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0); + + //when + value.ifPresentOrElse((v) -> successCounter.incrementAndGet(), onEmptyOptionalCounter::incrementAndGet); + + //then + assertThat(successCounter.get()).isEqualTo(0); + assertThat(onEmptyOptionalCounter.get()).isEqualTo(1); + } + + @Test + public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() { + //given + String expected = "properValue"; + Optional value = Optional.of(expected); + Optional defaultValue = Optional.of("default"); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(expected); + } + + @Test + public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() { + //given + String defaultString = "default"; + Optional value = Optional.empty(); + Optional defaultValue = Optional.of(defaultString); + + //when + Optional result = value.or(() -> defaultValue); + + //then + assertThat(result.get()).isEqualTo(defaultString); + } +} \ No newline at end of file From ea302a5f335334c69c7467c65525913ec8a14985 Mon Sep 17 00:00:00 2001 From: tschiman Date: Wed, 31 May 2017 16:31:02 -0600 Subject: [PATCH 73/78] BAEL-755 changing the name of the POKO to a DTO and removing the use of @Autowired in the constructor as it is not needed. --- .../com/baeldung/springbootkotlin/HelloController.kt | 9 ++++----- .../kotlin/com/baeldung/springbootkotlin/HelloDto.kt | 3 +++ .../kotlin/com/baeldung/springbootkotlin/HelloPoko.kt | 3 --- .../springbootkotlin/KotlinDemoApplicationTests.kt | 6 +++--- 4 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloDto.kt delete mode 100644 spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt index 622271211b..02b57bac5f 100644 --- a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloController.kt @@ -1,11 +1,10 @@ package com.baeldung.springbootkotlin -import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController @RestController -class HelloController @Autowired constructor(val helloService: HelloService) { +class HelloController constructor(val helloService: HelloService) { @GetMapping("/hello") fun helloKotlin(): String { @@ -17,8 +16,8 @@ class HelloController @Autowired constructor(val helloService: HelloService) { return helloService.getHello() } - @GetMapping("/hello-poko") - fun helloPoko(): HelloPoko { - return HelloPoko("Hello from the poko") + @GetMapping("/hello-dto") + fun helloDto(): HelloDto { + return HelloDto("Hello from the dto") } } \ No newline at end of file diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloDto.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloDto.kt new file mode 100644 index 0000000000..3f0139b5a9 --- /dev/null +++ b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloDto.kt @@ -0,0 +1,3 @@ +package com.baeldung.springbootkotlin + +data class HelloDto constructor(val greeting: String) diff --git a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt b/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt deleted file mode 100644 index 7e9c50e073..0000000000 --- a/spring-boot-kotlin/src/main/kotlin/com/baeldung/springbootkotlin/HelloPoko.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.baeldung.springbootkotlin - -data class HelloPoko constructor(val greeting: String) diff --git a/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt index c6d9146edd..08c9ad0889 100644 --- a/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt +++ b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt @@ -1,6 +1,6 @@ package com.example.kotlindemo -import com.baeldung.springbootkotlin.HelloPoko +import com.baeldung.springbootkotlin.HelloDto import com.baeldung.springbootkotlin.KotlinDemoApplication import org.junit.Assert import org.junit.Test @@ -42,11 +42,11 @@ class KotlinDemoApplicationTests { @Test fun testHelloPoko() { - var result = testRestTemplate?.getForEntity("/hello-poko", HelloPoko::class.java) + var result = testRestTemplate?.getForEntity("/hello-dto", HelloDto::class.java) Assert.assertNotNull(result) Assert.assertEquals(result?.statusCode, HttpStatus.OK) - Assert.assertEquals(result?.body, HelloPoko("Hello from the poko")) + Assert.assertEquals(result?.body, HelloDto("Hello from the dto")) } } From 50cf9a5070763982556515e64122b1f907ecad6a Mon Sep 17 00:00:00 2001 From: tschiman Date: Wed, 31 May 2017 16:33:27 -0600 Subject: [PATCH 74/78] BAEL-755 changing the name of the POKO to a DTO and removing the use of @Autowired in the constructor as it is not needed. --- .../test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt index 08c9ad0889..15ddc916e2 100644 --- a/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt +++ b/spring-boot-kotlin/src/test/kotlin/springbootkotlin/KotlinDemoApplicationTests.kt @@ -41,7 +41,7 @@ class KotlinDemoApplicationTests { } @Test - fun testHelloPoko() { + fun testHelloDto() { var result = testRestTemplate?.getForEntity("/hello-dto", HelloDto::class.java) Assert.assertNotNull(result) From 8edc3bfbaae23667f2383589f0f5f383cdf4b3d6 Mon Sep 17 00:00:00 2001 From: iaforek Date: Thu, 1 Jun 2017 00:24:21 +0100 Subject: [PATCH 75/78] BAEL-821 - How to round a number to n decimal places in Java (#1953) * Code for Dependency Injection Article. * Added Java based configuration. Downloaded formatter.xml and reformatted all changed files. Manually changed tab into 4 spaces in XML configuration files. * BAEL-434 - Spring Roo project files generated by Spring Roo. No formatting applied. Added POM, java and resources folders. * Moved project from roo to spring-roo folder. * BAEL-838 Initial code showing how to remove last char - helper class and tests. * BAEL-838 Corrected Helper class and associated empty string test case. Added StringUtils.substing tests. * BAEL-838 Refromatted code using formatter.xml. Added Assert.assertEquals import. Renamed test to follow convention. Reordered tests. * BAEL-838 - Added regex method and updated tests. * BAEL-838 Added new line examples. * BAEL-838 Renamed RemoveLastChar class to StringHelper and added Java8 examples. Refactord code. * BAEL-838 Changed method names * BAEL-838 Tiny change to keep code consistant. Return null or empty. * BAEL-838 Removed unresolved conflict. * BAEL-821 New class that shows different rounding techniques. Updated POM. * BAEL-821 - Added unit test for different round methods. * BAEL-821 Changed test method name to follow the convention --- core-java/pom.xml | 7 ++++ .../main/java/com/baeldung/maths/Round.java | 38 +++++++++++++++++++ .../java/com/baeldung/maths/RoundTest.java | 29 ++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/maths/Round.java create mode 100644 core-java/src/test/java/com/baeldung/maths/RoundTest.java diff --git a/core-java/pom.xml b/core-java/pom.xml index bcec20b1e1..5c9bf06a57 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -45,6 +45,12 @@ commons-math3 ${commons-math3.version} + + + org.decimal4j + decimal4j + ${decimal4j.version} + org.bouncycastle @@ -369,6 +375,7 @@ 1.55 1.10 3.6.1 + 1.0.3 2.5 4.1 4.01 diff --git a/core-java/src/main/java/com/baeldung/maths/Round.java b/core-java/src/main/java/com/baeldung/maths/Round.java new file mode 100644 index 0000000000..3b30ab2c7a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/maths/Round.java @@ -0,0 +1,38 @@ +package com.baeldung.maths; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.DecimalFormat; + +import org.apache.commons.math3.util.Precision; +import org.decimal4j.util.DoubleRounder; + +public class Round { + private static final double PI = 3.1415d; + + public static void main (String args[]) { + System.out.println("PI: " + PI); + System.out.printf("Value with 3 digits after decimal point %.3f %n", PI); + // OUTPUTS: Value with 3 digits after decimal point 3.142 + DecimalFormat df = new DecimalFormat("###.###"); + System.out.println(df.format(PI)); + System.out.println(round(PI, 3)); + System.out.println(roundOptional(PI, 3)); + System.out.println(Precision.round(PI, 3)); + System.out.println(DoubleRounder.round(PI, 3)); + } + + public static double round(double value, int places) { + if (places < 0) throw new IllegalArgumentException(); + + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + + public static double roundOptional(double value, int places) { + double scale = Math.pow(10, places); + double rounded = Math.round(value * scale) / scale; + return rounded; + } +} diff --git a/core-java/src/test/java/com/baeldung/maths/RoundTest.java b/core-java/src/test/java/com/baeldung/maths/RoundTest.java new file mode 100644 index 0000000000..2621cfb65c --- /dev/null +++ b/core-java/src/test/java/com/baeldung/maths/RoundTest.java @@ -0,0 +1,29 @@ +package com.baeldung.maths; + +import org.apache.commons.math3.util.Precision; +import org.decimal4j.util.DoubleRounder; +import org.junit.Assert; +import org.junit.Test; + +public class RoundTest { + private double value = 2.03456d; + private int places = 2; + private double delta = 0.0d; + private double expected = 2.03d; + + @Test + public void givenDecimalNumber_whenRoundToNDecimalPlaces_thenGetExpectedResult() { + Assert.assertEquals(expected, Round.round(value, places), delta); + Assert.assertEquals(expected, Round.roundOptional(value, places), delta); + Assert.assertEquals(expected, Precision.round(value, places), delta); + Assert.assertEquals(expected, DoubleRounder.round(value, places), delta); + + places = 3; + expected = 2.035d; + + Assert.assertEquals(expected, Round.round(value, places), delta); + Assert.assertEquals(expected, Round.roundOptional(value, places), delta); + Assert.assertEquals(expected, Precision.round(value, places), delta); + Assert.assertEquals(expected, DoubleRounder.round(value, places), delta); + } +} From 8bb276cabd1e346c7cf496fccfba5132da8185ba Mon Sep 17 00:00:00 2001 From: Doha2012 Date: Thu, 1 Jun 2017 15:10:59 +0200 Subject: [PATCH 76/78] sso using oauth (#1955) * minor logging fix * spring security sso * use basic auth * use form login * cleanup * cleanup * final cleanup --- spring-security-sso/pom.xml | 27 ++++++++++++ .../spring-security-sso-auth-server/pom.xml | 28 ++++++++++++ .../org/baeldung/config/AuthServerConfig.java | 41 +++++++++++++++++ .../AuthorizationServerApplication.java | 16 +++++++ .../org/baeldung/config/SecurityConfig.java | 38 ++++++++++++++++ .../org/baeldung/config/UserController.java | 16 +++++++ .../src/main/resources/application.properties | 4 ++ .../test/AuthServerIntegrationTest.java | 18 ++++++++ .../spring-security-sso-ui/pom.xml | 44 +++++++++++++++++++ .../org/baeldung/config/UiApplication.java | 33 ++++++++++++++ .../java/org/baeldung/config/UiWebConfig.java | 41 +++++++++++++++++ .../src/main/resources/application.yml | 20 +++++++++ .../src/main/resources/templates/index.html | 18 ++++++++ .../main/resources/templates/securedPage.html | 18 ++++++++ .../org/baeldung/test/UiIntegrationTest.java | 18 ++++++++ 15 files changed, 380 insertions(+) create mode 100644 spring-security-sso/pom.xml create mode 100644 spring-security-sso/spring-security-sso-auth-server/pom.xml create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/UserController.java create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties create mode 100644 spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java create mode 100644 spring-security-sso/spring-security-sso-ui/pom.xml create mode 100644 spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java create mode 100644 spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiWebConfig.java create mode 100644 spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml create mode 100644 spring-security-sso/spring-security-sso-ui/src/main/resources/templates/index.html create mode 100644 spring-security-sso/spring-security-sso-ui/src/main/resources/templates/securedPage.html create mode 100644 spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml new file mode 100644 index 0000000000..36c0c13052 --- /dev/null +++ b/spring-security-sso/pom.xml @@ -0,0 +1,27 @@ + + 4.0.0 + org.baeldung + spring-security-sso + 1.0.0-SNAPSHOT + + spring-security-sso + pom + + + parent-boot-5 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-5 + + + + spring-security-sso-auth-server + spring-security-sso-ui + + + + 3.0.1 + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/pom.xml b/spring-security-sso/spring-security-sso-auth-server/pom.xml new file mode 100644 index 0000000000..c7b23249f9 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/pom.xml @@ -0,0 +1,28 @@ + + 4.0.0 + spring-security-sso-auth-server + + spring-security-sso-auth-server + war + + + org.baeldung + spring-security-sso + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.security.oauth + spring-security-oauth2 + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java new file mode 100644 index 0000000000..20cde21073 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthServerConfig.java @@ -0,0 +1,41 @@ +package org.baeldung.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +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; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; + +@Configuration +@EnableAuthorizationServer +public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.tokenKeyAccess("permitAll()") + .checkTokenAccess("isAuthenticated()"); + } + + @Override + public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory() + .withClient("SampleClientId") + .secret("secret") + .authorizedGrantTypes("authorization_code") + .scopes("user_info") + .autoApprove(true) + // .accessTokenValiditySeconds(3600) + ; // 1 hour + } + + @Override + public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + +} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java new file mode 100644 index 0000000000..5b0b39b444 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/AuthorizationServerApplication.java @@ -0,0 +1,16 @@ +package org.baeldung.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; + +@SpringBootApplication +@EnableResourceServer +public class AuthorizationServerApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(AuthorizationServerApplication.class, args); + } + +} \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java new file mode 100644 index 0000000000..9de203b7c3 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/SecurityConfig.java @@ -0,0 +1,38 @@ +package org.baeldung.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.requestMatchers() + .antMatchers("/login", "/oauth/authorize") + .and() + .authorizeRequests() + .anyRequest() + .authenticated() + .and() + .formLogin() + .permitAll(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.parentAuthenticationManager(authenticationManager) + .inMemoryAuthentication() + .withUser("john") + .password("123") + .roles("USER"); + } + +} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/UserController.java b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/UserController.java new file mode 100644 index 0000000000..28128f9d97 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/java/org/baeldung/config/UserController.java @@ -0,0 +1,16 @@ +package org.baeldung.config; + +import java.security.Principal; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class UserController { + + @RequestMapping("/user/me") + public Principal user(Principal principal) { + System.out.println(principal); + return principal; + } +} diff --git a/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties new file mode 100644 index 0000000000..32a0993b04 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/main/resources/application.properties @@ -0,0 +1,4 @@ +server.port=8081 +server.context-path=/auth +security.basic.enabled=false +#logging.level.org.springframework=DEBUG \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java b/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java new file mode 100644 index 0000000000..9e2d6feca1 --- /dev/null +++ b/spring-security-sso/spring-security-sso-auth-server/src/test/java/org/baeldung/test/AuthServerIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung.test; + +import org.baeldung.config.AuthorizationServerApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = AuthorizationServerApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +public class AuthServerIntegrationTest { + + @Test + public void whenLoadApplication_thenSuccess() { + + } +} diff --git a/spring-security-sso/spring-security-sso-ui/pom.xml b/spring-security-sso/spring-security-sso-ui/pom.xml new file mode 100644 index 0000000000..fe1cd56a76 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + spring-security-sso-ui + + spring-security-sso-ui + war + + + org.baeldung + spring-security-sso + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security.oauth + spring-security-oauth2 + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity4 + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java new file mode 100644 index 0000000000..5ef699d264 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiApplication.java @@ -0,0 +1,33 @@ +package org.baeldung.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.web.context.request.RequestContextListener; + +@EnableOAuth2Sso +@SpringBootApplication +public class UiApplication extends WebSecurityConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http.antMatcher("/**") + .authorizeRequests() + .antMatchers("/", "/login**") + .permitAll() + .anyRequest() + .authenticated(); + } + + @Bean + public RequestContextListener requestContextListener() { + return new RequestContextListener(); + } + + public static void main(String[] args) { + SpringApplication.run(UiApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiWebConfig.java b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiWebConfig.java new file mode 100644 index 0000000000..24d6c9b5d8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/java/org/baeldung/config/UiWebConfig.java @@ -0,0 +1,41 @@ +package org.baeldung.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +@EnableWebMvc +public class UiWebConfig extends WebMvcConfigurerAdapter { + + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + super.addViewControllers(registry); + registry.addViewController("/") + .setViewName("forward:/index"); + registry.addViewController("/index"); + registry.addViewController("/securedPage"); + } + + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**") + .addResourceLocations("/resources/"); + } + +} \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml new file mode 100644 index 0000000000..bb4bd92033 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/application.yml @@ -0,0 +1,20 @@ +server: + port: 8082 + context-path: /ui + session: + cookie: + name: UISESSION +security: + basic: + enabled: false + oauth2: + client: + clientId: SampleClientId + clientSecret: secret + accessTokenUri: http://localhost:8081/auth/oauth/token + userAuthorizationUri: http://localhost:8081/auth/oauth/authorize + resource: + userInfoUri: http://localhost:8081/auth/user/me +spring: + thymeleaf: + cache: false \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/index.html b/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/index.html new file mode 100644 index 0000000000..12948e0738 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/index.html @@ -0,0 +1,18 @@ + + + + +Spring Security SSO + + + + +
+
+

Spring Security SSO

+ Login +
+
+ + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/securedPage.html b/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/securedPage.html new file mode 100644 index 0000000000..81ed51b2d6 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/main/resources/templates/securedPage.html @@ -0,0 +1,18 @@ + + + + +Spring Security SSO + + + + +
+
+

Secured Page

+ Welcome, Name +
+
+ + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java b/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java new file mode 100644 index 0000000000..6386eac0b8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui/src/test/java/org/baeldung/test/UiIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung.test; + +import org.baeldung.config.UiApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +public class UiIntegrationTest { + + @Test + public void whenLoadApplication_thenSuccess() { + + } +} From 3cf4dc5a78444d816ffd53b9d85d64b0ec43732b Mon Sep 17 00:00:00 2001 From: Doha2012 Date: Thu, 1 Jun 2017 20:14:41 +0200 Subject: [PATCH 77/78] second client fo sso (#1971) * minor logging fix * spring security sso * use basic auth * use form login * cleanup * cleanup * final cleanup * second client app for sso --- spring-security-sso/pom.xml | 1 + .../spring-security-sso-ui-2/pom.xml | 44 +++++++++++++++++++ .../org/baeldung/config/UiApplication.java | 33 ++++++++++++++ .../java/org/baeldung/config/UiWebConfig.java | 41 +++++++++++++++++ .../src/main/resources/application.yml | 20 +++++++++ .../src/main/resources/templates/index.html | 18 ++++++++ .../main/resources/templates/securedPage.html | 20 +++++++++ .../org/baeldung/test/UiIntegrationTest.java | 18 ++++++++ 8 files changed, 195 insertions(+) create mode 100644 spring-security-sso/spring-security-sso-ui-2/pom.xml create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiWebConfig.java create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/index.html create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/securedPage.html create mode 100644 spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java diff --git a/spring-security-sso/pom.xml b/spring-security-sso/pom.xml index 36c0c13052..7438cede16 100644 --- a/spring-security-sso/pom.xml +++ b/spring-security-sso/pom.xml @@ -18,6 +18,7 @@ spring-security-sso-auth-server spring-security-sso-ui + spring-security-sso-ui-2 diff --git a/spring-security-sso/spring-security-sso-ui-2/pom.xml b/spring-security-sso/spring-security-sso-ui-2/pom.xml new file mode 100644 index 0000000000..6a8dc5385b --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + spring-security-sso-ui-2 + + spring-security-sso-ui-2 + war + + + org.baeldung + spring-security-sso + 1.0.0-SNAPSHOT + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.security.oauth + spring-security-oauth2 + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity4 + + + + + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java new file mode 100644 index 0000000000..5ef699d264 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiApplication.java @@ -0,0 +1,33 @@ +package org.baeldung.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.web.context.request.RequestContextListener; + +@EnableOAuth2Sso +@SpringBootApplication +public class UiApplication extends WebSecurityConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http.antMatcher("/**") + .authorizeRequests() + .antMatchers("/", "/login**") + .permitAll() + .anyRequest() + .authenticated(); + } + + @Bean + public RequestContextListener requestContextListener() { + return new RequestContextListener(); + } + + public static void main(String[] args) { + SpringApplication.run(UiApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiWebConfig.java b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiWebConfig.java new file mode 100644 index 0000000000..24d6c9b5d8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/java/org/baeldung/config/UiWebConfig.java @@ -0,0 +1,41 @@ +package org.baeldung.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +@EnableWebMvc +public class UiWebConfig extends WebMvcConfigurerAdapter { + + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Override + public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + super.addViewControllers(registry); + registry.addViewController("/") + .setViewName("forward:/index"); + registry.addViewController("/index"); + registry.addViewController("/securedPage"); + } + + @Override + public void addResourceHandlers(final ResourceHandlerRegistry registry) { + registry.addResourceHandler("/resources/**") + .addResourceLocations("/resources/"); + } + +} \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml new file mode 100644 index 0000000000..6b0d3db5ad --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/application.yml @@ -0,0 +1,20 @@ +server: + port: 8083 + context-path: /ui2 + session: + cookie: + name: UI2SESSION +security: + basic: + enabled: false + oauth2: + client: + clientId: SampleClientId + clientSecret: secret + accessTokenUri: http://localhost:8081/auth/oauth/token + userAuthorizationUri: http://localhost:8081/auth/oauth/authorize + resource: + userInfoUri: http://localhost:8081/auth/user/me +spring: + thymeleaf: + cache: false \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/index.html b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/index.html new file mode 100644 index 0000000000..38fa8bda50 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/index.html @@ -0,0 +1,18 @@ + + + + +Spring Security SSO Client 2 + + + + +
+
+

Spring Security SSO Client 2

+ Login +
+
+ + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/securedPage.html b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/securedPage.html new file mode 100644 index 0000000000..7807298828 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/main/resources/templates/securedPage.html @@ -0,0 +1,20 @@ + + + + +Spring Security SSO Client 2 + + + + +
+
+

Secured Page

+ Welcome, Name +
+ Your authorities are authorities +
+
+ + \ No newline at end of file diff --git a/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java b/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java new file mode 100644 index 0000000000..6386eac0b8 --- /dev/null +++ b/spring-security-sso/spring-security-sso-ui-2/src/test/java/org/baeldung/test/UiIntegrationTest.java @@ -0,0 +1,18 @@ +package org.baeldung.test; + +import org.baeldung.config.UiApplication; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = UiApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) +public class UiIntegrationTest { + + @Test + public void whenLoadApplication_thenSuccess() { + + } +} From d3597a84c7a5e8fe800daf29c0146ce5393941c8 Mon Sep 17 00:00:00 2001 From: lor6 Date: Thu, 1 Jun 2017 23:33:52 +0300 Subject: [PATCH 78/78] Bael 911 (#1969) * log4j2 examples * log4j2 examples --- guest/log4j2-example/.gitignore | 4 + guest/log4j2-example/java.log | 3 + guest/log4j2-example/logs/app.log | 25 ++++++ guest/log4j2-example/pom.xml | 56 +++++++++++++ .../main/java/com/stackify/models/User.java | 43 ++++++++++ .../java/com/stackify/services/MyService.java | 14 ++++ .../src/main/resources/log4j2.xml | 62 ++++++++++++++ .../com/stackify/services/MyServiceTest.java | 81 +++++++++++++++++++ 8 files changed, 288 insertions(+) create mode 100644 guest/log4j2-example/.gitignore create mode 100644 guest/log4j2-example/java.log create mode 100644 guest/log4j2-example/logs/app.log create mode 100644 guest/log4j2-example/pom.xml create mode 100644 guest/log4j2-example/src/main/java/com/stackify/models/User.java create mode 100644 guest/log4j2-example/src/main/java/com/stackify/services/MyService.java create mode 100644 guest/log4j2-example/src/main/resources/log4j2.xml create mode 100644 guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java diff --git a/guest/log4j2-example/.gitignore b/guest/log4j2-example/.gitignore new file mode 100644 index 0000000000..60be5b80aa --- /dev/null +++ b/guest/log4j2-example/.gitignore @@ -0,0 +1,4 @@ +/target/ +.settings/ +.classpath +.project diff --git a/guest/log4j2-example/java.log b/guest/log4j2-example/java.log new file mode 100644 index 0000000000..21e964d9ce --- /dev/null +++ b/guest/log4j2-example/java.log @@ -0,0 +1,3 @@ +14:00:35.258 INFO Programmatic Logger Message +14:03:51.178 INFO Programmatic Logger Message +14:04:11.753 INFO Programmatic Logger Message diff --git a/guest/log4j2-example/logs/app.log b/guest/log4j2-example/logs/app.log new file mode 100644 index 0000000000..022f6fcea9 --- /dev/null +++ b/guest/log4j2-example/logs/app.log @@ -0,0 +1,25 @@ +[ +{ + "timeMillis" : 1496315051753, + "thread" : "main", + "level" : "INFO", + "loggerName" : "RollingFileLogger", + "message" : "Json Message 1", + "endOfBatch" : false, + "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", + "threadId" : 1, + "threadPriority" : 5 +} +, { + "timeMillis" : 1496315051862, + "thread" : "main", + "level" : "INFO", + "loggerName" : "RollingFileLogger", + "message" : "Json Messag 2", + "endOfBatch" : false, + "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger", + "threadId" : 1, + "threadPriority" : 5 +} + +] diff --git a/guest/log4j2-example/pom.xml b/guest/log4j2-example/pom.xml new file mode 100644 index 0000000000..197f3df2b9 --- /dev/null +++ b/guest/log4j2-example/pom.xml @@ -0,0 +1,56 @@ + + 4.0.0 + log4j2-example + log4j2-example + 0.0.1-SNAPSHOT + + + + + org.apache.logging.log4j + log4j-core + ${log4j-core.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + junit + junit + 4.12 + + + + + + + src/main/resources/ + + **/*.java + + + + + + maven-compiler-plugin + 3.5 + + 1.8 + 1.8 + + + + + + + 2.8.8.1 + 2.8.2 + + + \ No newline at end of file diff --git a/guest/log4j2-example/src/main/java/com/stackify/models/User.java b/guest/log4j2-example/src/main/java/com/stackify/models/User.java new file mode 100644 index 0000000000..1a53651292 --- /dev/null +++ b/guest/log4j2-example/src/main/java/com/stackify/models/User.java @@ -0,0 +1,43 @@ +package com.stackify.models; + +import java.time.LocalDate; + +public class User { + private String name; + private String email; + private LocalDate dateOfBirth; + + public User() { + } + + public User(String name, String email) { + super(); + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public LocalDate getDateOfBirth() { + return dateOfBirth; + } + + public void setDateOfBirth(LocalDate dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + +} diff --git a/guest/log4j2-example/src/main/java/com/stackify/services/MyService.java b/guest/log4j2-example/src/main/java/com/stackify/services/MyService.java new file mode 100644 index 0000000000..4b1dc0bf34 --- /dev/null +++ b/guest/log4j2-example/src/main/java/com/stackify/services/MyService.java @@ -0,0 +1,14 @@ +package com.stackify.services; + +import java.time.LocalDate; +import java.time.Period; + +import com.stackify.models.User; + +public class MyService { + + public int calculateUserAge(User user) { + return Period.between(user.getDateOfBirth(), LocalDate.now()).getYears(); + } + +} diff --git a/guest/log4j2-example/src/main/resources/log4j2.xml b/guest/log4j2-example/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..06f2ba5245 --- /dev/null +++ b/guest/log4j2-example/src/main/resources/log4j2.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java new file mode 100644 index 0000000000..49e367e45b --- /dev/null +++ b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java @@ -0,0 +1,81 @@ +package com.stackify.services; + +import java.time.LocalDate; +import java.time.Month; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.FileAppender; +import org.apache.logging.log4j.core.config.AppenderRef; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.junit.Test; + +import com.stackify.models.User; +import com.stackify.services.MyService; + +public class MyServiceTest { + + private static final Logger logger = LogManager.getLogger(MyServiceTest.class); + + @Test + public void testService() { + MyService myService = new MyService(); + User user = new User("John", "john@yahoo.com"); + user.setDateOfBirth(LocalDate.of(1980, Month.APRIL, 20)); + logger.info("Age of user {} is {}", () -> user.getName(), () -> myService.calculateUserAge(user)); + } + + @Test + public void testColoredLogger() { + logger.fatal("Fatal level message"); + logger.error("Error level message"); + logger.warn("Warn level message"); + logger.info("Info level message"); + logger.debug("Debug level message"); + } + + @Test + public void testRollingFileAppender() { + Logger rfLogger = LogManager.getLogger("RollingFileLogger"); + rfLogger.info("Json Message 1"); + rfLogger.info("Json Message 2"); + } + + @Test + public void testProgrammaticConfig() { + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + Configuration config = ctx.getConfiguration(); + + PatternLayout layout = PatternLayout.newBuilder().withConfiguration(config).withPattern("%d{HH:mm:ss.SSS} %level %msg%n").build(); + + Appender appender = FileAppender.newBuilder().setConfiguration(config).withName("programmaticFileAppender").withLayout(layout).withFileName("java.log").build(); + appender.start(); + config.addAppender(appender); + AppenderRef ref = AppenderRef.createAppenderRef("programmaticFileAppender", null, null); + AppenderRef[] refs = new AppenderRef[] { ref }; + + LoggerConfig loggerConfig = LoggerConfig.createLogger(false, Level.INFO, "programmaticLogger", "true", refs, null, config, null); + + loggerConfig.addAppender(appender, null, null); + config.addLogger("programmaticLogger", loggerConfig); + ctx.updateLoggers(); + + Logger pLogger = LogManager.getLogger("programmaticLogger"); + pLogger.info("Programmatic Logger Message"); + } + + @Test + public void testCustomLevel() { + Level myLevel = Level.forName("NEW_LEVEL", 350); + logger.log(myLevel, "Custom Level Message"); + + logger.log(Level.getLevel("NEW_XML_LEVEL"), "Custom XML Level Message"); + + } + +}