diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java index 6ddcb954a1..d742d3a55f 100644 --- a/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/daemon/NewThread.java @@ -3,8 +3,18 @@ package com.baeldung.concurrent.daemon; public class NewThread extends Thread { public void run() { - while (true) - for (int i = 0; i < 10; i++) - System.out.println("New Thread is running..."); + + long startTime = System.currentTimeMillis(); + while (true) { + for (int i = 0; i < 10; i++) { + System.out.println("New Thread is running..." + i); + } + + // prevent the Thread to run forever. It will finish it's execution after 2 seconds + if (System.currentTimeMillis() - startTime > 2000) { + Thread.currentThread().interrupt(); + break; + } + } } } diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java new file mode 100644 index 0000000000..2f0796b491 --- /dev/null +++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/executorservice/DelayedCallable.java @@ -0,0 +1,26 @@ +package com.baeldung.concurrent.executorservice; + +import java.util.concurrent.Callable; + +public class DelayedCallable implements Callable { + + private String name; + private long period; + + public DelayedCallable(String name, long period) { + this.name = name; + this.period = period; + } + + public String call() { + + try { + Thread.sleep(period); + } catch (InterruptedException ex) { + // handle exception + ex.printStackTrace(); + } + + return name; + } +} diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java index 2c4eeb63d6..3ca69d8847 100644 --- a/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/daemon/DaemonThreadTest.java @@ -3,11 +3,13 @@ package com.baeldung.concurrent.daemon; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.junit.Ignore; import org.junit.Test; public class DaemonThreadTest { @Test + @Ignore public void whenCallIsDaemon_thenCorrect() { NewThread daemonThread = new NewThread(); NewThread userThread = new NewThread(); @@ -20,6 +22,7 @@ public class DaemonThreadTest { } @Test(expected = IllegalThreadStateException.class) + @Ignore public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() { NewThread daemonThread = new NewThread(); daemonThread.start(); diff --git a/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java new file mode 100644 index 0000000000..0f461909ea --- /dev/null +++ b/core-java-concurrency/src/test/java/com/baeldung/concurrent/executorservice/WaitingForThreadsToFinishTest.java @@ -0,0 +1,147 @@ +package com.baeldung.concurrent.executorservice; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.*; + +import static junit.framework.TestCase.assertTrue; + +public class WaitingForThreadsToFinishTest { + + private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishTest.class); + private final static ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + + @Test + public void givenMultipleThreads_whenInvokeAll_thenMainThreadShouldWaitForAllToFinish() { + + ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10); + + List> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000)); + + try { + long startProcessingTime = System.currentTimeMillis(); + List> futures = WORKER_THREAD_POOL.invokeAll(callables); + + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + assertTrue(totalProcessingTime >= 3000); + + String firstThreadResponse = futures.get(0) + .get(); + assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse)); + + String secondThreadResponse = futures.get(1) + .get(); + assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse)); + + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); + } + + WORKER_THREAD_POOL.shutdown(); + } + + @Test + public void givenMultipleThreads_whenUsingCompletionService_thenMainThreadShouldWaitForAllToFinish() { + + CompletionService service = new ExecutorCompletionService<>(WORKER_THREAD_POOL); + + List> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000)); + + for (Callable callable : callables) { + service.submit(callable); + } + + WORKER_THREAD_POOL.shutdown(); + + try { + + long startProcessingTime = System.currentTimeMillis(); + + Future future = service.take(); + String firstThreadResponse = future.get(); + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + + assertTrue("First response should be from the fast thread", "fast thread".equals(firstThreadResponse)); + assertTrue(totalProcessingTime >= 100 && totalProcessingTime < 1000); + LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds"); + + future = service.take(); + String secondThreadResponse = future.get(); + totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + + assertTrue("Last response should be from the slow thread", "slow thread".equals(secondThreadResponse)); + assertTrue(totalProcessingTime >= 3000 && totalProcessingTime < 4000); + LOG.debug("Thread finished after: " + totalProcessingTime + " milliseconds"); + + } catch (ExecutionException | InterruptedException ex) { + ex.printStackTrace(); + } + + } + + @Test + public void givenMultipleThreads_whenUsingCompletableFutures_thenMainThreadShouldWaitForAllToFinish() { + + CompletableFuture future1 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "Hello"; + }); + + CompletableFuture future2 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "Beautiful"; + }); + + CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { + + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + return "World"; + }); + + long startProcessingTime = System.currentTimeMillis(); + CompletableFuture combinedFuture = CompletableFuture.allOf(future1, future2, future3); + combinedFuture.join(); + + long totalProcessingTime = System.currentTimeMillis() - startProcessingTime; + assertTrue(totalProcessingTime >= 5000 && totalProcessingTime < 6000); + + LOG.debug("Responses from all threads are available after " + totalProcessingTime + " milliseconds"); + + try { + String thread1Response = future1.get(); + assertTrue(thread1Response.equals("Hello")); + + String thread2Response = future2.get(); + assertTrue(thread2Response.equals("Beautiful")); + + String thread3Response = future3.get(); + assertTrue(thread3Response.equals("World")); + + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + + WORKER_THREAD_POOL.shutdown(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java index 2ed9a27c4c..7c1e291646 100644 --- a/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java +++ b/core-java/src/main/java/com/baeldung/java/nio/selector/EchoServer.java @@ -13,6 +13,8 @@ import java.util.Set; public class EchoServer { + private static final String POISON_PILL = "POISON_PILL"; + public static void main(String[] args) throws IOException { Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open(); @@ -30,23 +32,36 @@ public class EchoServer { SelectionKey key = iter.next(); if (key.isAcceptable()) { - SocketChannel client = serverSocket.accept(); - client.configureBlocking(false); - client.register(selector, SelectionKey.OP_READ); + register(selector, serverSocket); } if (key.isReadable()) { - SocketChannel client = (SocketChannel) key.channel(); - client.read(buffer); - buffer.flip(); - client.write(buffer); - buffer.clear(); + answerWithEcho(buffer, key); } iter.remove(); } } } + private static void answerWithEcho(ByteBuffer buffer, SelectionKey key) throws IOException { + SocketChannel client = (SocketChannel) key.channel(); + client.read(buffer); + if (new String(buffer.array()).trim().equals(POISON_PILL)) { + client.close(); + System.out.println("Not accepting client messages anymore"); + } + + buffer.flip(); + client.write(buffer); + buffer.clear(); + } + + private static void register(Selector selector, ServerSocketChannel serverSocket) throws IOException { + SocketChannel client = serverSocket.accept(); + client.configureBlocking(false); + client.register(selector, SelectionKey.OP_READ); + } + public static Process start() throws IOException, InterruptedException { String javaHome = System.getProperty("java.home"); String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; diff --git a/drools/backward-chaining/src/main/java/com/baeldung/drools/BackwardChaining.java b/drools/backward-chaining/src/main/java/com/baeldung/drools/BackwardChaining.java new file mode 100644 index 0000000000..1c1d258b47 --- /dev/null +++ b/drools/backward-chaining/src/main/java/com/baeldung/drools/BackwardChaining.java @@ -0,0 +1,33 @@ +package com.baeldung.drools; + +import org.kie.api.KieServices; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; + +import com.baeldung.drools.model.Fact; +import com.baeldung.drools.model.Result; + +public class BackwardChaining { + public static void main(String[] args) { + Result result = new BackwardChaining().backwardChaining(); + System.out.println(result.getValue()); + result.getFacts().stream().forEach(System.out::println); + } + + public Result backwardChaining() { + Result result = new Result(); + KieServices ks = KieServices.Factory.get(); + KieContainer kContainer = ks.getKieClasspathContainer(); + KieSession ksession = kContainer.newKieSession("ksession-backward-chaining"); + ksession.setGlobal("result", result); + ksession.insert(new Fact("Asia", "Planet Earth")); +// ksession.insert(new Fact("China", "Asia")); + ksession.insert(new Fact("Great Wall of China", "China")); + + ksession.fireAllRules(); + + return result; + + } + +} \ No newline at end of file diff --git a/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Fact.java b/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Fact.java new file mode 100644 index 0000000000..62b44b9d92 --- /dev/null +++ b/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Fact.java @@ -0,0 +1,69 @@ +package com.baeldung.drools.model; + +import org.kie.api.definition.type.Position; + +public class Fact { + + @Position(0) + private String element; + + @Position(1) + private String place; + + public Fact(String element, String place) { + this.element = element; + this.place = place; + } + + public String getElement() { + return element; + } + + public void setElement(String element) { + this.element = element; + } + + public String getPlace() { + return place; + } + + public void setPlace(String place) { + this.place = place; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((element == null) ? 0 : element.hashCode()); + result = prime * result + ((place == null) ? 0 : place.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; + Fact other = (Fact) obj; + if (element == null) { + if (other.element != null) + return false; + } else if (!element.equals(other.element)) + return false; + if (place == null) { + if (other.place != null) + return false; + } else if (!place.equals(other.place)) + return false; + return true; + } + + @Override + public String toString() { + return "Fact{" + "element='" + element + '\'' + ", place='" + place + '\'' + '}'; + } +} \ No newline at end of file diff --git a/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Result.java b/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Result.java new file mode 100644 index 0000000000..b22557832b --- /dev/null +++ b/drools/backward-chaining/src/main/java/com/baeldung/drools/model/Result.java @@ -0,0 +1,31 @@ +package com.baeldung.drools.model; + +import java.util.ArrayList; +import java.util.List; + +public class Result { + private String value; + private List facts = new ArrayList<>(); + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getFacts() { + return facts; + } + + public void setFacts(List facts) { + this.facts = facts; + } + + public void addFact(String fact) { + this.facts.add(fact); + } + + +} diff --git a/drools/backward-chaining/src/main/resources/META-INF/maven/pom.properties b/drools/backward-chaining/src/main/resources/META-INF/maven/pom.properties new file mode 100644 index 0000000000..26d8331732 --- /dev/null +++ b/drools/backward-chaining/src/main/resources/META-INF/maven/pom.properties @@ -0,0 +1,3 @@ +groupId=com.baeldung.drools +artifactId=DroosBackwardChaining +version=1.0.0-SNAPSHOT diff --git a/drools/backward-chaining/src/main/resources/backward_chaining/rules.drl b/drools/backward-chaining/src/main/resources/backward_chaining/rules.drl new file mode 100644 index 0000000000..abcf95b9f1 --- /dev/null +++ b/drools/backward-chaining/src/main/resources/backward_chaining/rules.drl @@ -0,0 +1,34 @@ +package com.baeldung + +import com.baeldung.drools.model.Fact; + +global com.baeldung.drools.model.Result result; + +dialect "mvel" + +query belongsTo(String x, String y) + Fact(x, y;) + or + (Fact(z, y;) and belongsTo(x, z;)) +end + +rule "Great Wall of China BELONGS TO Planet Earth" +when + belongsTo("Great Wall of China", "Planet Earth";) +then + result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth"); +end + +rule "Great Wall of China DOES NOT BELONG TO of Planet Earth" +when + not belongsTo("Great Wall of China", "Planet Earth";) +then + result.setValue("Decision two taken: Great Wall of China DOES NOT BELONG TO Planet Earth"); +end + +rule "print all facts" +when + belongsTo(element, place;) +then + result.addFact(element + " IS ELEMENT OF " + place); +end diff --git a/drools/backward-chaining/src/test/java/com/baeldung/test/BackwardChainingTest.java b/drools/backward-chaining/src/test/java/com/baeldung/test/BackwardChainingTest.java new file mode 100644 index 0000000000..676e941950 --- /dev/null +++ b/drools/backward-chaining/src/test/java/com/baeldung/test/BackwardChainingTest.java @@ -0,0 +1,57 @@ +package com.baeldung.test; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.kie.api.KieServices; +import org.kie.api.runtime.KieContainer; +import org.kie.api.runtime.KieSession; + +import com.baeldung.drools.model.Fact; +import com.baeldung.drools.model.Result; + +import static junit.framework.TestCase.assertEquals; + +@RunWith(value = JUnit4.class) +public class BackwardChainingTest { + private Result result; + private KieServices ks; + private KieContainer kContainer; + private KieSession ksession; + + @Before + public void before() { + result = new Result(); + ks = KieServices.Factory.get(); + kContainer = ks.getKieClasspathContainer(); + ksession = kContainer.newKieSession("ksession-backward-chaining"); + ksession.setGlobal("result", result); + } + + @Test + public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() { + + ksession.setGlobal("result", result); + ksession.insert(new Fact("Asia", "Planet Earth")); + ksession.insert(new Fact("China", "Asia")); + ksession.insert(new Fact("Great Wall of China", "China")); + + ksession.fireAllRules(); + + // Assert Decision one + assertEquals(result.getValue(), "Decision one taken: Great Wall of China BELONGS TO Planet Earth"); + } + + @Test + public void whenChinaIsNotGiven_ThenWallOfChinaDoesNotBelongToPlanetEarth() { + ksession.insert(new Fact("Asia", "Planet Earth")); + // ksession.insert(new Location("China", "Asia")); // not provided to force Decision two + ksession.insert(new Fact("Great Wall of China", "China")); + + ksession.fireAllRules(); + + // Assert Decision two + assertEquals(result.getValue(), "Decision two taken: Great Wall of China DOES NOT BELONG TO Planet Earth"); + } +} diff --git a/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java index 62feb6b4b9..e86f52ff56 100644 --- a/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java +++ b/ejb/wildfly/widlfly-web/src/main/java/TestEJBServlet.java @@ -1,5 +1,6 @@ import java.io.IOException; +import java.io.PrintWriter; import java.util.List; import javax.ejb.EJB; @@ -15,19 +16,32 @@ import wildfly.beans.UserBeanLocal; * Servlet implementation class TestEJBServlet */ public class TestEJBServlet extends HttpServlet { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @EJB - private UserBeanLocal userBean; + @EJB + private UserBeanLocal userBean; - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - List users = userBean.getUsers(); + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + List users = userBean.getUsers(); - response.getWriter() - .append("The number of users is: " + users.size()); - } + PrintWriter out = response.getWriter(); - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - doGet(request, response); - } + out.println(""); + out.println("Users"); + out.println(""); + out.println("

List of users:

"); + out.println(""); + for (User user : users) { + out.println(""); + out.print(""); + out.print(""); + out.println(""); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doGet(request, response); + } } diff --git a/guest/spring-mvc/pom.xml b/guest/spring-mvc/pom.xml index 9974a76e8a..1f695a75a7 100644 --- a/guest/spring-mvc/pom.xml +++ b/guest/spring-mvc/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.forketyfork.guest + com.stackify.guestspring-mvc0.0.1-SNAPSHOTjar diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/Spring5Application.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java similarity index 76% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/Spring5Application.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java index d9af7c8ac9..42d40fa02d 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/Spring5Application.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/Spring5Application.java @@ -1,11 +1,11 @@ -package com.forketyfork.guest.springmvc; +package com.stackify.guest.springmvc; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.SpringApplication; @SpringBootApplication -@ComponentScan(basePackages = {"com.forketyfork.guest.springmvc"}) +@ComponentScan(basePackages = {"com.stackify.guest.springmvc"}) public class Spring5Application { public static void main(String[] args) { diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/model/LoginData.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java similarity index 89% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/model/LoginData.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java index a9140da4f9..b1a0e86ef4 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/model/LoginData.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/model/LoginData.java @@ -1,4 +1,4 @@ -package com.forketyfork.guest.springmvc.model; +package com.stackify.guest.springmvc.model; public class LoginData { diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/InternalsController.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java similarity index 92% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/InternalsController.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java index 04adb9211e..0bd8570eed 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/InternalsController.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/InternalsController.java @@ -1,6 +1,5 @@ -package com.forketyfork.guest.springmvc.web; +package com.stackify.guest.springmvc.web; -import com.forketyfork.guest.springmvc.model.LoginData; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -8,6 +7,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; +import com.stackify.guest.springmvc.model.LoginData; + import java.util.Collections; @Controller diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyInputResource.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java similarity index 85% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyInputResource.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java index 4c30cfb842..cf5815840a 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyInputResource.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyInputResource.java @@ -1,4 +1,4 @@ -package com.forketyfork.guest.springmvc.web; +package com.stackify.guest.springmvc.web; public class MyInputResource { diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyOutputResource.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java similarity index 85% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyOutputResource.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java index bcb76056a4..2d0e174243 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/MyOutputResource.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/MyOutputResource.java @@ -1,4 +1,4 @@ -package com.forketyfork.guest.springmvc.web; +package com.stackify.guest.springmvc.web; public class MyOutputResource { diff --git a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/RestfulWebServiceController.java b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java similarity index 87% rename from guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/RestfulWebServiceController.java rename to guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java index 820c80db7a..edb35e6ecf 100644 --- a/guest/spring-mvc/src/main/java/com/forketyfork/guest/springmvc/web/RestfulWebServiceController.java +++ b/guest/spring-mvc/src/main/java/com/stackify/guest/springmvc/web/RestfulWebServiceController.java @@ -1,4 +1,4 @@ -package com.forketyfork.guest.springmvc.web; +package com.stackify.guest.springmvc.web; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/hibernate5/README.md b/hibernate5/README.md index ff12555376..9ef170a134 100644 --- a/hibernate5/README.md +++ b/hibernate5/README.md @@ -1 +1,3 @@ ## Relevant articles: + +- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping) diff --git a/junit5/src/main/java/com/baeldung/junit5/Greetings.java b/junit5/src/main/java/com/baeldung/junit5/Greetings.java new file mode 100644 index 0000000000..f43269f646 --- /dev/null +++ b/junit5/src/main/java/com/baeldung/junit5/Greetings.java @@ -0,0 +1,9 @@ +package com.baeldung.junit5; + +public class Greetings { + + public static String sayHello() { + return "Hello"; + } + +} diff --git a/junit5/src/test/java/com/baeldung/GreetingsTest.java b/junit5/src/test/java/com/baeldung/GreetingsTest.java new file mode 100644 index 0000000000..e894d5857c --- /dev/null +++ b/junit5/src/test/java/com/baeldung/GreetingsTest.java @@ -0,0 +1,19 @@ +package com.baeldung; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import com.baeldung.junit5.Greetings; + +@RunWith(JUnitPlatform.class) +public class GreetingsTest { + + @Test + void whenCallingSayHello_thenReturnHello() { + assertTrue("Hello".equals(Greetings.sayHello())); + } + +} diff --git a/patterns/template-method/pom.xml b/patterns/template-method/pom.xml new file mode 100644 index 0000000000..c3b6a084ac --- /dev/null +++ b/patterns/template-method/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + com.baeldung.templatemethodpattern + templatemethodpattern + 1.0 + jar + + UTF-8 + 1.8 + 1.8 + + + + junit + junit + 4.12 + test + + + \ No newline at end of file diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java new file mode 100644 index 0000000000..581c774f52 --- /dev/null +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/application/Application.java @@ -0,0 +1,18 @@ +package com.baeldung.templatemethodpattern.application; + +import com.baeldung.templatemethodpattern.model.Computer; +import com.baeldung.templatemethodpattern.model.HighEndComputer; +import com.baeldung.templatemethodpattern.model.StandardComputer; + +public class Application { + + public static void main(String[] args) { + Computer standardComputer = new StandardComputer(); + standardComputer.buildComputer(); + standardComputer.getComputerParts().forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v)); + + Computer highEndComputer = new HighEndComputer(); + highEndComputer.buildComputer(); + highEndComputer.getComputerParts().forEach((k, v) -> System.out.println("Part : " + k + " Value : " + v)); + } +} diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java new file mode 100644 index 0000000000..c5d1a2cde8 --- /dev/null +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/Computer.java @@ -0,0 +1,34 @@ +package com.baeldung.templatemethodpattern.model; + +import java.util.HashMap; +import java.util.Map; + +public abstract class Computer { + + protected Map computerParts = new HashMap<>(); + + public final void buildComputer() { + addMotherboard(); + addProcessor(); + addMemory(); + addHardDrive(); + addGraphicCard(); + addSoundCard(); + } + + public abstract void addProcessor(); + + public abstract void addMotherboard(); + + public abstract void addMemory(); + + public abstract void addHardDrive(); + + public abstract void addGraphicCard(); + + public abstract void addSoundCard(); + + public Map getComputerParts() { + return computerParts; + } +} diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java new file mode 100644 index 0000000000..11baeca6f7 --- /dev/null +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/HighEndComputer.java @@ -0,0 +1,34 @@ +package com.baeldung.templatemethodpattern.model; + +public class HighEndComputer extends Computer { + + @Override + public void addProcessor() { + computerParts.put("Processor", "High End Processor"); + } + + @Override + public void addMotherboard() { + computerParts.put("Motherboard", "High End Motherboard"); + } + + @Override + public void addMemory() { + computerParts.put("Memory", "16GB"); + } + + @Override + public void addHardDrive() { + computerParts.put("Hard Drive", "2TB Hard Drive"); + } + + @Override + public void addGraphicCard() { + computerParts.put("Graphic Card", "High End Graphic Card"); + } + + @Override + public void addSoundCard() { + computerParts.put("Sound Card", "High End Sound Card"); + } +} diff --git a/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java new file mode 100644 index 0000000000..22ff370203 --- /dev/null +++ b/patterns/template-method/src/main/java/com/baeldung/templatemethodpattern/model/StandardComputer.java @@ -0,0 +1,34 @@ +package com.baeldung.templatemethodpattern.model; + +public class StandardComputer extends Computer { + + @Override + public void addProcessor() { + computerParts.put("Processor", "Standard Processor"); + } + + @Override + public void addMotherboard() { + computerParts.put("Motherboard", "Standard Motherboard"); + } + + @Override + public void addMemory() { + computerParts.put("Memory", "8GB"); + } + + @Override + public void addHardDrive() { + computerParts.put("Hard Drive", "1TB Hard Drive"); + } + + @Override + public void addGraphicCard() { + computerParts.put("Graphic Card", "Standard Graphic Card"); + } + + @Override + public void addSoundCard() { + computerParts.put("Sound Card", "Standard Sound Card"); + } +} diff --git a/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java b/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java new file mode 100644 index 0000000000..afe66883ac --- /dev/null +++ b/patterns/template-method/src/test/java/com/baeldung/templatemethodpatterntest/TemplateMethodPatternTest.java @@ -0,0 +1,120 @@ +package com.baeldung.templatemethodpatterntest; + +import com.baeldung.templatemethodpattern.model.HighEndComputer; +import com.baeldung.templatemethodpattern.model.StandardComputer; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TemplateMethodPatternTest { + + private static StandardComputer standardComputer; + private static HighEndComputer highEndComputer; + + @BeforeClass + public static void setUpStandardComputerInstance() { + standardComputer = new StandardComputer(); + } + + @BeforeClass + public static void setUpHighEndComputerInstance() { + highEndComputer = new HighEndComputer(); + } + + @Test + public void givenStandardProcessor_whenAddingProcessor_thenEqualAssertion() { + standardComputer.addProcessor(); + Assert.assertEquals("Standard Processor", standardComputer + .getComputerParts().get("Processor")); + } + + @Test + public void givenStandardMotherBoard_whenAddingMotherBoard_thenEqualAssertion() { + standardComputer.addMotherboard(); + Assert.assertEquals("Standard Motherboard", standardComputer + .getComputerParts().get("Motherboard")); + } + + @Test + public void givenStandardMemory_whenAddingMemory_thenEqualAssertion() { + standardComputer.addMemory(); + Assert.assertEquals("8GB", standardComputer + .getComputerParts().get("Memory")); + } + + @Test + public void givenStandardHardDrive_whenAddingHardDrive_thenEqualAssertion() { + standardComputer.addHardDrive(); + Assert.assertEquals("1TB Hard Drive", standardComputer + .getComputerParts().get("Hard Drive")); + } + + @Test + public void givenStandardGraphicaCard_whenAddingGraphicCard_thenEqualAssertion() { + standardComputer.addGraphicCard(); + Assert.assertEquals("Standard Graphic Card", standardComputer + .getComputerParts().get("Graphic Card")); + } + + @Test + public void givenStandardSoundCard_whenAddingSoundCard_thenEqualAssertion() { + standardComputer.addSoundCard(); + Assert.assertEquals("Standard Sound Card", standardComputer + .getComputerParts().get("Sound Card")); + } + + @Test + public void givenAllStandardParts_whenBuildingComputer_thenSixParts() { + standardComputer.buildComputer(); + Assert.assertEquals(6, standardComputer + .getComputerParts().size()); + } + + @Test + public void givenHightEndProcessor_whenAddingProcessor_thenEqualAssertion() { + highEndComputer.addProcessor(); + Assert.assertEquals("High End Processor", highEndComputer + .getComputerParts().get("Processor")); + } + + @Test + public void givenHighEnddMotherBoard_whenAddingMotherBoard_thenEqualAssertion() { + highEndComputer.addMotherboard(); + Assert.assertEquals("High End Motherboard", highEndComputer + .getComputerParts().get("Motherboard")); + } + + @Test + public void givenHighEndMemory_whenAddingMemory_thenEqualAssertion() { + highEndComputer.addMemory(); + Assert.assertEquals("16GB", highEndComputer + .getComputerParts().get("Memory")); + } + + @Test + public void givenHighEndHardDrive_whenAddingHardDrive_thenEqualAssertion() { + highEndComputer.addHardDrive(); + Assert.assertEquals("2TB Hard Drive", highEndComputer + .getComputerParts().get("Hard Drive")); + } + + @Test + public void givenHighEndGraphicCard_whenAddingGraphicCard_thenEqualAssertion() { + highEndComputer.addGraphicCard(); + Assert.assertEquals("High End Graphic Card", highEndComputer + .getComputerParts().get("Graphic Card")); + } + + @Test + public void givenHighEndSoundCard_whenAddingSoundCard_thenEqualAssertion() { + highEndComputer.addSoundCard(); + Assert.assertEquals("High End Sound Card", highEndComputer + .getComputerParts().get("Sound Card")); + } + + @Test + public void givenAllHighEndParts_whenBuildingComputer_thenSixParts() { + highEndComputer.buildComputer(); + Assert.assertEquals(6, highEndComputer.getComputerParts().size()); + } +} diff --git a/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java b/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java index 7bab288bab..a218c6b7cf 100644 --- a/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java +++ b/spring-5/src/main/java/com/baeldung/web/reactive/client/WebClientController.java @@ -43,7 +43,8 @@ public class WebClientController { WebClient.RequestHeadersSpec requestSpec2 = uri2.body(BodyInserters.fromObject("data")); // inserters - BodyInserter, ReactiveHttpOutputMessage> inserter1 = BodyInserters.fromPublisher(Subscriber::onComplete, String.class); + BodyInserter, ReactiveHttpOutputMessage> inserter1 = BodyInserters + .fromPublisher(Subscriber::onComplete, String.class); LinkedMultiValueMap map = new LinkedMultiValueMap<>(); map.add("key1", "value1"); diff --git a/spring-boot-admin/README.md b/spring-boot-admin/README.md new file mode 100644 index 0000000000..4cea3f0611 --- /dev/null +++ b/spring-boot-admin/README.md @@ -0,0 +1 @@ +Spring Boot Admin \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/.gitignore b/spring-boot-admin/spring-boot-admin-client/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/pom.xml b/spring-boot-admin/spring-boot-admin-client/pom.xml new file mode 100644 index 0000000000..ecb6c3f8b6 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + com.baeldung + spring-boot-admin-client + 0.0.1-SNAPSHOT + jar + + spring-boot-admin-client + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.5.4 + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-security + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin-starter-client.version} + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + build-info + + + + + + + + + diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java b/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java new file mode 100644 index 0000000000..596da131a6 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.springbootadminclient; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringBootAdminClientApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootAdminClientApplication.class, args); + } +} diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties b/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties new file mode 100644 index 0000000000..58c178ecd9 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/resources/application.properties @@ -0,0 +1,16 @@ +#basic auth creddentials +security.user.name=client +security.user.password=client + +#configs to connect to a secured server +spring.boot.admin.url=http://localhost:8080 +spring.boot.admin.username=admin +spring.boot.admin.password=admin + +#configs to give secured server info +spring.boot.admin.client.metadata.user.name=${security.user.name} +spring.boot.admin.client.metadata.user.password=${security.user.password} + +#app config +spring.application.name=spring-boot-admin-client +server.port=8081 \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml b/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..ff96acae79 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + + %date [%thread] %-5level %logger{25} - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java new file mode 100644 index 0000000000..d70fb1c7cf --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-client/src/test/java/com/baeldung/springbootadminclient/SpringBootAdminClientApplicationTests.java @@ -0,0 +1,55 @@ +package com.baeldung.springbootadminclient; + +import org.junit.Before; +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.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.junit.Assert.assertEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = RANDOM_PORT) +public class SpringBootAdminClientApplicationTests { + + @Autowired Environment environment; + + @Autowired WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = MockMvcBuilders + .webAppContextSetup(wac) + .build(); + } + + @Test + public void whenEnvironmentAvailable_ThenAdminServerPropertiesExist() { + assertEquals(environment.getProperty("spring.boot.admin.url"), "http://localhost:8080"); + assertEquals(environment.getProperty("spring.boot.admin.username"), "admin"); + assertEquals(environment.getProperty("spring.boot.admin.password"), "admin"); + } + + @Test + public void whenHttpBasicAttempted_ThenSuccess() throws Exception { + mockMvc.perform(get("/env").with(httpBasic("client", "client"))); + } + + @Test + public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception { + mockMvc + .perform(get("/env").with(httpBasic("client", "invalid"))) + .andExpect(status().isUnauthorized()); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/.gitignore b/spring-boot-admin/spring-boot-admin-server/.gitignore new file mode 100644 index 0000000000..2af7cefb0a --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/pom.xml b/spring-boot-admin/spring-boot-admin-server/pom.xml new file mode 100644 index 0000000000..b199e63b31 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + com.baeldung + spring-boot-admin-server + 0.0.1-SNAPSHOT + jar + + spring-boot-admin-server + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.5.4 + 1.5.4 + + + + + org.springframework.boot + spring-boot-starter + + + + + de.codecentric + spring-boot-admin-server + ${spring-boot-admin-server.version} + + + de.codecentric + spring-boot-admin-server-ui + ${spring-boot-admin-server.version} + + + + + de.codecentric + spring-boot-admin-server-ui-login + ${spring-boot-admin-server.version} + + + org.springframework.boot + spring-boot-starter-security + + + com.hazelcast + hazelcast + + + + de.codecentric + spring-boot-admin-starter-client + ${spring-boot-admin-starter-client.version} + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java new file mode 100644 index 0000000000..d1fb4e769b --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/SpringBootAdminServerApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootadminserver; + +import de.codecentric.boot.admin.config.EnableAdminServer; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@EnableAdminServer +@SpringBootApplication +public class SpringBootAdminServerApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootAdminServerApplication.class, args); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java new file mode 100644 index 0000000000..b19b7820af --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/HazelcastConfig.java @@ -0,0 +1,24 @@ +package com.baeldung.springbootadminserver.configs; + +import com.hazelcast.config.Config; +import com.hazelcast.config.EvictionPolicy; +import com.hazelcast.config.ListConfig; +import com.hazelcast.config.MapConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HazelcastConfig { + + @Bean + public Config hazelcast() { + return new Config() + .setProperty("hazelcast.jmx", "true") + .addMapConfig(new MapConfig("spring-boot-admin-application-store") + .setBackupCount(1) + .setEvictionPolicy(EvictionPolicy.NONE)) + .addListConfig(new ListConfig("spring-boot-admin-event-store") + .setBackupCount(1) + .setMaxSize(1000)); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java new file mode 100644 index 0000000000..10a31464ab --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/NotifierConfiguration.java @@ -0,0 +1,42 @@ +package com.baeldung.springbootadminserver.configs; + +import de.codecentric.boot.admin.notify.LoggingNotifier; +import de.codecentric.boot.admin.notify.RemindingNotifier; +import de.codecentric.boot.admin.notify.filter.FilteringNotifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import java.util.concurrent.TimeUnit; + +@Configuration +@EnableScheduling +public class NotifierConfiguration { + + // @Autowired private Notifier notifier; + + @Bean + public LoggingNotifier notifier() { + return new LoggingNotifier(); + } + + @Bean + public FilteringNotifier filteringNotifier() { + return new FilteringNotifier(notifier()); + } + + @Bean + @Primary + public RemindingNotifier remindingNotifier() { + RemindingNotifier remindingNotifier = new RemindingNotifier(filteringNotifier()); + remindingNotifier.setReminderPeriod(TimeUnit.MINUTES.toMillis(5)); + return remindingNotifier; + } + + @Scheduled(fixedRate = 60_000L) + public void remind() { + remindingNotifier().sendReminders(); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java new file mode 100644 index 0000000000..4a7c8330b7 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/java/com/baeldung/springbootadminserver/configs/WebSecurityConfig.java @@ -0,0 +1,33 @@ +package com.baeldung.springbootadminserver.configs; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .formLogin() + .loginPage("/login.html") + .loginProcessingUrl("/login") + .permitAll(); + http + .logout() + .logoutUrl("/logout"); + http + .csrf() + .disable(); + http + .authorizeRequests() + .antMatchers("/login.html", "/**/*.css", "/img/**", "/third-party/**") + .permitAll(); + http + .authorizeRequests() + .antMatchers("/**") + .authenticated(); + http.httpBasic(); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties b/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties new file mode 100644 index 0000000000..362f6428e8 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/resources/application.properties @@ -0,0 +1,28 @@ +spring.application.name=spring-boot-admin-server + +security.user.name=admin +security.user.password=admin + +#configs to connect to self register the admin server as a client +spring.boot.admin.url=http://localhost:8080 +spring.boot.admin.username=${security.user.name} +spring.boot.admin.password=${security.user.password} + +#configs to give secured server info +spring.boot.admin.client.metadata.user.name=${security.user.name} +spring.boot.admin.client.metadata.user.password=${security.user.password} + +#mail notifications +#spring.mail.host=smtp.gmail.com +#spring.mail.username=test@gmail.com +#spring.mail.password=password +#spring.mail.port=587 +#spring.mail.properties.mail.smtp.auth=true +#spring.mail.properties.mail.smtp.starttls.enable=true + +#spring.boot.admin.notify.mail.to=test@gmail.com + +#hipchat notifications +#spring.boot.admin.notify.hipchat.auth-token= +#spring.boot.admin.notify.hipchat.room-id= +#spring.boot.admin.notify.hipchat.url=https://youcompany.hipchat.com/v2/ \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml b/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml new file mode 100644 index 0000000000..ff96acae79 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + + %date [%thread] %-5level %logger{25} - %msg%n + + + + + + + \ No newline at end of file diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java new file mode 100644 index 0000000000..8ca50a6f75 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/HazelcastConfigTest.java @@ -0,0 +1,24 @@ +package com.baeldung.springbootadminserver; + +import com.baeldung.springbootadminserver.configs.HazelcastConfig; +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.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertNotEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { HazelcastConfig.class }, webEnvironment = NONE) +public class HazelcastConfigTest { + + @Autowired private ApplicationContext applicationContext; + + @Test + public void whenApplicationContextStarts_HazelcastConfigBeanExists() { + assertNotEquals(applicationContext.getBean("hazelcast"), null); + } +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java new file mode 100644 index 0000000000..85f6b374a4 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/NotifierConfigurationTest.java @@ -0,0 +1,41 @@ +package com.baeldung.springbootadminserver; + +import com.baeldung.springbootadminserver.configs.NotifierConfiguration; +import de.codecentric.boot.admin.notify.Notifier; +import de.codecentric.boot.admin.notify.RemindingNotifier; +import de.codecentric.boot.admin.notify.filter.FilteringNotifier; +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.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertNotEquals; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { NotifierConfiguration.class }, webEnvironment = NONE) +public class NotifierConfigurationTest { + + @Autowired private ApplicationContext applicationContext; + + @Test + public void whenApplicationContextStart_ThenNotifierBeanExists() { + Notifier notifier = (Notifier) applicationContext.getBean("notifier"); + assertNotEquals(notifier, null); + } + + @Test + public void whenApplicationContextStart_ThenFilteringNotifierBeanExists() { + FilteringNotifier filteringNotifier = (FilteringNotifier) applicationContext.getBean("filteringNotifier"); + assertNotEquals(filteringNotifier, null); + } + + @Test + public void whenApplicationContextStart_ThenRemindingNotifierBeanExists() { + RemindingNotifier remindingNotifier = (RemindingNotifier) applicationContext.getBean("remindingNotifier"); + assertNotEquals(remindingNotifier, null); + } + +} diff --git a/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java new file mode 100644 index 0000000000..40611f00f6 --- /dev/null +++ b/spring-boot-admin/spring-boot-admin-server/src/test/java/com/baeldung/springbootadminserver/WebSecurityConfigTest.java @@ -0,0 +1,71 @@ +package com.baeldung.springbootadminserver; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +public class WebSecurityConfigTest { + + @Autowired WebApplicationContext wac; + + private MockMvc mockMvc; + + @Before + public void setup() { + mockMvc = MockMvcBuilders + .webAppContextSetup(wac) + .build(); + } + + @Test + public void whenApplicationStarts_ThenGetLoginPageWithSuccess() throws Exception { + mockMvc + .perform(get("/login.html")) + .andExpect(status().is2xxSuccessful()); + } + + @Test + public void whenFormLoginAttempted_ThenSuccess() throws Exception { + mockMvc.perform(formLogin("/login") + .user("admin") + .password("admin")); + } + + @Test + public void whenFormLoginWithSuccess_ThenApiEndpointsAreAccessible() throws Exception { + mockMvc.perform(formLogin("/login") + .user("admin") + .password("admin")); + + mockMvc + .perform(get("/api/applications/")) + .andExpect(status().is2xxSuccessful()); + + } + + @Test + public void whenHttpBasicAttempted_ThenSuccess() throws Exception { + mockMvc.perform(get("/env").with(httpBasic("admin", "admin"))); + } + + @Test + public void whenInvalidHttpBasicAttempted_ThenUnauthorized() throws Exception { + mockMvc + .perform(get("/env").with(httpBasic("admin", "invalid"))) + .andExpect(status().isUnauthorized()); + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IService.java b/spring-core/src/main/java/com/baeldung/di/spring/IService.java new file mode 100644 index 0000000000..478eea0657 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IService.java @@ -0,0 +1,5 @@ +package com.baeldung.di.spring; + +public interface IService { + public String serve(); +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java b/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java new file mode 100644 index 0000000000..a45970d6b2 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IndexApp.java @@ -0,0 +1,19 @@ +package com.baeldung.di.spring; + +public class IndexApp { + + private IService service; + + public String getServiceValue() { + return service.serve(); + } + + public IService getService() { + return service; + } + + public void setService(IService service) { + this.service = service; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java b/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java new file mode 100644 index 0000000000..ad241f5200 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/IndexService.java @@ -0,0 +1,10 @@ +package com.baeldung.di.spring; + +public class IndexService implements IService { + + @Override + public String serve() { + return "Hello World"; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java b/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java new file mode 100644 index 0000000000..f083504e8f --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/InstanceServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class InstanceServiceFactory { + public IService getService(int number) { + switch (number) { + case 1: + return new MessageService("Foo"); + case 0: + return new IndexService(); + default: + throw new IllegalArgumentException("Unknown parameter " + number); + } + } +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java b/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java new file mode 100644 index 0000000000..1bf6c20b28 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/MessageApp.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class MessageApp { + + private IService iService; + + public MessageApp(IService iService) { + this.iService = iService; + } + + public String getServiceValue() { + return iService.serve(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java b/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java new file mode 100644 index 0000000000..9b6efaab2a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/MessageService.java @@ -0,0 +1,16 @@ +package com.baeldung.di.spring; + +public class MessageService implements IService { + + private String message; + + public MessageService(String message) { + this.message = message; + } + + @Override + public String serve() { + return message; + } + +} diff --git a/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java b/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java new file mode 100644 index 0000000000..bd70898faf --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/di/spring/StaticServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.di.spring; + +public class StaticServiceFactory { + public static IService getService(int number) { + switch (number) { + case 1: + return new MessageService("Foo"); + case 0: + return new IndexService(); + default: + throw new IllegalArgumentException("Unknown parameter " + number); + } + } +} diff --git a/spring-core/src/main/resources/com.baeldung.di.spring.properties b/spring-core/src/main/resources/com.baeldung.di.spring.properties new file mode 100644 index 0000000000..8b8b5b85c2 --- /dev/null +++ b/spring-core/src/main/resources/com.baeldung.di.spring.properties @@ -0,0 +1 @@ +message.value=Hello World \ No newline at end of file diff --git a/spring-core/src/main/resources/com.baeldung.di.spring.xml b/spring-core/src/main/resources/com.baeldung.di.spring.xml new file mode 100644 index 0000000000..9c44d911d1 --- /dev/null +++ b/spring-core/src/main/resources/com.baeldung.di.spring.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java b/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java new file mode 100644 index 0000000000..1d133faf63 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/di/spring/BeanInjectionTest.java @@ -0,0 +1,45 @@ +package com.baeldung.di.spring; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class BeanInjectionTest { + + private ApplicationContext applicationContext; + + @Before + public void setUp() throws Exception { + applicationContext = new ClassPathXmlApplicationContext("com.baeldung.di.spring.xml"); + } + + @Test + public void protoBean_getBean_returnsMultipleInstance() { + final MessageApp messageApp1 = applicationContext.getBean("messageWorldApp", MessageApp.class); + final MessageApp messageApp2 = applicationContext.getBean("messageWorldApp", MessageApp.class); + assertNotEquals(messageApp1, messageApp2); + } + + @Test + public void protoFactoryMethod_getBean_returnsMultipleInstance() { + final IndexApp indexApp1 = applicationContext.getBean("indexAppWithFactoryMethod", IndexApp.class); + final IndexApp indexApp2 = applicationContext.getBean("indexAppWithFactoryMethod", IndexApp.class); + assertNotEquals(indexApp1, indexApp2); + } + + @Test + public void protoStaticFactory_getBean_returnsMultipleInstance() { + final IndexApp indexApp1 = applicationContext.getBean("indexAppWithStaticFactory", IndexApp.class); + final IndexApp indexApp2 = applicationContext.getBean("indexAppWithStaticFactory", IndexApp.class); + assertNotEquals(indexApp1, indexApp2); + } + + @Test + public void singletonBean_getBean_returnsSingleInstance() { + final IndexApp indexApp1 = applicationContext.getBean("indexApp", IndexApp.class); + final IndexApp indexApp2 = applicationContext.getBean("indexApp", IndexApp.class); + assertEquals(indexApp1, indexApp2); + } +} diff --git a/spring-rest-shell/README.md b/spring-rest-shell/README.md new file mode 100644 index 0000000000..06e18450c6 --- /dev/null +++ b/spring-rest-shell/README.md @@ -0,0 +1,5 @@ +## Spring REST Shell Project + +### Relevant Articles + +- [Spring REST Shell](http://www.baeldung.com/) \ No newline at end of file diff --git a/spring-rest-shell/pom.xml b/spring-rest-shell/pom.xml new file mode 100644 index 0000000000..fe255b397f --- /dev/null +++ b/spring-rest-shell/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + com.baeldung + spring-rest-shell + 0.0.1-SNAPSHOT + jar + + spring-rest-shell + A simple project to demonstrate Spring REST Shell features. + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-data-rest + + + + + com.h2database + h2 + runtime + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-rest-shell/src/main/java/com/baeldung/Application.java b/spring-rest-shell/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..37dbe7dab8 --- /dev/null +++ b/spring-rest-shell/src/main/java/com/baeldung/Application.java @@ -0,0 +1,13 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java b/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java new file mode 100644 index 0000000000..6a55517f9f --- /dev/null +++ b/spring-rest-shell/src/main/java/com/baeldung/acticle/Article.java @@ -0,0 +1,40 @@ +package com.baeldung.acticle; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public final class Article { + + @Id + @GeneratedValue + private Long id; + private String title; + private String content; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + +} diff --git a/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java b/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java new file mode 100644 index 0000000000..83daf819f0 --- /dev/null +++ b/spring-rest-shell/src/main/java/com/baeldung/acticle/ArticleRepository.java @@ -0,0 +1,18 @@ +package com.baeldung.acticle; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +import java.util.Optional; + +@RepositoryRestResource( + path = "articles", + collectionResourceRel = "articles", + itemResourceRel = "article" +) +public interface ArticleRepository extends CrudRepository { + + Optional
findByTitle(@Param("title") String title); + +}
" + user.getUsername() + "" + user.getEmail() + "