Merge branch 'master' into BAEL-3951
This commit is contained in:
commit
542852f569
|
@ -0,0 +1,56 @@
|
|||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.6.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>aws-app-sync</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>aws-app-sync</name>
|
||||
|
||||
<description>Spring Boot using AWS App Sync</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.junit.vintage</groupId>
|
||||
<artifactId>junit-vintage-engine</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
public class AppSyncClientHelper {
|
||||
|
||||
static String apiUrl = "https://m4i3b6icrrb7livfbypfspiifi.appsync-api.us-east-2.amazonaws.com";
|
||||
static String apiKey = "da2-bm4rpatkkrc5jfyhvvq7itjeke";
|
||||
static String API_KEY_HEADER = "x-api-key";
|
||||
|
||||
public static WebClient.ResponseSpec getResponseBodySpec(Map<String, Object> requestBody) {
|
||||
return WebClient
|
||||
.builder()
|
||||
.baseUrl(apiUrl)
|
||||
.defaultHeader(API_KEY_HEADER, apiKey)
|
||||
.defaultHeader("Content-Type", "application/json")
|
||||
.build()
|
||||
.method(HttpMethod.POST)
|
||||
.uri("/graphql")
|
||||
.body(BodyInserters.fromValue(requestBody))
|
||||
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
|
||||
.acceptCharset(StandardCharsets.UTF_8)
|
||||
.retrieve();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AwsAppSyncApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AwsAppSyncApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.baeldung.awsappsync;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SpringBootTest
|
||||
class AwsAppSyncApplicationTests {
|
||||
|
||||
@Test
|
||||
void givenGraphQuery_whenListEvents_thenReturnAllEvents() {
|
||||
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("query", "query ListEvents {"
|
||||
+ " listEvents {"
|
||||
+ " items {"
|
||||
+ " id"
|
||||
+ " name"
|
||||
+ " where"
|
||||
+ " when"
|
||||
+ " description"
|
||||
+ " }"
|
||||
+ " }"
|
||||
+ "}");
|
||||
requestBody.put("variables", "");
|
||||
requestBody.put("operationName", "ListEvents");
|
||||
|
||||
String bodyString = AppSyncClientHelper.getResponseBodySpec(requestBody)
|
||||
.bodyToMono(String.class).block();
|
||||
|
||||
assertNotNull(bodyString);
|
||||
assertTrue(bodyString.contains("My First Event"));
|
||||
assertTrue(bodyString.contains("where"));
|
||||
assertTrue(bodyString.contains("when"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGraphAdd_whenMutation_thenReturnIdNameDesc() {
|
||||
|
||||
String queryString = "mutation add {"
|
||||
+ " createEvent("
|
||||
+ " name:\"My added GraphQL event\""
|
||||
+ " where:\"Day 2\""
|
||||
+ " when:\"Saturday night\""
|
||||
+ " description:\"Studying GraphQL\""
|
||||
+ " ){"
|
||||
+ " id"
|
||||
+ " name"
|
||||
+ " description"
|
||||
+ " }"
|
||||
+ "}";
|
||||
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("query", queryString);
|
||||
requestBody.put("variables", "");
|
||||
requestBody.put("operationName", "add");
|
||||
|
||||
WebClient.ResponseSpec response = AppSyncClientHelper.getResponseBodySpec(requestBody);
|
||||
|
||||
String bodyString = response.bodyToMono(String.class).block();
|
||||
|
||||
assertNotNull(bodyString);
|
||||
assertTrue(bodyString.contains("My added GraphQL event"));
|
||||
assertFalse(bodyString.contains("where"));
|
||||
assertFalse(bodyString.contains("when"));
|
||||
}
|
||||
}
|
|
@ -1,22 +1,22 @@
|
|||
package com.baeldung.java14.record;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public record Person (String name, String address) {
|
||||
|
||||
public static String UNKNOWN_ADDRESS = "Unknown";
|
||||
public static String UNNAMED = "Unnamed";
|
||||
|
||||
public Person {
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(address);
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this(name, UNKNOWN_ADDRESS);
|
||||
}
|
||||
|
||||
public static Person unnamed(String address) {
|
||||
return new Person(UNNAMED, address);
|
||||
}
|
||||
}
|
||||
package com.baeldung.java14.record;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public record Person (String name, String address) {
|
||||
|
||||
public static String UNKNOWN_ADDRESS = "Unknown";
|
||||
public static String UNNAMED = "Unnamed";
|
||||
|
||||
public Person {
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(address);
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this(name, UNKNOWN_ADDRESS);
|
||||
}
|
||||
|
||||
public static Person unnamed(String address) {
|
||||
return new Person(UNNAMED, address);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.baeldung.java14.foreign.api;
|
||||
|
||||
import jdk.incubator.foreign.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class ForeignMemoryUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenAValueIsSet_thenAccessTheValue() {
|
||||
long value = 10;
|
||||
MemoryAddress memoryAddress =
|
||||
MemorySegment.allocateNative(8).baseAddress();
|
||||
VarHandle varHandle = MemoryHandles.varHandle(long.class,
|
||||
ByteOrder.nativeOrder());
|
||||
varHandle.set(memoryAddress, value);
|
||||
assertThat(varHandle.get(memoryAddress), is(value));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMultipleValuesAreSet_thenAccessAll() {
|
||||
VarHandle varHandle = MemoryHandles.varHandle(int.class,
|
||||
ByteOrder.nativeOrder());
|
||||
|
||||
try(MemorySegment memorySegment =
|
||||
MemorySegment.allocateNative(100)) {
|
||||
MemoryAddress base = memorySegment.baseAddress();
|
||||
for(int i=0; i<25; i++) {
|
||||
varHandle.set(base.addOffset((i*4)), i);
|
||||
}
|
||||
for(int i=0; i<25; i++) {
|
||||
assertThat(varHandle.get(base.addOffset((i*4))), is(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSetValuesWithMemoryLayout_thenTheyCanBeRetrieved() {
|
||||
SequenceLayout sequenceLayout =
|
||||
MemoryLayout.ofSequence(25,
|
||||
MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder()));
|
||||
VarHandle varHandle =
|
||||
sequenceLayout.varHandle(long.class,
|
||||
MemoryLayout.PathElement.sequenceElement());
|
||||
|
||||
try(MemorySegment memorySegment =
|
||||
MemorySegment.allocateNative(sequenceLayout)) {
|
||||
MemoryAddress base = memorySegment.baseAddress();
|
||||
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||
varHandle.set(base, i, i);
|
||||
}
|
||||
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||
assertThat(varHandle.get(base, i), is(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSlicingMemorySegment_thenTheyCanBeAccessedIndividually() {
|
||||
MemoryAddress memoryAddress =
|
||||
MemorySegment.allocateNative(12).baseAddress();
|
||||
MemoryAddress memoryAddress1 =
|
||||
memoryAddress.segment().asSlice(0,4).baseAddress();
|
||||
MemoryAddress memoryAddress2 =
|
||||
memoryAddress.segment().asSlice(4,4).baseAddress();
|
||||
MemoryAddress memoryAddress3 =
|
||||
memoryAddress.segment().asSlice(8,4).baseAddress();
|
||||
|
||||
VarHandle intHandle =
|
||||
MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
|
||||
intHandle.set(memoryAddress1, Integer.MIN_VALUE);
|
||||
intHandle.set(memoryAddress2, 0);
|
||||
intHandle.set(memoryAddress3, Integer.MAX_VALUE);
|
||||
|
||||
assertThat(intHandle.get(memoryAddress1), is(Integer.MIN_VALUE));
|
||||
assertThat(intHandle.get(memoryAddress2), is(0));
|
||||
assertThat(intHandle.get(memoryAddress3), is(Integer.MAX_VALUE));
|
||||
}
|
||||
}
|
|
@ -1,150 +1,150 @@
|
|||
package com.baeldung.java14.record;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PersonTest {
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertTrue(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenEquals_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertFalse(person.equals(new Object()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenHashCode_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertNotEquals(person.hashCode(), new Object().hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullName_whenConstruct_thenErrorThrown() {
|
||||
new Person(null, "100 Linda Ln.");
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullAddress_whenConstruct_thenErrorThrown() {
|
||||
new Person("John Doe", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnknownAddress_whenConstructing_thenAddressPopulated() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person = new Person(name);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(Person.UNKNOWN_ADDRESS, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = Person.unnamed(address);
|
||||
|
||||
assertEquals(Person.UNNAMED, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
}
|
||||
package com.baeldung.java14.record;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PersonTest {
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertTrue(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenEquals_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertFalse(person.equals(new Object()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertFalse(person1.equals(person2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person(name, address);
|
||||
Person person2 = new Person(name, address);
|
||||
|
||||
assertEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentObject_whenHashCode_thenNotEqual() {
|
||||
|
||||
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||
|
||||
assertNotEquals(person.hashCode(), new Object().hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentName_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person1 = new Person("Jane Doe", address);
|
||||
Person person2 = new Person("John Doe", address);
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person1 = new Person(name, "100 Linda Ln.");
|
||||
Person person2 = new Person(name, "200 London Ave.");
|
||||
|
||||
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() {
|
||||
|
||||
String name = "John Doe";
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = new Person(name, address);
|
||||
|
||||
assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullName_whenConstruct_thenErrorThrown() {
|
||||
new Person(null, "100 Linda Ln.");
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void givenNullAddress_whenConstruct_thenErrorThrown() {
|
||||
new Person("John Doe", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnknownAddress_whenConstructing_thenAddressPopulated() {
|
||||
|
||||
String name = "John Doe";
|
||||
|
||||
Person person = new Person(name);
|
||||
|
||||
assertEquals(name, person.name());
|
||||
assertEquals(Person.UNKNOWN_ADDRESS, person.address());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() {
|
||||
|
||||
String address = "100 Linda Ln.";
|
||||
|
||||
Person person = Person.unnamed(address);
|
||||
|
||||
assertEquals(Person.UNNAMED, person.name());
|
||||
assertEquals(address, person.address());
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import org.apache.commons.collections4.MapUtils;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConvertListToMapService {
|
||||
|
@ -21,7 +22,7 @@ public class ConvertListToMapService {
|
|||
}
|
||||
|
||||
public Map<Integer, Animal> convertListAfterJava8(List<Animal> list) {
|
||||
Map<Integer, Animal> map = list.stream().collect(Collectors.toMap(Animal::getId, animal -> animal));
|
||||
Map<Integer, Animal> map = list.stream().collect(Collectors.toMap(Animal::getId, Function.identity()));
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,14 +53,14 @@ public class CollectionToArrayListUnitTest {
|
|||
|
||||
verifyShallowCopy(srcCollection, newList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Section 5. Deep Copy
|
||||
*/
|
||||
@Test
|
||||
public void whenUsingDeepCopy_thenVerifyDeepCopy() {
|
||||
ArrayList<Foo> newList = srcCollection.stream()
|
||||
.map(foo -> foo.deepCopy())
|
||||
.map(Foo::deepCopy)
|
||||
.collect(toCollection(ArrayList::new));
|
||||
|
||||
verifyDeepCopy(srcCollection, newList);
|
||||
|
@ -83,13 +83,13 @@ public class CollectionToArrayListUnitTest {
|
|||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
private void verifyShallowCopy(Collection a, Collection b) {
|
||||
private void verifyShallowCopy(Collection<Foo> a, Collection<Foo> b) {
|
||||
assertEquals("Collections have different lengths", a.size(), b.size());
|
||||
Iterator<Foo> iterA = a.iterator();
|
||||
Iterator<Foo> iterB = b.iterator();
|
||||
while (iterA.hasNext()) {
|
||||
// use '==' to test instance identity
|
||||
assertTrue("Foo instances differ!", iterA.next() == iterB.next());
|
||||
assertSame("Foo instances differ!", iterA.next(), iterB.next());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class CollectionToArrayListUnitTest {
|
|||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
private void verifyDeepCopy(Collection a, Collection b) {
|
||||
private void verifyDeepCopy(Collection<Foo> a, Collection<Foo> b) {
|
||||
assertEquals("Collections have different lengths", a.size(), b.size());
|
||||
Iterator<Foo> iterA = a.iterator();
|
||||
Iterator<Foo> iterB = b.iterator();
|
||||
|
@ -106,7 +106,7 @@ public class CollectionToArrayListUnitTest {
|
|||
Foo nextA = iterA.next();
|
||||
Foo nextB = iterB.next();
|
||||
// should not be same instance
|
||||
assertFalse("Foo instances are the same!", nextA == nextB);
|
||||
assertNotSame("Foo instances are the same!", nextA, nextB);
|
||||
// but should have same content
|
||||
assertFalse("Foo instances have different content!", fooDiff(nextA, nextB));
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
|||
Iterator<Integer> iterator;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setUp() {
|
||||
iterator = Arrays.asList(1, 2, 3)
|
||||
.iterator();
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
|||
@Test
|
||||
public void givenAnIterator_whenConvertIteratorToListUsingWhileLoop_thenReturnAList() {
|
||||
|
||||
List<Integer> actualList = new ArrayList<Integer>();
|
||||
List<Integer> actualList = new ArrayList<>();
|
||||
|
||||
// Convert Iterator to List using while loop dsf
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -44,7 +44,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
|||
|
||||
@Test
|
||||
public void givenAnIterator_whenConvertIteratorToListAfterJava8_thenReturnAList() {
|
||||
List<Integer> actualList = new ArrayList<Integer>();
|
||||
List<Integer> actualList = new ArrayList<>();
|
||||
|
||||
// Convert Iterator to List using Java 8
|
||||
iterator.forEachRemaining(actualList::add);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
## Java Python Interop
|
||||
|
||||
This module contains articles about Java and Python interoperability.
|
||||
|
||||
### Relevant Articles:
|
|
@ -0,0 +1,55 @@
|
|||
<?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>
|
||||
<artifactId>java-python-interop</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>java-python-interop</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.python</groupId>
|
||||
<artifactId>jython-slim</artifactId>
|
||||
<version>${jython.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-exec</artifactId>
|
||||
<version>${commons-exec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>java-python-interop</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/test/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jython.version>2.7.2</jython.version>
|
||||
<commons-exec.version>1.3</commons-exec.version>
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.python.interop;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
|
||||
public class ScriptEngineManagerUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptEngineManagerUtils.class);
|
||||
|
||||
private ScriptEngineManagerUtils() {
|
||||
}
|
||||
|
||||
public static void listEngines() {
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
List<ScriptEngineFactory> engines = manager.getEngineFactories();
|
||||
|
||||
for (ScriptEngineFactory engine : engines) {
|
||||
LOGGER.info("Engine name: {}", engine.getEngineName());
|
||||
LOGGER.info("Version: {}", engine.getEngineVersion());
|
||||
LOGGER.info("Language: {}", engine.getLanguageName());
|
||||
|
||||
LOGGER.info("Short Names:");
|
||||
for (String names : engine.getNames()) {
|
||||
LOGGER.info(names);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,131 @@
|
|||
package com.baeldung.python.interop;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteException;
|
||||
import org.apache.commons.exec.PumpStreamHandler;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.python.core.PyException;
|
||||
import org.python.core.PyObject;
|
||||
import org.python.util.PythonInterpreter;
|
||||
|
||||
public class JavaPythonInteropUnitTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void givenPythonScript_whenPythonProcessInvoked_thenSuccess() throws Exception {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("python", resolvePythonScriptPath("hello.py"));
|
||||
processBuilder.redirectErrorStream(true);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
List<String> results = readProcessOutput(process.getInputStream());
|
||||
|
||||
assertThat("Results should not be empty", results, is(not(empty())));
|
||||
assertThat("Results should contain output of script: ", results, hasItem(containsString("Hello Baeldung Readers!!")));
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPythonScriptEngineIsAvailable_whenScriptInvoked_thenOutputDisplayed() throws Exception {
|
||||
StringWriter output = new StringWriter();
|
||||
ScriptContext context = new SimpleScriptContext();
|
||||
context.setWriter(output);
|
||||
|
||||
ScriptEngineManager manager = new ScriptEngineManager();
|
||||
ScriptEngine engine = manager.getEngineByName("python");
|
||||
engine.eval(new FileReader(resolvePythonScriptPath("hello.py")), context);
|
||||
assertEquals("Should contain script output: ", "Hello Baeldung Readers!!", output.toString()
|
||||
.trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPythonInterpreter_whenPrintExecuted_thenOutputDisplayed() {
|
||||
try (PythonInterpreter pyInterp = new PythonInterpreter()) {
|
||||
StringWriter output = new StringWriter();
|
||||
pyInterp.setOut(output);
|
||||
|
||||
pyInterp.exec("print('Hello Baeldung Readers!!')");
|
||||
assertEquals("Should contain script output: ", "Hello Baeldung Readers!!", output.toString()
|
||||
.trim());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPythonInterpreter_whenNumbersAdded_thenOutputDisplayed() {
|
||||
try (PythonInterpreter pyInterp = new PythonInterpreter()) {
|
||||
pyInterp.exec("x = 10+10");
|
||||
PyObject x = pyInterp.get("x");
|
||||
assertEquals("x: ", 20, x.asInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPythonInterpreter_whenErrorOccurs_thenExceptionIsThrown() {
|
||||
thrown.expect(PyException.class);
|
||||
thrown.expectMessage("ImportError: No module named syds");
|
||||
|
||||
try (PythonInterpreter pyInterp = new PythonInterpreter()) {
|
||||
pyInterp.exec("import syds");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPythonScript_whenPythonProcessExecuted_thenSuccess() throws ExecuteException, IOException {
|
||||
String line = "python " + resolvePythonScriptPath("hello.py");
|
||||
CommandLine cmdLine = CommandLine.parse(line);
|
||||
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
|
||||
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler(streamHandler);
|
||||
|
||||
int exitCode = executor.execute(cmdLine);
|
||||
assertEquals("No errors should be detected", 0, exitCode);
|
||||
assertEquals("Should contain script output: ", "Hello Baeldung Readers!!", outputStream.toString()
|
||||
.trim());
|
||||
}
|
||||
|
||||
private List<String> readProcessOutput(InputStream inputStream) throws IOException {
|
||||
try (BufferedReader output = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
return output.lines()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
private String resolvePythonScriptPath(String filename) {
|
||||
File file = new File("src/test/resources/" + filename);
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
print("Hello Baeldung Readers!!")
|
|
@ -0,0 +1,35 @@
|
|||
<?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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>libraries-rpc</artifactId>
|
||||
<name>libraries-rpc</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-core_2.13</artifactId>
|
||||
<version>${finagle.core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twitter</groupId>
|
||||
<artifactId>finagle-http_2.13</artifactId>
|
||||
<version>${finagle.http.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<finagle.core.version>20.4.0</finagle.core.version>
|
||||
<finagle.http.version>20.4.0</finagle.http.version>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.rpc.finagle;
|
||||
|
||||
import com.twitter.finagle.Service;
|
||||
import com.twitter.finagle.http.Request;
|
||||
import com.twitter.finagle.http.Response;
|
||||
import com.twitter.finagle.http.Status;
|
||||
import com.twitter.io.Buf;
|
||||
import com.twitter.io.Reader;
|
||||
import com.twitter.util.Future;
|
||||
|
||||
public class GreetingService extends Service<Request, Response> {
|
||||
@Override
|
||||
public Future<Response> apply(Request request) {
|
||||
String greeting = "Hello " + request.getParam("name");
|
||||
Reader<Buf> reader = Reader.fromBuf(new Buf.ByteArray(greeting.getBytes(), 0, greeting.length()));
|
||||
return Future.value(Response.apply(request.version(), Status.Ok(), reader));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.rpc.finagle;
|
||||
|
||||
import com.twitter.finagle.Service;
|
||||
import com.twitter.finagle.SimpleFilter;
|
||||
import com.twitter.finagle.http.Request;
|
||||
import com.twitter.finagle.http.Response;
|
||||
import com.twitter.util.Future;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LogFilter extends SimpleFilter<Request, Response> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LogFilter.class);
|
||||
|
||||
@Override
|
||||
public Future<Response> apply(Request request, Service<Request, Response> service) {
|
||||
logger.info("Request host:" + request.host().getOrElse(() -> ""));
|
||||
logger.info("Request params:");
|
||||
request.getParams().forEach(entry -> logger.info("\t" + entry.getKey() + " : " + entry.getValue()));
|
||||
return service.apply(request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.rpc.finagle;
|
||||
|
||||
import com.twitter.finagle.Http;
|
||||
import com.twitter.finagle.Service;
|
||||
import com.twitter.finagle.http.Method;
|
||||
import com.twitter.finagle.http.Request;
|
||||
import com.twitter.finagle.http.Response;
|
||||
import com.twitter.util.Await;
|
||||
import com.twitter.util.Future;
|
||||
import org.junit.Test;
|
||||
import scala.runtime.BoxedUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FinagleIntegrationTest {
|
||||
@Test
|
||||
public void givenServerAndClient_whenRequestSent_thenClientShouldReceiveResponseFromServer() throws Exception {
|
||||
// given
|
||||
Service serverService = new LogFilter().andThen(new GreetingService());
|
||||
Http.serve(":8080", serverService);
|
||||
|
||||
Service<Request, Response> clientService = new LogFilter().andThen(Http.newService(":8080"));
|
||||
|
||||
// when
|
||||
Request request = Request.apply(Method.Get(), "/?name=John");
|
||||
request.host("localhost");
|
||||
Future<Response> response = clientService.apply(request);
|
||||
|
||||
// then
|
||||
Await.result(response
|
||||
.onSuccess(r -> {
|
||||
assertEquals("Hello John", r.getContentString());
|
||||
return BoxedUnit.UNIT;
|
||||
})
|
||||
.onFailure(r -> {
|
||||
throw new RuntimeException(r);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.logging.log4j2.plugins;
|
||||
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.pattern.ConverterKeys;
|
||||
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
|
||||
import org.apache.logging.log4j.core.pattern.PatternConverter;
|
||||
|
||||
@Plugin(name = "DockerPatternConverter", category = PatternConverter.CATEGORY)
|
||||
@ConverterKeys({"docker", "container"})
|
||||
public class DockerPatternConverter extends LogEventPatternConverter {
|
||||
|
||||
private DockerPatternConverter(String[] options) {
|
||||
super("Docker", "docker");
|
||||
}
|
||||
|
||||
public static DockerPatternConverter newInstance(String[] options) {
|
||||
return new DockerPatternConverter(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void format(LogEvent event, StringBuilder toAppendTo) {
|
||||
toAppendTo.append(dockerContainer());
|
||||
}
|
||||
|
||||
private String dockerContainer() {
|
||||
//get docker container ID inside which application is running here
|
||||
return "container-1";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package com.baeldung.logging.log4j2.plugins;
|
||||
|
||||
import org.apache.logging.log4j.core.Core;
|
||||
import org.apache.logging.log4j.core.Filter;
|
||||
import org.apache.logging.log4j.core.Layout;
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Plugin(name = "Kafka2", category = Core.CATEGORY_NAME)
|
||||
public class KafkaAppender extends AbstractAppender {
|
||||
|
||||
@PluginBuilderFactory
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder implements org.apache.logging.log4j.core.util.Builder<KafkaAppender> {
|
||||
|
||||
@PluginBuilderAttribute("name")
|
||||
@Required
|
||||
private String name;
|
||||
|
||||
@PluginBuilderAttribute("ip")
|
||||
private String ipAddress;
|
||||
|
||||
@PluginBuilderAttribute("port")
|
||||
private int port;
|
||||
|
||||
@PluginBuilderAttribute("topic")
|
||||
private String topic;
|
||||
|
||||
@PluginBuilderAttribute("partition")
|
||||
private String partition;
|
||||
|
||||
@PluginElement("Layout")
|
||||
private Layout<? extends Serializable> layout;
|
||||
|
||||
@PluginElement("Filter")
|
||||
private Filter filter;
|
||||
|
||||
public Layout<? extends Serializable> getLayout() {
|
||||
return layout;
|
||||
}
|
||||
|
||||
public Builder setLayout(Layout<? extends Serializable> layout) {
|
||||
this.layout = layout;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Builder setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setFilter(Filter filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public Builder setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public Builder setPort(int port) {
|
||||
this.port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTopic() {
|
||||
return topic;
|
||||
}
|
||||
|
||||
public Builder setTopic(String topic) {
|
||||
this.topic = topic;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPartition() {
|
||||
return partition;
|
||||
}
|
||||
|
||||
public Builder setPartition(String partition) {
|
||||
this.partition = partition;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KafkaAppender build() {
|
||||
return new KafkaAppender(getName(), getFilter(), getLayout(), true, new KafkaBroker(ipAddress, port, topic, partition));
|
||||
}
|
||||
}
|
||||
|
||||
private KafkaBroker broker;
|
||||
|
||||
private KafkaAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, KafkaBroker broker) {
|
||||
super(name, filter, layout, ignoreExceptions);
|
||||
this.broker = broker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(LogEvent event) {
|
||||
|
||||
connectAndSendToKafka(broker, event);
|
||||
}
|
||||
|
||||
private void connectAndSendToKafka(KafkaBroker broker, LogEvent event) {
|
||||
//send to Kafka
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.logging.log4j2.plugins;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class KafkaBroker implements Serializable {
|
||||
|
||||
private final String ipAddress;
|
||||
private final int port;
|
||||
|
||||
public KafkaBroker(String ipAddress, int port, String topic, String partition) {
|
||||
this.ipAddress = ipAddress;
|
||||
this.port = port;
|
||||
this.topic = topic;
|
||||
this.partition = partition;
|
||||
}
|
||||
|
||||
public String getTopic() {
|
||||
return topic;
|
||||
}
|
||||
|
||||
public String getPartition() {
|
||||
return partition;
|
||||
}
|
||||
|
||||
private final String topic;
|
||||
private final String partition;
|
||||
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.logging.log4j2.plugins;
|
||||
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.lookup.StrLookup;
|
||||
|
||||
@Plugin(name = "kafka", category = StrLookup.CATEGORY)
|
||||
public class KafkaLookup implements StrLookup {
|
||||
|
||||
@Override
|
||||
public String lookup(String key) {
|
||||
return getFromKafka(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookup(LogEvent event, String key) {
|
||||
return getFromKafka(key);
|
||||
}
|
||||
|
||||
private String getFromKafka(String topicName) {
|
||||
//kafka search logic should go here
|
||||
return "topic1-p1";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package com.baeldung.logging.log4j2.plugins;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.Appender;
|
||||
import org.apache.logging.log4j.core.Core;
|
||||
import org.apache.logging.log4j.core.Filter;
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.synchronizedList;
|
||||
|
||||
@Plugin(name = "ListAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
|
||||
public class ListAppender extends AbstractAppender {
|
||||
|
||||
private List<LogEvent> logList;
|
||||
|
||||
protected ListAppender(String name, Filter filter) {
|
||||
super(name, filter, null);
|
||||
logList = synchronizedList(new ArrayList<>());
|
||||
}
|
||||
|
||||
@PluginFactory
|
||||
public static ListAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filter") final Filter filter) {
|
||||
return new ListAppender(name, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(LogEvent event) {
|
||||
if (event.getLevel()
|
||||
.isLessSpecificThan(Level.WARN)) {
|
||||
error("Unable to log less than WARN level.");
|
||||
return;
|
||||
}
|
||||
logList.add(event);
|
||||
}
|
||||
|
||||
}
|
|
@ -50,6 +50,12 @@
|
|||
</Policies>
|
||||
</RollingFile>
|
||||
<MapAppender name="MapAppender"/>
|
||||
<Console name="DockerConsoleLogger" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%pid %docker" />
|
||||
</Console>
|
||||
<Kafka2 name="KafkaLogger" ip ="127.0.0.1" port="9010" topic="log" partition="p-1">
|
||||
<PatternLayout pattern="%pid%style{%message}{red}%n" />
|
||||
</Kafka2>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE"
|
||||
|
@ -80,6 +86,9 @@
|
|||
additivity="false">
|
||||
<AppenderRef ref="ConsoleJSONAppender" />
|
||||
</Logger>
|
||||
<Logger name="com.baeldung.logging.log4j2.plugins" level="INFO">
|
||||
<AppenderRef ref="KafkaLogger" />
|
||||
</Logger>
|
||||
<Root level="DEBUG">
|
||||
<AppenderRef ref="ConsoleAppender" />
|
||||
<AppenderRef ref="MapAppender" />
|
||||
|
|
10
pdf/pom.xml
10
pdf/pom.xml
|
@ -60,6 +60,16 @@
|
|||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi-ooxml.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>3.0.11.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xhtmlrenderer</groupId>
|
||||
<artifactId>flying-saucer-pdf</artifactId>
|
||||
<version>9.1.20</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung.pdf;
|
||||
|
||||
import com.lowagie.text.DocumentException;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.xhtmlrenderer.pdf.ITextRenderer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class PDFThymeleafExample {
|
||||
|
||||
public static void main(String[] args) throws IOException, DocumentException {
|
||||
PDFThymeleafExample thymeleaf2Pdf = new PDFThymeleafExample();
|
||||
String html = thymeleaf2Pdf.parseThymeleafTemplate();
|
||||
thymeleaf2Pdf.generatePdfFromHtml(html);
|
||||
}
|
||||
|
||||
public void generatePdfFromHtml(String html) throws IOException, DocumentException {
|
||||
String outputFolder = System.getProperty("user.home") + File.separator + "thymeleaf.pdf";
|
||||
OutputStream outputStream = new FileOutputStream(outputFolder);
|
||||
|
||||
ITextRenderer renderer = new ITextRenderer();
|
||||
renderer.setDocumentFromString(html);
|
||||
renderer.layout();
|
||||
renderer.createPDF(outputStream);
|
||||
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
private String parseThymeleafTemplate() {
|
||||
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
|
||||
templateResolver.setSuffix(".html");
|
||||
templateResolver.setTemplateMode(TemplateMode.HTML);
|
||||
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
templateEngine.setTemplateResolver(templateResolver);
|
||||
|
||||
Context context = new Context();
|
||||
context.setVariable("to", "Baeldung.com");
|
||||
|
||||
return templateEngine.process("thymeleaf_template", context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||
<body>
|
||||
<h3 style="text-align: center; color: green">
|
||||
<span th:text="'Welcome to ' + ${to} + '!'"></span>
|
||||
</h3>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.pdf;
|
||||
|
||||
import com.lowagie.text.DocumentException;
|
||||
import org.junit.Test;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.xhtmlrenderer.pdf.ITextRenderer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class PDFThymeleafUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenThymeleafTemplate_whenParsedAndRenderedToPDF_thenItShouldNotBeEmpty() throws DocumentException, IOException {
|
||||
String html = parseThymeleafTemplate();
|
||||
|
||||
ByteArrayOutputStream outputStream = generatePdfOutputStreamFromHtml(html);
|
||||
|
||||
assertTrue(outputStream.size() > 0);
|
||||
}
|
||||
|
||||
private ByteArrayOutputStream generatePdfOutputStreamFromHtml(String html) throws IOException, DocumentException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
ITextRenderer renderer = new ITextRenderer();
|
||||
renderer.setDocumentFromString(html);
|
||||
renderer.layout();
|
||||
renderer.createPDF(outputStream);
|
||||
|
||||
outputStream.close();
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
private String parseThymeleafTemplate() {
|
||||
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
|
||||
templateResolver.setSuffix(".html");
|
||||
templateResolver.setTemplateMode(TemplateMode.HTML);
|
||||
|
||||
TemplateEngine templateEngine = new TemplateEngine();
|
||||
templateEngine.setTemplateResolver(templateResolver);
|
||||
|
||||
Context context = new Context();
|
||||
context.setVariable("to", "Baeldung.com");
|
||||
|
||||
return templateEngine.process("thymeleaf_template", context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package com.baeldung.bsontojson;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import dev.morphia.annotations.Embedded;
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Field;
|
||||
import dev.morphia.annotations.Id;
|
||||
import dev.morphia.annotations.Index;
|
||||
import dev.morphia.annotations.IndexOptions;
|
||||
import dev.morphia.annotations.Indexes;
|
||||
import dev.morphia.annotations.Property;
|
||||
import dev.morphia.annotations.Reference;
|
||||
import dev.morphia.annotations.Validation;
|
||||
|
||||
@Entity("Books")
|
||||
@Indexes({ @Index(fields = @Field("title"), options = @IndexOptions(name = "book_title")) })
|
||||
@Validation("{ price : { $gt : 0 } }")
|
||||
public class Book {
|
||||
@Id
|
||||
private String isbn;
|
||||
@Property
|
||||
private String title;
|
||||
private String author;
|
||||
@Embedded
|
||||
private Publisher publisher;
|
||||
@Property("price")
|
||||
private double cost;
|
||||
@Reference
|
||||
private Set<Book> companionBooks;
|
||||
@Property
|
||||
private LocalDateTime publishDate;
|
||||
|
||||
public Book() {
|
||||
|
||||
}
|
||||
|
||||
public Book(String isbn, String title, String author, double cost, Publisher publisher) {
|
||||
this.isbn = isbn;
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.cost = cost;
|
||||
this.publisher = publisher;
|
||||
this.companionBooks = new HashSet<>();
|
||||
}
|
||||
|
||||
// Getters and setters ...
|
||||
public String getIsbn() {
|
||||
return isbn;
|
||||
}
|
||||
|
||||
public Book setIsbn(String isbn) {
|
||||
this.isbn = isbn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Book setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Book setAuthor(String author) {
|
||||
this.author = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Publisher getPublisher() {
|
||||
return publisher;
|
||||
}
|
||||
|
||||
public Book setPublisher(Publisher publisher) {
|
||||
this.publisher = publisher;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public Book setCost(double cost) {
|
||||
this.cost = cost;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LocalDateTime getPublishDate() {
|
||||
return publishDate;
|
||||
}
|
||||
|
||||
public Book setPublishDate(LocalDateTime publishDate) {
|
||||
this.publishDate = publishDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<Book> getCompanionBooks() {
|
||||
return companionBooks;
|
||||
}
|
||||
|
||||
public Book addCompanionBooks(Book book) {
|
||||
if (companionBooks != null)
|
||||
this.companionBooks.add(book);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", publisher=" + publisher + ", cost=" + cost + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((author == null) ? 0 : author.hashCode());
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(cost);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
result = prime * result + ((isbn == null) ? 0 : isbn.hashCode());
|
||||
result = prime * result + ((publisher == null) ? 0 : publisher.hashCode());
|
||||
result = prime * result + ((title == null) ? 0 : title.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;
|
||||
Book other = (Book) obj;
|
||||
if (author == null) {
|
||||
if (other.author != null)
|
||||
return false;
|
||||
} else if (!author.equals(other.author))
|
||||
return false;
|
||||
if (Double.doubleToLongBits(cost) != Double.doubleToLongBits(other.cost))
|
||||
return false;
|
||||
if (isbn == null) {
|
||||
if (other.isbn != null)
|
||||
return false;
|
||||
} else if (!isbn.equals(other.isbn))
|
||||
return false;
|
||||
if (publisher == null) {
|
||||
if (other.publisher != null)
|
||||
return false;
|
||||
} else if (!publisher.equals(other.publisher))
|
||||
return false;
|
||||
if (title == null) {
|
||||
if (other.title != null)
|
||||
return false;
|
||||
} else if (!title.equals(other.title))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.bsontojson;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
|
||||
@Entity
|
||||
public class Publisher {
|
||||
|
||||
@Id
|
||||
private ObjectId id;
|
||||
private String name;
|
||||
|
||||
public Publisher() {
|
||||
|
||||
}
|
||||
|
||||
public Publisher(ObjectId id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ObjectId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(ObjectId id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Catalog [id=" + id + ", name=" + name + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Publisher other = (Publisher) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,32 +2,18 @@ package com.baeldung.bsontojson;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bson.json.Converter;
|
||||
import org.bson.json.JsonMode;
|
||||
import org.bson.json.JsonWriterSettings;
|
||||
import org.bson.json.StrictJsonWriter;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.baeldung.morphia.domain.Book;
|
||||
import com.baeldung.morphia.domain.Publisher;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
|
||||
|
@ -42,7 +28,7 @@ public class BsonToJsonLiveTest {
|
|||
@BeforeClass
|
||||
public static void setUp() {
|
||||
Morphia morphia = new Morphia();
|
||||
morphia.mapPackage("com.baeldung.morphia");
|
||||
morphia.mapPackage("com.baeldung.bsontojson");
|
||||
datastore = morphia.createDatastore(new MongoClient(), DB_NAME);
|
||||
datastore.ensureIndexes();
|
||||
|
||||
|
@ -72,7 +58,7 @@ public class BsonToJsonLiveTest {
|
|||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"className\": \"com.baeldung.bsontojson.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
|
@ -100,7 +86,7 @@ public class BsonToJsonLiveTest {
|
|||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"className\": \"com.baeldung.bsontojson.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
|
@ -127,7 +113,7 @@ public class BsonToJsonLiveTest {
|
|||
}
|
||||
|
||||
String expectedJson = "{\"_id\": \"isbn\", " +
|
||||
"\"className\": \"com.baeldung.morphia.domain.Book\", " +
|
||||
"\"className\": \"com.baeldung.bsontojson.Book\", " +
|
||||
"\"title\": \"title\", " +
|
||||
"\"author\": \"author\", " +
|
||||
"\"publisher\": {\"_id\": {\"$oid\": \"fffffffffffffffffffffffa\"}, " +
|
||||
|
|
5
pom.xml
5
pom.xml
|
@ -461,7 +461,8 @@
|
|||
<module>java-lite</module>
|
||||
<module>java-numbers</module>
|
||||
<module>java-numbers-2</module>
|
||||
<module>java-numbers-3</module>
|
||||
<module>java-numbers-3</module>
|
||||
<module>java-python-interop</module>
|
||||
<module>java-rmi</module>
|
||||
<module>java-spi</module>
|
||||
<module>java-vavr-stream</module>
|
||||
|
@ -508,6 +509,7 @@
|
|||
<module>libraries-http-2</module>
|
||||
<module>libraries-io</module>
|
||||
<module>libraries-primitive</module>
|
||||
<module>libraries-rpc</module>
|
||||
<module>libraries-security</module>
|
||||
<module>libraries-server</module>
|
||||
<module>libraries-testing</module>
|
||||
|
@ -896,6 +898,7 @@
|
|||
<module>atomix</module>
|
||||
|
||||
<module>aws</module>
|
||||
<module>aws-app-sync</module>
|
||||
<module>aws-lambda</module>
|
||||
<module>aws-reactive</module>
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"
|
||||
>
|
||||
|
||||
<context:property-placeholder location="classpath:database.properties"/>
|
||||
|
||||
|
||||
<bean id="dataSource" class="com.baeldung.configurationproperties.Database">
|
||||
<property name="url" value="${jdbc.url}" />
|
||||
<property name="username" value="${database.username}" />
|
||||
<property name="password" value="${database.password}" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -7,7 +7,8 @@
|
|||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"
|
||||
>
|
||||
|
||||
<context:property-placeholder location="classpath:foo.properties,classpath:bar.properties, classpath:database.properties"/>
|
||||
|
||||
<context:property-placeholder location="classpath:foo.properties,classpath:bar.properties,classpath:database.properties"/>
|
||||
|
||||
<bean id="componentInXmlUsingProperties" class="com.baeldung.properties.core.ComponentInXmlUsingProperties">
|
||||
<constructor-arg value="${key.something}"/>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
database.url=jdbc:postgresql:/localhost:5432/instance
|
||||
|
||||
jdbc.url=jdbc:postgresql:/localhost:5432
|
||||
database.username=foo
|
||||
database.password=bar
|
||||
jdbc.url=jdbc:postgresql:/localhost:5432
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringJUnitConfig(locations = "classpath:configForProperties.xml")
|
||||
@SpringJUnitConfig(locations = {"classpath:configForProperties.xml", "classpath:configForDbProperties.xml"})
|
||||
public class MultiplePropertiesXmlConfigIntegrationTest {
|
||||
|
||||
@Value("${key.something}") private String something;
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-1</relativePath>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-1</relativePath>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -25,7 +25,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session</artifactId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -36,6 +36,11 @@
|
|||
<artifactId>embedded-redis</artifactId>
|
||||
<version>${embedded-redis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -1,23 +1,31 @@
|
|||
package com.baeldung.spring.session;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication().withUser("admin").password("password").roles("ADMIN");
|
||||
auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("password")).roles("ADMIN");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.httpBasic().and().authorizeRequests().antMatchers("/").hasRole("ADMIN").anyRequest().authenticated();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import org.junit.Before;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-1</artifactId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-1</relativePath>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -42,15 +42,16 @@
|
|||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.social</groupId>
|
||||
<artifactId>spring-social-facebook</artifactId>
|
||||
<version>${spring.social.facebook.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
|
@ -60,6 +61,12 @@
|
|||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>net.bytebuddy</groupId>
|
||||
<artifactId>byte-buddy-dep</artifactId>
|
||||
<version>${bytebuddy.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
|
||||
|
@ -93,5 +100,10 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<bytebuddy.version>1.10.9</bytebuddy.version>
|
||||
<spring.social.facebook.version>2.0.3.RELEASE</spring.social.facebook.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -3,7 +3,7 @@ package com.baeldung.config;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package com.baeldung.config;
|
||||
|
||||
import com.baeldung.security.FacebookSignInAdapter;
|
||||
import com.baeldung.security.FacebookConnectionSignup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -14,22 +13,27 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||
import org.springframework.social.connect.ConnectionFactoryLocator;
|
||||
import org.springframework.social.connect.UsersConnectionRepository;
|
||||
import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository;
|
||||
import org.springframework.social.connect.support.ConnectionFactoryRegistry;
|
||||
import org.springframework.social.connect.web.ProviderSignInController;
|
||||
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
|
||||
|
||||
import com.baeldung.security.FacebookConnectionSignup;
|
||||
import com.baeldung.security.FacebookSignInAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@ComponentScan(basePackages = { "com.baeldung.security" })
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Value("${spring.social.facebook.appSecret}")
|
||||
String appSecret;
|
||||
|
||||
@Value("${spring.social.facebook.appId}")
|
||||
String appId;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private ConnectionFactoryLocator connectionFactoryLocator;
|
||||
|
||||
@Autowired
|
||||
private UsersConnectionRepository usersConnectionRepository;
|
||||
|
||||
@Autowired
|
||||
private FacebookConnectionSignup facebookConnectionSignup;
|
||||
|
||||
|
@ -55,7 +59,19 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||
@Bean
|
||||
// @Primary
|
||||
public ProviderSignInController providerSignInController() {
|
||||
ConnectionFactoryLocator connectionFactoryLocator = connectionFactoryLocator();
|
||||
UsersConnectionRepository usersConnectionRepository = getUsersConnectionRepository(connectionFactoryLocator);
|
||||
((InMemoryUsersConnectionRepository) usersConnectionRepository).setConnectionSignUp(facebookConnectionSignup);
|
||||
return new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, new FacebookSignInAdapter());
|
||||
}
|
||||
|
||||
private ConnectionFactoryLocator connectionFactoryLocator() {
|
||||
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
|
||||
registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
|
||||
return registry;
|
||||
}
|
||||
|
||||
private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
|
||||
return new InMemoryUsersConnectionRepository(connectionFactoryLocator);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue