@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.java14.record;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public record Person (String name, String address) {
|
||||
|
||||
public static String UNKWOWN_ADDRESS = "Unknown";
|
||||
public static String UNNAMED = "Unnamed";
|
||||
|
||||
public Person {
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(address);
|
||||
}
|
||||
|
||||
public Person(String name) {
|
||||
this(name, UNKWOWN_ADDRESS);
|
||||
}
|
||||
|
||||
public static Person unnamed(String address) {
|
||||
return new Person(UNNAMED, address);
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +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.UNKWOWN_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());
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.weeknumber;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
public class WeekNumberUsingCalendar {
|
||||
|
||||
public int getWeekNumberFrom(String day, String dateFormat, Locale locale) throws ParseException {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
|
||||
|
||||
Calendar calendar = Calendar.getInstance(locale);
|
||||
Date date = sdf.parse(day);
|
||||
calendar.setTime(date);
|
||||
|
||||
return calendar.get(Calendar.WEEK_OF_YEAR);
|
||||
}
|
||||
|
||||
public int getWeekNumberFrom(int year, int month, int day, Locale locale) {
|
||||
Calendar calendar = Calendar.getInstance(locale);
|
||||
calendar.set(year, month, day);
|
||||
|
||||
return calendar.get(Calendar.WEEK_OF_YEAR);
|
||||
}
|
||||
|
||||
public int getWeekNumberFrom(int year, int month, int day, int firstDayOfWeek, int minimalDaysInFirstWeek, Locale locale) {
|
||||
Calendar calendar = Calendar.getInstance(locale);
|
||||
calendar.setFirstDayOfWeek(firstDayOfWeek);
|
||||
calendar.setMinimalDaysInFirstWeek(minimalDaysInFirstWeek);
|
||||
calendar.set(year, month, day);
|
||||
|
||||
return calendar.get(Calendar.WEEK_OF_YEAR);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
System.out.println(calendar.getWeekNumberFrom(2020, 2, 22, Locale.CANADA));
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.weeknumber;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.Locale;
|
||||
|
||||
public class WeekNumberUsingLocalDate {
|
||||
|
||||
public Integer getWeekNumberUsingWeekFiedsFrom(String day, String dayFormat, Locale locale) {
|
||||
LocalDate date = LocalDate.parse(day, DateTimeFormatter.ofPattern(dayFormat));
|
||||
|
||||
return date.get(WeekFields.of(locale)
|
||||
.weekOfYear());
|
||||
}
|
||||
|
||||
public Integer getWeekNumberUsinWeekFieldsFrom(int year, int month, int day, Locale locale) {
|
||||
LocalDate date = LocalDate.of(year, month, day);
|
||||
|
||||
return date.get(WeekFields.of(locale)
|
||||
.weekOfYear());
|
||||
}
|
||||
|
||||
public Integer getWeekNumberUsingChronoFieldFrom(int year, int month, int day) {
|
||||
LocalDate date = LocalDate.of(year, month, day);
|
||||
|
||||
return date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.weeknumber;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class WeekNumberUsingCalendarUnitTest {
|
||||
@Test
|
||||
public void givenDateInStringAndDateFormatUsingLocaleItaly_thenGettingWeekNumberUsingCalendarIsCorrectlyReturned() throws ParseException {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
|
||||
assertEquals(12, calendar.getWeekNumberFrom("20200322", "yyyyMMdd", Locale.ITALY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInStringAndDateFormatUsingLocaleCanada_thenGettingWeekNumberUsingCalendarIsCorrectlyReturned() throws ParseException {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
|
||||
assertEquals(13, calendar.getWeekNumberFrom("20200322", "yyyyMMdd", Locale.CANADA));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInYearMonthDayNumbersLocaleItaly_thenGettingWeekNumberUsingCalendarIsCorrectlyReturned() {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
|
||||
assertEquals(12, calendar.getWeekNumberFrom(2020, 2, 22, Locale.ITALY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInYearMonthDayNumbersLocaleItalyChangingWeekCalculationSettings_thenGettingWeekNumberUsingCalendarIsCorrectlyReturned() {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
|
||||
assertEquals(13, calendar.getWeekNumberFrom(2020, 2, 22, Calendar.SUNDAY, 4, Locale.ITALY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInYearMonthDayNumbersLocaleCanada_thenGettingWeekNumberUsingCalendarIsCorrectlyReturned() {
|
||||
WeekNumberUsingCalendar calendar = new WeekNumberUsingCalendar();
|
||||
|
||||
assertEquals(13, calendar.getWeekNumberFrom(2020, 2, 22, Locale.CANADA));
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.weeknumber;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class WeekNumberUsingLocalDateUnitTest {
|
||||
@Test
|
||||
public void givenDateInStringAndDateFormatUsingWeekFieldsWithLocaleItaly_thenGettingWeekNumberUsingLocalDateIsCorrectlyReturned() {
|
||||
WeekNumberUsingLocalDate localDate = new WeekNumberUsingLocalDate();
|
||||
|
||||
assertEquals(12, localDate.getWeekNumberUsingWeekFiedsFrom("20200322", "yyyyMMdd", Locale.ITALY)
|
||||
.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInStringAndDateFormatUsingWeekFieldsWithLocaleCanada_thenGettingWeekNumberUsingLocalDateIsCorrectlyReturned() {
|
||||
WeekNumberUsingLocalDate localDate = new WeekNumberUsingLocalDate();
|
||||
|
||||
assertEquals(13, localDate.getWeekNumberUsingWeekFiedsFrom("20200322", "yyyyMMdd", Locale.CANADA)
|
||||
.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInStringAndDateFormatUsingChronoFieds_thenGettingWeekNumberUsingLocalDateIsCorrectlyReturned() {
|
||||
WeekNumberUsingLocalDate localDate = new WeekNumberUsingLocalDate();
|
||||
|
||||
assertEquals(12, localDate.getWeekNumberUsingChronoFieldFrom(2020, 3, 22)
|
||||
.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInYearMonthDayNumbersUsingWeekFieldsWithLocaleItaly_thenGettingWeekNumberUsingLocalDateIsCorrectlyReturned() {
|
||||
WeekNumberUsingLocalDate localDate = new WeekNumberUsingLocalDate();
|
||||
|
||||
assertEquals(12, localDate.getWeekNumberUsinWeekFieldsFrom(2020, 3, 22, Locale.ITALY)
|
||||
.longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDateInYearMonthDayNumbersUsingWeekFieldsWithLocaleCanada_thenGettingWeekNumberUsingLocalDateIsCorrectlyReturned() {
|
||||
WeekNumberUsingLocalDate localDate = new WeekNumberUsingLocalDate();
|
||||
|
||||
assertEquals(13, localDate.getWeekNumberUsinWeekFieldsFrom(2020, 3, 22, Locale.CANADA)
|
||||
.longValue());
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
+34
@@ -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>
|
||||
+131
@@ -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,27 @@
|
||||
package com.baeldung.jsonproxy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsoupProxyLiveTest {
|
||||
|
||||
@Test
|
||||
public void whenUsingHostAndPort_thenConnect() throws IOException {
|
||||
Jsoup.connect("https://spring.io/blog")
|
||||
.proxy("200.216.227.141", 53281)
|
||||
.get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingProxyClass_thenConnect() throws IOException {
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("200.216.227.141", 53281));
|
||||
|
||||
Jsoup.connect("https://spring.io/blog")
|
||||
.proxy(proxy)
|
||||
.get();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
+30
@@ -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";
|
||||
}
|
||||
}
|
||||
+133
@@ -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
|
||||
}
|
||||
}
|
||||
+38
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+24
@@ -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";
|
||||
}
|
||||
}
|
||||
+48
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user