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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.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();
|
||||
|
@ -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 {
|
||||
|
||||
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";
|
||||
|
@ -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.PrintWriter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.EJB;
|
||||
@ -20,14 +21,27 @@ public class TestEJBServlet extends HttpServlet {
|
||||
@EJB
|
||||
private UserBeanLocal userBean;
|
||||
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
List<User> users = userBean.getUsers();
|
||||
|
||||
response.getWriter()
|
||||
.append("The number of users is: " + users.size());
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
out.println("<html>");
|
||||
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 {
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.forketyfork.guest</groupId>
|
||||
<groupId>com.stackify.guest</groupId>
|
||||
<artifactId>spring-mvc</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<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.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) {
|
@ -1,4 +1,4 @@
|
||||
package com.forketyfork.guest.springmvc.model;
|
||||
package com.stackify.guest.springmvc.model;
|
||||
|
||||
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.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
|
@ -1,4 +1,4 @@
|
||||
package com.forketyfork.guest.springmvc.web;
|
||||
package com.stackify.guest.springmvc.web;
|
||||
|
||||
public class MyInputResource {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.forketyfork.guest.springmvc.web;
|
||||
package com.stackify.guest.springmvc.web;
|
||||
|
||||
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.RestController;
|
@ -1 +1,3 @@
|
||||
## 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"));
|
||||
|
||||
// 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<>();
|
||||
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