merge from upstream
This commit is contained in:
commit
dd90165679
@ -3,8 +3,18 @@ package com.baeldung.concurrent.daemon;
|
|||||||
public class NewThread extends Thread {
|
public class NewThread extends Thread {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true)
|
|
||||||
for (int i = 0; i < 10; i++)
|
long startTime = System.currentTimeMillis();
|
||||||
System.out.println("New Thread is running...");
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.concurrent.executorservice;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class DelayedCallable implements Callable<String> {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,13 @@ package com.baeldung.concurrent.daemon;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class DaemonThreadTest {
|
public class DaemonThreadTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore
|
||||||
public void whenCallIsDaemon_thenCorrect() {
|
public void whenCallIsDaemon_thenCorrect() {
|
||||||
NewThread daemonThread = new NewThread();
|
NewThread daemonThread = new NewThread();
|
||||||
NewThread userThread = new NewThread();
|
NewThread userThread = new NewThread();
|
||||||
@ -20,6 +22,7 @@ public class DaemonThreadTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalThreadStateException.class)
|
@Test(expected = IllegalThreadStateException.class)
|
||||||
|
@Ignore
|
||||||
public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
|
public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
|
||||||
NewThread daemonThread = new NewThread();
|
NewThread daemonThread = new NewThread();
|
||||||
daemonThread.start();
|
daemonThread.start();
|
||||||
|
@ -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<Callable<String>> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000));
|
||||||
|
|
||||||
|
try {
|
||||||
|
long startProcessingTime = System.currentTimeMillis();
|
||||||
|
List<Future<String>> 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<String> service = new ExecutorCompletionService<>(WORKER_THREAD_POOL);
|
||||||
|
|
||||||
|
List<Callable<String>> callables = Arrays.asList(new DelayedCallable("fast thread", 100), new DelayedCallable("slow thread", 3000));
|
||||||
|
|
||||||
|
for (Callable<String> callable : callables) {
|
||||||
|
service.submit(callable);
|
||||||
|
}
|
||||||
|
|
||||||
|
WORKER_THREAD_POOL.shutdown();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
long startProcessingTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
Future<String> 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<String> future1 = CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Hello";
|
||||||
|
});
|
||||||
|
|
||||||
|
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(5000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Beautiful";
|
||||||
|
});
|
||||||
|
|
||||||
|
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(3000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "World";
|
||||||
|
});
|
||||||
|
|
||||||
|
long startProcessingTime = System.currentTimeMillis();
|
||||||
|
CompletableFuture<Void> 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();
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,8 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class EchoServer {
|
public class EchoServer {
|
||||||
|
|
||||||
|
private static final String POISON_PILL = "POISON_PILL";
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
Selector selector = Selector.open();
|
Selector selector = Selector.open();
|
||||||
ServerSocketChannel serverSocket = ServerSocketChannel.open();
|
ServerSocketChannel serverSocket = ServerSocketChannel.open();
|
||||||
@ -30,23 +32,36 @@ public class EchoServer {
|
|||||||
SelectionKey key = iter.next();
|
SelectionKey key = iter.next();
|
||||||
|
|
||||||
if (key.isAcceptable()) {
|
if (key.isAcceptable()) {
|
||||||
SocketChannel client = serverSocket.accept();
|
register(selector, serverSocket);
|
||||||
client.configureBlocking(false);
|
|
||||||
client.register(selector, SelectionKey.OP_READ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.isReadable()) {
|
if (key.isReadable()) {
|
||||||
SocketChannel client = (SocketChannel) key.channel();
|
answerWithEcho(buffer, key);
|
||||||
client.read(buffer);
|
|
||||||
buffer.flip();
|
|
||||||
client.write(buffer);
|
|
||||||
buffer.clear();
|
|
||||||
}
|
}
|
||||||
iter.remove();
|
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 {
|
public static Process start() throws IOException, InterruptedException {
|
||||||
String javaHome = System.getProperty("java.home");
|
String javaHome = System.getProperty("java.home");
|
||||||
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
String javaBin = javaHome + File.separator + "bin" + File.separator + "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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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 + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
@ -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<String> facts = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFacts() {
|
||||||
|
return facts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFacts(List<String> facts) {
|
||||||
|
this.facts = facts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFact(String fact) {
|
||||||
|
this.facts.add(fact);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
groupId=com.baeldung.drools
|
||||||
|
artifactId=DroosBackwardChaining
|
||||||
|
version=1.0.0-SNAPSHOT
|
@ -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
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.ejb.EJB;
|
import javax.ejb.EJB;
|
||||||
@ -15,19 +16,32 @@ import wildfly.beans.UserBeanLocal;
|
|||||||
* Servlet implementation class TestEJBServlet
|
* Servlet implementation class TestEJBServlet
|
||||||
*/
|
*/
|
||||||
public class TestEJBServlet extends HttpServlet {
|
public class TestEJBServlet extends HttpServlet {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@EJB
|
@EJB
|
||||||
private UserBeanLocal userBean;
|
private UserBeanLocal userBean;
|
||||||
|
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
List<User> users = userBean.getUsers();
|
throws ServletException, IOException {
|
||||||
|
List<User> users = userBean.getUsers();
|
||||||
|
|
||||||
response.getWriter()
|
PrintWriter out = response.getWriter();
|
||||||
.append("The number of users is: " + users.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
out.println("<html>");
|
||||||
doGet(request, response);
|
out.println("<head><title>Users</title></head>");
|
||||||
}
|
out.println("<body>");
|
||||||
|
out.println("<center><h1>List of users:</h1>");
|
||||||
|
out.println("<table border=\"1\" align=\"center\" style=\"width:50%\">");
|
||||||
|
for (User user : users) {
|
||||||
|
out.println("<tr>");
|
||||||
|
out.print("<td>" + user.getUsername() + "</td>");
|
||||||
|
out.print("<td>" + user.getEmail() + "</td>");
|
||||||
|
out.println("</tr>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
doGet(request, response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.forketyfork.guest</groupId>
|
<groupId>com.stackify.guest</groupId>
|
||||||
<artifactId>spring-mvc</artifactId>
|
<artifactId>spring-mvc</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package com.forketyfork.guest.springmvc;
|
package com.stackify.guest.springmvc;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@ComponentScan(basePackages = {"com.forketyfork.guest.springmvc"})
|
@ComponentScan(basePackages = {"com.stackify.guest.springmvc"})
|
||||||
public class Spring5Application {
|
public class Spring5Application {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
@ -1,4 +1,4 @@
|
|||||||
package com.forketyfork.guest.springmvc.model;
|
package com.stackify.guest.springmvc.model;
|
||||||
|
|
||||||
public class LoginData {
|
public class LoginData {
|
||||||
|
|
@ -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.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
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.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import com.stackify.guest.springmvc.model.LoginData;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
@ -1,4 +1,4 @@
|
|||||||
package com.forketyfork.guest.springmvc.web;
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
public class MyInputResource {
|
public class MyInputResource {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.forketyfork.guest.springmvc.web;
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
public class MyOutputResource {
|
public class MyOutputResource {
|
||||||
|
|
@ -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.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
@ -1 +1,3 @@
|
|||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
|
||||||
|
9
junit5/src/main/java/com/baeldung/junit5/Greetings.java
Normal file
9
junit5/src/main/java/com/baeldung/junit5/Greetings.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.junit5;
|
||||||
|
|
||||||
|
public class Greetings {
|
||||||
|
|
||||||
|
public static String sayHello() {
|
||||||
|
return "Hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
junit5/src/test/java/com/baeldung/GreetingsTest.java
Normal file
19
junit5/src/test/java/com/baeldung/GreetingsTest.java
Normal file
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
patterns/template-method/pom.xml
Normal file
21
patterns/template-method/pom.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung.templatemethodpattern</groupId>
|
||||||
|
<artifactId>templatemethodpattern</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.templatemethodpattern.model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class Computer {
|
||||||
|
|
||||||
|
protected Map<String, String> 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<String, String> getComputerParts() {
|
||||||
|
return computerParts;
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -43,7 +43,8 @@ public class WebClientController {
|
|||||||
WebClient.RequestHeadersSpec<?> requestSpec2 = uri2.body(BodyInserters.fromObject("data"));
|
WebClient.RequestHeadersSpec<?> requestSpec2 = uri2.body(BodyInserters.fromObject("data"));
|
||||||
|
|
||||||
// inserters
|
// inserters
|
||||||
BodyInserter<Publisher<String>, ReactiveHttpOutputMessage> inserter1 = BodyInserters.fromPublisher(Subscriber::onComplete, String.class);
|
BodyInserter<Publisher<String>, ReactiveHttpOutputMessage> inserter1 = BodyInserters
|
||||||
|
.fromPublisher(Subscriber::onComplete, String.class);
|
||||||
|
|
||||||
LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
|
||||||
map.add("key1", "value1");
|
map.add("key1", "value1");
|
||||||
|
1
spring-boot-admin/README.md
Normal file
1
spring-boot-admin/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Spring Boot Admin
|
24
spring-boot-admin/spring-boot-admin-client/.gitignore
vendored
Normal file
24
spring-boot-admin/spring-boot-admin-client/.gitignore
vendored
Normal file
@ -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/
|
71
spring-boot-admin/spring-boot-admin-client/pom.xml
Normal file
71
spring-boot-admin/spring-boot-admin-client/pom.xml
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-boot-admin-client</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-boot-admin-client</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<spring-boot-admin-starter-client.version>1.5.4</spring-boot-admin-starter-client.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
|
<version>${spring-boot-admin-starter-client.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>build-info</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<jmxConfigurator />
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%date [%thread] %-5level %logger{25} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
24
spring-boot-admin/spring-boot-admin-server/.gitignore
vendored
Normal file
24
spring-boot-admin/spring-boot-admin-server/.gitignore
vendored
Normal file
@ -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/
|
95
spring-boot-admin/spring-boot-admin-server/pom.xml
Normal file
95
spring-boot-admin/spring-boot-admin-server/pom.xml
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-boot-admin-server</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-boot-admin-server</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<spring-boot-admin-server.version>1.5.4</spring-boot-admin-server.version>
|
||||||
|
<spring-boot-admin-starter-client.version>1.5.4</spring-boot-admin-starter-client.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- dependencies used to enable admin server and UI-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-server</artifactId>
|
||||||
|
<version>${spring-boot-admin-server.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-server-ui</artifactId>
|
||||||
|
<version>${spring-boot-admin-server.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--Add login page and logout feature-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-server-ui-login</artifactId>
|
||||||
|
<version>${spring-boot-admin-server.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.hazelcast</groupId>
|
||||||
|
<artifactId>hazelcast</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!--declare the admin server as a client, for self monitoring-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.codecentric</groupId>
|
||||||
|
<artifactId>spring-boot-admin-starter-client</artifactId>
|
||||||
|
<version>${spring-boot-admin-starter-client.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!--mail notifications-->
|
||||||
|
<!--<dependency>-->
|
||||||
|
<!--<groupId>org.springframework.boot</groupId>-->
|
||||||
|
<!--<artifactId>spring-boot-starter-mail</artifactId>-->
|
||||||
|
<!--</dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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=<generated_token>
|
||||||
|
#spring.boot.admin.notify.hipchat.room-id=<room-id>
|
||||||
|
#spring.boot.admin.notify.hipchat.url=https://youcompany.hipchat.com/v2/
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<jmxConfigurator />
|
||||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%date [%thread] %-5level %logger{25} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="CONSOLE"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.baeldung.di.spring;
|
||||||
|
|
||||||
|
public interface IService {
|
||||||
|
public String serve();
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.di.spring;
|
||||||
|
|
||||||
|
public class IndexService implements IService {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serve() {
|
||||||
|
return "Hello World";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
message.value=Hello World
|
43
spring-core/src/main/resources/com.baeldung.di.spring.xml
Normal file
43
spring-core/src/main/resources/com.baeldung.di.spring.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||||
|
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
|
||||||
|
|
||||||
|
<bean id="indexService" class="com.baeldung.di.spring.IndexService" />
|
||||||
|
|
||||||
|
<bean id="messageService" class="com.baeldung.di.spring.MessageService" scope="prototype">
|
||||||
|
<constructor-arg value="${message.value}" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||||
|
<property name="location" value="com.baeldung.di.spring.properties" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="messageServiceFromStaticFactory" class="com.baeldung.di.spring.StaticServiceFactory"
|
||||||
|
factory-method="getService">
|
||||||
|
<constructor-arg value="1" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="indexServiceFactory" class="com.baeldung.di.spring.InstanceServiceFactory" />
|
||||||
|
|
||||||
|
<bean id="messageServiceFromInstanceFactory" class="com.baeldung.di.spring.InstanceServiceFactory"
|
||||||
|
factory-method="getService" factory-bean="indexServiceFactory">
|
||||||
|
<constructor-arg value="1" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="indexApp" class="com.baeldung.di.spring.IndexApp">
|
||||||
|
<property name="service" ref="indexService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="indexAppWithStaticFactory" class="com.baeldung.di.spring.IndexApp" scope="prototype">
|
||||||
|
<property name="service" ref="messageServiceFromStaticFactory" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="indexAppWithFactoryMethod" class="com.baeldung.di.spring.IndexApp" scope="prototype">
|
||||||
|
<property name="service" ref="messageServiceFromInstanceFactory" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="messageWorldApp" class="com.baeldung.di.spring.MessageApp" scope="prototype">
|
||||||
|
<constructor-arg ref="messageService" />
|
||||||
|
</bean>
|
||||||
|
</beans>
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
5
spring-rest-shell/README.md
Normal file
5
spring-rest-shell/README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## Spring REST Shell Project
|
||||||
|
|
||||||
|
### Relevant Articles
|
||||||
|
|
||||||
|
- [Spring REST Shell](http://www.baeldung.com/<ARTICLE_URI>)
|
60
spring-rest-shell/pom.xml
Normal file
60
spring-rest-shell/pom.xml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>spring-rest-shell</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>spring-rest-shell</name>
|
||||||
|
<description>A simple project to demonstrate Spring REST Shell features.</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spring dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- H2 dependency -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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<Article, Long> {
|
||||||
|
|
||||||
|
Optional<Article> findByTitle(@Param("title") String title);
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user