Merge branch 'eugenp:master' into master
This commit is contained in:
commit
5b399786f6
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.poi.excel.lastrow;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class LastRowUnitTest {
|
||||
private static final String FILE_NAME = "lastRowTest.xlsx";
|
||||
private String fileLocation;
|
||||
|
||||
@Before
|
||||
public void setup() throws URISyntaxException {
|
||||
fileLocation = Paths.get(ClassLoader.getSystemResource(FILE_NAME).toURI()).toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExampleGrid_whenGetRow_thenReturnRowObjectIfModified() throws IOException {
|
||||
Workbook workbook = new XSSFWorkbook(fileLocation);
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
assertEquals(7, sheet.getLastRowNum());
|
||||
assertEquals(6, sheet.getPhysicalNumberOfRows());
|
||||
|
||||
assertNotNull(sheet.getRow(0));
|
||||
assertNotNull(sheet.getRow(1));
|
||||
assertNotNull(sheet.getRow(2));
|
||||
assertNotNull(sheet.getRow(3));
|
||||
assertNull(sheet.getRow(4));
|
||||
assertNull(sheet.getRow(5));
|
||||
assertNotNull(sheet.getRow(6));
|
||||
assertNotNull(sheet.getRow(7));
|
||||
assertNull(sheet.getRow(8));
|
||||
|
||||
assertSame(sheet.getRow(7), getLastRowFromSheet(sheet));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptySheet_whenGetRow_thenReturnNull() throws IOException {
|
||||
Workbook workbook = new XSSFWorkbook(fileLocation);
|
||||
Sheet sheet = workbook.getSheetAt(1);
|
||||
|
||||
assertEquals(-1, sheet.getLastRowNum());
|
||||
assertEquals(0, sheet.getPhysicalNumberOfRows());
|
||||
|
||||
assertNull(sheet.getRow(0));
|
||||
|
||||
assertSame(sheet.getRow(0), getLastRowFromSheet(sheet));
|
||||
}
|
||||
|
||||
public static Row getLastRowFromSheet(Sheet sheet) {
|
||||
Row lastRow = null;
|
||||
int lastRowNum = sheet.getLastRowNum();
|
||||
if (lastRowNum >= 0) {
|
||||
lastRow = sheet.getRow(lastRowNum);
|
||||
}
|
||||
return lastRow;
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -6,3 +6,5 @@ This module contains articles about Map data structures in Java.
|
|||
- [Using a Custom Class as a Key in a Java HashMap](https://www.baeldung.com/java-custom-class-map-key)
|
||||
- [Nested HashMaps Examples in Java](https://www.baeldung.com/java-nested-hashmaps)
|
||||
- [Java HashMap With Different Value Types](https://www.baeldung.com/java-hashmap-different-value-types)
|
||||
- [Difference Between Map and HashMap in Java](https://www.baeldung.com/java-map-vs-hashmap)
|
||||
- [How to Create a New Entry in a Map](https://www.baeldung.com/java-map-new-entry)
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
- [Bad Practices With Synchronization](https://www.baeldung.com/java-synchronization-bad-practices)
|
||||
- [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time)
|
||||
- [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety)
|
||||
- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception)
|
||||
- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement)
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package com.baeldung.exception.variablemightnothavebeeninitialized;
|
||||
|
||||
public class VariableMightNotHaveBeenInitialized {
|
||||
|
||||
private static int instanceVariableCount;
|
||||
|
||||
/**
|
||||
* Method would not compile if lines 14 and 18 are uncommented.
|
||||
*/
|
||||
public static void countEven() {
|
||||
//uninstantiated
|
||||
int count;
|
||||
int[] arr = new int[]{23, 56, 89, 12, 23};
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if ((arr[i] % 2) == 0) {
|
||||
// count++;
|
||||
}
|
||||
|
||||
}
|
||||
// System.out.println("Total Even Numbers : " + count);
|
||||
}
|
||||
|
||||
public static int countEvenUsingInstanceVariable(int[] arr) {
|
||||
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if ((arr[i] % 2) == 0) {
|
||||
instanceVariableCount++;
|
||||
}
|
||||
|
||||
}
|
||||
return instanceVariableCount;
|
||||
}
|
||||
|
||||
public static int countEvenUsingIfElse(int[] arr, int args) {
|
||||
int count;
|
||||
count = args > 0 ? args : 0;
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if ((arr[i] % 2) == 0) {
|
||||
count++;
|
||||
}
|
||||
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package com.baeldung.exception.variablemightnothavebeeninitialized;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class VariableMightNotHaveBeenInitializedUnitTest {
|
||||
|
||||
@Test
|
||||
public void usingInstanceVariable_returnCount() {
|
||||
int[] arr = new int[]{1, 2, 3, 4, 5, 6};
|
||||
int value = VariableMightNotHaveBeenInitialized.countEvenUsingInstanceVariable(arr);
|
||||
|
||||
assertEquals(3, value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usingArgumentsAndIfElse_returnCount() {
|
||||
int[] arr = new int[]{1, 2, 3, 4, 5, 6};
|
||||
int value = VariableMightNotHaveBeenInitialized.countEvenUsingIfElse(arr, 2);
|
||||
|
||||
assertEquals(5, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.filetomap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FileToHashMap {
|
||||
|
||||
enum DupKeyOption {
|
||||
OVERWRITE, DISCARD
|
||||
}
|
||||
|
||||
public static Map<String, String> byBufferedReader(String filePath, DupKeyOption dupKeyOption) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
String line;
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] keyValuePair = line.split(":", 2);
|
||||
if (keyValuePair.length > 1) {
|
||||
String key = keyValuePair[0];
|
||||
String value = keyValuePair[1];
|
||||
if (DupKeyOption.OVERWRITE == dupKeyOption) {
|
||||
map.put(key, value);
|
||||
} else if (DupKeyOption.DISCARD == dupKeyOption) {
|
||||
map.putIfAbsent(key, value);
|
||||
}
|
||||
} else {
|
||||
System.out.println("No Key:Value found in line, ignoring: " + line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, String> byStream(String filePath, DupKeyOption dupKeyOption) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
|
||||
lines.filter(line -> line.contains(":"))
|
||||
.forEach(line -> {
|
||||
String[] keyValuePair = line.split(":", 2);
|
||||
String key = keyValuePair[0];
|
||||
String value = keyValuePair[1];
|
||||
if (DupKeyOption.OVERWRITE == dupKeyOption) {
|
||||
map.put(key, value);
|
||||
} else if (DupKeyOption.DISCARD == dupKeyOption) {
|
||||
map.putIfAbsent(key, value);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, List<String>> aggregateByKeys(String filePath) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
|
||||
lines.filter(line -> line.contains(":"))
|
||||
.forEach(line -> {
|
||||
String[] keyValuePair = line.split(":", 2);
|
||||
String key = keyValuePair[0];
|
||||
String value = keyValuePair[1];
|
||||
if (map.containsKey(key)) {
|
||||
map.get(key).add(value);
|
||||
} else {
|
||||
map.put(key, Stream.of(value).collect(Collectors.toList()));
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.filetomap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class FileToHashMapUnitTest {
|
||||
|
||||
private String filePath;
|
||||
|
||||
private static final Map<String, String> EXPECTED_MAP_DISCARD = Stream.of(new String[][]{
|
||||
{"title", "The Lord of the Rings: The Return of the King"},
|
||||
{"director", "Peter Jackson"},
|
||||
{"actor", "Sean Astin"}
|
||||
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
|
||||
|
||||
private static final Map<String, String> EXPECTED_MAP_OVERWRITE = Stream.of(new String[][]{
|
||||
{"title", "The Lord of the Rings: The Return of the King"},
|
||||
{"director", "Peter Jackson"},
|
||||
{"actor", "Ian McKellen"}
|
||||
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
|
||||
|
||||
private static final Map<String, List<String>> EXPECTED_MAP_AGGREGATE = Stream.of(new String[][]{
|
||||
{"title", "The Lord of the Rings: The Return of the King"},
|
||||
{"director", "Peter Jackson"},
|
||||
{"actor", "Sean Astin", "Ian McKellen"}
|
||||
}).collect(Collectors.toMap(arr -> arr[0], arr -> Arrays.asList(Arrays.copyOfRange(arr, 1, arr.length))));
|
||||
|
||||
@Before
|
||||
public void setPath() throws URISyntaxException {
|
||||
if (filePath == null) {
|
||||
filePath = Paths.get(ClassLoader.getSystemResource("filetomap/theLordOfRings.txt").toURI()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInputFile_whenInvokeByBufferedReaderPriorToJava8_shouldGetExpectedMap() {
|
||||
Map<String, String> mapOverwrite = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.OVERWRITE);
|
||||
Map<String, String> mapDiscard = FileToHashMap.byBufferedReader(filePath, FileToHashMap.DupKeyOption.DISCARD);
|
||||
assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE);
|
||||
assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInputFile_whenInvokeByStream_shouldGetExpectedMap() {
|
||||
Map<String, String> mapOverwrite = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.OVERWRITE);
|
||||
Map<String, String> mapDiscard = FileToHashMap.byStream(filePath, FileToHashMap.DupKeyOption.DISCARD);
|
||||
assertThat(mapOverwrite).isEqualTo(EXPECTED_MAP_OVERWRITE);
|
||||
assertThat(mapDiscard).isEqualTo(EXPECTED_MAP_DISCARD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInputFile_whenInvokeAggregateByKeys_shouldGetExpectedMap() {
|
||||
Map<String, List<String>> mapAgg = FileToHashMap.aggregateByKeys(filePath);
|
||||
assertThat(mapAgg).isEqualTo(EXPECTED_MAP_AGGREGATE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
title:The Lord of the Rings: The Return of the King
|
||||
director:Peter Jackson
|
||||
actor:Sean Astin
|
||||
actor:Ian McKellen
|
||||
Gandalf and Aragorn lead the World of Men against Sauron's
|
||||
army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring.
|
|
@ -7,3 +7,4 @@
|
|||
- [Dockerfile Strategies for Git](https://www.baeldung.com/ops/dockerfile-git-strategies)
|
||||
- [How to Get Docker-Compose to Always Use the Latest Image](https://www.baeldung.com/ops/docker-compose-latest-image)
|
||||
- [How to Include Files Outside of Docker’s Build Context](https://www.baeldung.com/ops/docker-include-files-outside-build-context)
|
||||
- [Caching Maven Dependencies with Docker](https://www.baeldung.com/ops/docker-cache-maven-dependencies)
|
||||
|
|
|
@ -12,8 +12,24 @@
|
|||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>central</id>
|
||||
<name>Central Repository</name>
|
||||
<url>https://repo.maven.apache.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
|
@ -25,11 +41,114 @@
|
|||
<artifactId>ratpack-core</artifactId>
|
||||
<version>${ratpack-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.americanexpress.nodes</groupId>
|
||||
<artifactId>nodes</artifactId>
|
||||
<version>0.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-java</artifactId>
|
||||
<version>9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-java-tools</artifactId>
|
||||
<version>5.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-java-servlet</artifactId>
|
||||
<version>6.1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-netty</artifactId>
|
||||
<version>5.11.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mock-server</groupId>
|
||||
<artifactId>mockserver-client-java</artifactId>
|
||||
<version>5.11.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.graphql-java-generator</groupId>
|
||||
<artifactId>graphql-java-runtime</artifactId>
|
||||
<version>${graphql.java.generator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.8.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-maven-plugin</artifactId>
|
||||
<version>10.0.7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.graphql-java-generator</groupId>
|
||||
<artifactId>graphql-maven-plugin</artifactId>
|
||||
<version>${graphql.java.generator.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generateClientCode</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<packageName>com.baeldung.graphql.generated</packageName>
|
||||
<copyRuntimeSources>false</copyRuntimeSources>
|
||||
<generateDeprecatedRequestResponse>false</generateDeprecatedRequestResponse>
|
||||
<separateUtilityClasses>true</separateUtilityClasses>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<graphql-java-annotations.version>3.0.3</graphql-java-annotations.version>
|
||||
<ratpack-core.version>1.4.6</ratpack-core.version>
|
||||
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<graphql.java.generator.version>1.18</graphql.java.generator.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.graphql.clients;
|
||||
|
||||
import com.baeldung.graphql.data.Data;
|
||||
import io.aexp.nodes.graphql.GraphQLRequestEntity;
|
||||
import io.aexp.nodes.graphql.GraphQLResponseEntity;
|
||||
import io.aexp.nodes.graphql.GraphQLTemplate;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class AmericanExpressNodes {
|
||||
|
||||
public static GraphQLResponseEntity<Data> callGraphQLService(String url, String query) throws IOException {
|
||||
GraphQLTemplate graphQLTemplate = new GraphQLTemplate();
|
||||
|
||||
GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
|
||||
.url(StringUtils.join(url, "?query=", query))
|
||||
.request(Data.class)
|
||||
.build();
|
||||
|
||||
return graphQLTemplate.query(requestEntity, Data.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.graphql.clients;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.utils.URIBuilder;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class ApacheHttpClient {
|
||||
|
||||
public static HttpResponse callGraphQLService(String url, String query) throws URISyntaxException, IOException {
|
||||
HttpClient client = HttpClientBuilder.create().build();
|
||||
HttpGet request = new HttpGet(url);
|
||||
URI uri = new URIBuilder(request.getURI())
|
||||
.addParameter("query", query)
|
||||
.build();
|
||||
request.setURI(uri);
|
||||
return client.execute(request);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.graphql.data;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class Author {
|
||||
|
||||
private String name;
|
||||
private String surname;
|
||||
|
||||
public Author() {
|
||||
|
||||
}
|
||||
|
||||
public Author(String name, String surname) {
|
||||
this.name = name;
|
||||
this.surname = surname;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSurname() {
|
||||
return surname;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return StringUtils.join(getName(), " ", getSurname());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.graphql.data;
|
||||
|
||||
public class Book {
|
||||
|
||||
private String title;
|
||||
private Author author;
|
||||
|
||||
public Book() {
|
||||
|
||||
}
|
||||
|
||||
public Book(String title, Author author) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.graphql.data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BookRepository {
|
||||
|
||||
private static final List<Book> books = Stream.of(
|
||||
new Book("Title 1", new Author("Pero", "Peric")),
|
||||
new Book("Title 2", new Author("Marko", "Maric"))
|
||||
).collect(Collectors.toList());
|
||||
|
||||
public List<Book> getAllBooks() {
|
||||
return Collections.unmodifiableList(books);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.graphql.data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Data {
|
||||
|
||||
private List<Book> allBooks;
|
||||
|
||||
public Data() {
|
||||
|
||||
}
|
||||
|
||||
public Data(List<Book> allBooks) {
|
||||
this.allBooks = allBooks;
|
||||
}
|
||||
|
||||
public List<Book> getAllBooks() {
|
||||
return Collections.unmodifiableList(allBooks);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.graphql.data;
|
||||
|
||||
public class Response {
|
||||
|
||||
private Data data;
|
||||
|
||||
public Response() {
|
||||
|
||||
}
|
||||
|
||||
public Response(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.graphql.server;
|
||||
|
||||
import com.baeldung.graphql.data.BookRepository;
|
||||
import com.coxautodev.graphql.tools.SchemaParser;
|
||||
import graphql.schema.GraphQLSchema;
|
||||
import graphql.servlet.SimpleGraphQLHttpServlet;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebServlet(urlPatterns = "/graphql")
|
||||
public class GraphQLEndpoint extends HttpServlet {
|
||||
|
||||
private SimpleGraphQLHttpServlet graphQLServlet;
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
graphQLServlet.service(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
GraphQLSchema schema = SchemaParser.newParser()
|
||||
.resolvers(new GraphQLQuery(new BookRepository()))
|
||||
.file("schema.graphqls")
|
||||
.build()
|
||||
.makeExecutableSchema();
|
||||
graphQLServlet = SimpleGraphQLHttpServlet
|
||||
.newBuilder(schema)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.graphql.server;
|
||||
|
||||
import com.baeldung.graphql.data.Book;
|
||||
import com.baeldung.graphql.data.BookRepository;
|
||||
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GraphQLQuery implements GraphQLQueryResolver {
|
||||
|
||||
private final BookRepository repository;
|
||||
|
||||
public GraphQLQuery(BookRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public List<Book> allBooks() {
|
||||
return repository.getAllBooks();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
type Book {
|
||||
title: String!
|
||||
author: Author
|
||||
}
|
||||
|
||||
type Author {
|
||||
name: String!
|
||||
surname: String!
|
||||
}
|
||||
|
||||
type Query {
|
||||
allBooks: [Book]
|
||||
}
|
||||
|
||||
schema {
|
||||
query: Query
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.graphql;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.mockserver.client.MockServerClient;
|
||||
import org.mockserver.integration.ClientAndServer;
|
||||
import org.mockserver.model.HttpStatusCode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
|
||||
import static org.mockserver.matchers.Times.exactly;
|
||||
import static org.mockserver.model.HttpRequest.request;
|
||||
import static org.mockserver.model.HttpResponse.response;
|
||||
|
||||
public class GraphQLMockServer {
|
||||
|
||||
public static ClientAndServer mockServer;
|
||||
public static String serviceUrl;
|
||||
|
||||
private static int serverPort;
|
||||
|
||||
public static final String SERVER_ADDRESS = "127.0.0.1";
|
||||
public static final String HTTP_GET_POST = "GET";
|
||||
public static final String PATH = "/graphql";
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException, URISyntaxException {
|
||||
serverPort = getFreePort();
|
||||
serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH;
|
||||
mockServer = startClientAndServer(serverPort);
|
||||
mockAllBooksTitleRequest();
|
||||
mockAllBooksTitleAuthorRequest();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void stopServer() {
|
||||
mockServer.stop();
|
||||
}
|
||||
|
||||
private static void mockAllBooksTitleAuthorRequest() {
|
||||
String requestQuery = "{allBooks{title,author{name,surname}}}";
|
||||
String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\",\"author\":{\"name\":\"Pero\",\"surname\":\"Peric\"}},{\"title\":\"Title 2\",\"author\":{\"name\":\"Marko\",\"surname\":\"Maric\"}}]}}";
|
||||
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH)
|
||||
.withQueryStringParameter("query", requestQuery),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatusCode.OK_200.code())
|
||||
.withBody(responseJson)
|
||||
);
|
||||
}
|
||||
|
||||
private static void mockAllBooksTitleRequest() {
|
||||
String requestQuery = "{allBooks{title}}";
|
||||
String responseJson = "{\"data\":{\"allBooks\":[{\"title\":\"Title 1\"},{\"title\":\"Title 2\"}]}}";
|
||||
|
||||
new MockServerClient(SERVER_ADDRESS, serverPort)
|
||||
.when(
|
||||
request()
|
||||
.withPath(PATH)
|
||||
.withQueryStringParameter("query", requestQuery),
|
||||
exactly(1)
|
||||
)
|
||||
.respond(
|
||||
response()
|
||||
.withStatusCode(HttpStatusCode.OK_200.code())
|
||||
.withBody(responseJson)
|
||||
);
|
||||
}
|
||||
|
||||
private static int getFreePort () throws IOException {
|
||||
try (ServerSocket serverSocket = new ServerSocket(0)) {
|
||||
return serverSocket.getLocalPort();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.graphql.clients;
|
||||
|
||||
import com.baeldung.graphql.GraphQLMockServer;
|
||||
import com.baeldung.graphql.data.Data;
|
||||
import io.aexp.nodes.graphql.GraphQLResponseEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
|
||||
class AmericanExpressNodesUnitTest extends GraphQLMockServer {
|
||||
|
||||
@Test
|
||||
void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException {
|
||||
GraphQLResponseEntity<Data> responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title}}");
|
||||
|
||||
assertAll(
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException {
|
||||
GraphQLResponseEntity<Data> responseEntity = AmericanExpressNodes.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}");
|
||||
|
||||
assertAll(
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks()).hasSize(2),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"),
|
||||
() -> assertThat(responseEntity.getResponse().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.graphql.clients;
|
||||
|
||||
import com.baeldung.graphql.GraphQLMockServer;
|
||||
import com.baeldung.graphql.data.Response;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
|
||||
class ApacheHttpClientUnitTest extends GraphQLMockServer {
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
void givenGraphQLEndpoint_whenRequestingAllBooksWithTitle_thenExpectedJsonIsReturned() throws IOException, URISyntaxException {
|
||||
HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title}}");
|
||||
String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name());
|
||||
Response parsedResponse = objectMapper.readValue(actualResponse, Response.class);
|
||||
|
||||
assertAll(
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenGraphQLEndpoint_whenRequestingAllBooksWithTitleAndAuthor_thenExpectedJsonIsReturned() throws IOException, URISyntaxException {
|
||||
HttpResponse httpResponse = ApacheHttpClient.callGraphQLService(serviceUrl, "{allBooks{title,author{name,surname}}}");
|
||||
String actualResponse = IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8.name());
|
||||
Response parsedResponse = objectMapper.readValue(actualResponse, Response.class);
|
||||
|
||||
assertAll(
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks()).hasSize(2),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(0).getTitle()).isEqualTo("Title 1"),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(0).getAuthor().getFullName()).isEqualTo("Pero Peric"),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(1).getTitle()).isEqualTo("Title 2"),
|
||||
() -> assertThat(parsedResponse.getData().getAllBooks().get(1).getAuthor().getFullName()).isEqualTo("Marko Maric")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,3 +3,4 @@
|
|||
This module contains articles about Servlets.
|
||||
|
||||
### Relevant Articles:
|
||||
- [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.lombok.tostring;
|
||||
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public class Account {
|
||||
|
||||
private String name;
|
||||
|
||||
// render this field before any others (the highest ranked)
|
||||
@ToString.Include(rank = 1)
|
||||
private String id;
|
||||
|
||||
@ToString.Exclude
|
||||
private String accountNumber;
|
||||
|
||||
// automatically excluded
|
||||
private String $ignored;
|
||||
|
||||
@ToString.Include
|
||||
String description() {
|
||||
return "Account description";
|
||||
}
|
||||
|
||||
public String getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
public void setAccountNumber(String accountNumber) {
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String get$ignored() {
|
||||
return $ignored;
|
||||
}
|
||||
|
||||
public void set$ignored(String value) {
|
||||
this.$ignored = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.lombok.tostring;
|
||||
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public enum AccountType {
|
||||
CHECKING,
|
||||
SAVING
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.lombok.tostring;
|
||||
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
public class RewardAccount extends Account {
|
||||
|
||||
private String rewardAccountId;
|
||||
|
||||
private Object[] relatedAccounts;
|
||||
|
||||
public String getRewardAccountId() {
|
||||
return rewardAccountId;
|
||||
}
|
||||
|
||||
public void setRewardAccountId(String rewardAccountId) {
|
||||
this.rewardAccountId = rewardAccountId;
|
||||
}
|
||||
|
||||
public Object[] getRelatedAccounts() {
|
||||
return relatedAccounts;
|
||||
}
|
||||
|
||||
public void setRelatedAccounts(Object[] relatedAccounts) {
|
||||
this.relatedAccounts = relatedAccounts;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.lombok.tostring;
|
||||
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString(callSuper = true)
|
||||
public class SavingAccount extends Account {
|
||||
|
||||
private String savingAccountId;
|
||||
|
||||
public String getSavingAccountId() {
|
||||
return savingAccountId;
|
||||
}
|
||||
|
||||
public void setSavingAccountId(String savingAccountId) {
|
||||
this.savingAccountId = savingAccountId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.lombok.tostring;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ToStringUnitTest {
|
||||
|
||||
@Test
|
||||
void whenPrintObject_thenOutputIsCorrect() {
|
||||
Account account = new Account();
|
||||
account.setId("12345");
|
||||
account.setName("An account");
|
||||
account.setAccountNumber("11111"); // should not be present in output
|
||||
account.set$ignored("ignored value"); // should not be present in output
|
||||
|
||||
assertThat(account.toString())
|
||||
.isEqualTo("Account(id=12345, name=An account, description=Account description)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintSubclassWithSuper_thenOutputIsCorrect() {
|
||||
SavingAccount savingAccount = new SavingAccount();
|
||||
savingAccount.setSavingAccountId("5678");
|
||||
savingAccount.setId("12345");
|
||||
savingAccount.setName("An account");
|
||||
|
||||
assertThat(savingAccount.toString())
|
||||
.isEqualTo("SavingAccount(super=Account(id=12345, name=An account, description=Account description), savingAccountId=5678)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintArrays_thenOutputIsCorrect() {
|
||||
RewardAccount account = new RewardAccount();
|
||||
account.setRewardAccountId("12345");
|
||||
|
||||
// circular ref, just for demonstration
|
||||
Object[] relatedAccounts = new Object[2];
|
||||
relatedAccounts[0] = "54321";
|
||||
relatedAccounts[1] = relatedAccounts;
|
||||
|
||||
account.setRelatedAccounts(relatedAccounts);
|
||||
|
||||
assertThat(account.toString())
|
||||
.isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=[54321, [...]])");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintSubclassWithoutSuper_thenOutputIsCorrect() {
|
||||
RewardAccount rewardAccount = new RewardAccount();
|
||||
rewardAccount.setRewardAccountId("12345");
|
||||
|
||||
assertThat(rewardAccount.toString())
|
||||
.isEqualTo("RewardAccount(rewardAccountId=12345, relatedAccounts=null)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenPrintEnum_thenOutputIsCorrect() {
|
||||
assertThat(AccountType.CHECKING.toString())
|
||||
.isEqualTo("AccountType.CHECKING");
|
||||
|
||||
assertThat(AccountType.SAVING.toString())
|
||||
.isEqualTo("AccountType.SAVING");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [A Guide to Maven Artifact Classifiers](https://www.baeldung.com/maven-artifact-classifiers)
|
|
@ -5,7 +5,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>maven-profiles</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>maven-profiles</name>
|
||||
|
||||
<profiles>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<artifactId>parent-project</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -4,14 +4,13 @@
|
|||
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>
|
||||
<artifactId>parent-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>parent-project</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>maven-simple</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<artifactId>parent-project</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<artifactId>parent-project</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<parent>
|
||||
<artifactId>maven-simple</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@ -56,8 +56,8 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.plugin>3.8.1</maven.compiler.plugin>
|
||||
<maven.bulid.helper.plugin>3.2.0</maven.bulid.helper.plugin>
|
||||
<maven.compiler.plugin>3.10.0</maven.compiler.plugin>
|
||||
<maven.bulid.helper.plugin>3.3.0</maven.bulid.helper.plugin>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<artifactId>plugin-management</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<artifactId>plugin-management</artifactId>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
|
@ -5,6 +5,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>maven-simple</artifactId>
|
||||
<name>maven-simple</name>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
<plugin>
|
||||
<groupId>org.mule.tools.maven</groupId>
|
||||
<artifactId>mule-maven-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>${mule-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<deploymentType>standalone</deploymentType>
|
||||
<muleVersion>${mule.version}</muleVersion>
|
||||
|
@ -203,7 +203,7 @@
|
|||
<id>mulesoft-release</id>
|
||||
<name>mulesoft release repository</name>
|
||||
<layout>default</layout>
|
||||
<url>https://repository.mulesoft.org/releases/</url>
|
||||
<url>https://repository.mulesoft.org/nexus/content/repositories/public/</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
|
@ -212,9 +212,10 @@
|
|||
|
||||
<properties>
|
||||
<mule.version>3.9.0</mule.version>
|
||||
<mule.tools.version>1.2</mule.tools.version>
|
||||
<mule.tools.version>1.8</mule.tools.version>
|
||||
<munit.version>1.3.6</munit.version>
|
||||
<build-helper-maven-plugin.version>1.7</build-helper-maven-plugin.version>
|
||||
<build-helper-maven-plugin.version>1.10</build-helper-maven-plugin.version>
|
||||
<mule-maven-plugin.version>2.2.1</mule-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -50,6 +50,25 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration-lite-first</id>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
<reuseForks>true</reuseForks>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<!-- Cassandra -->
|
||||
<cassandra-driver-core.version>3.1.2</cassandra-driver-core.version>
|
||||
|
|
|
@ -10,35 +10,35 @@ import com.mongodb.client.result.UpdateResult;
|
|||
|
||||
public class MultipleFieldsExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
|
||||
//
|
||||
// Connect to cluster (default is localhost:27017)
|
||||
//
|
||||
//
|
||||
// Connect to cluster (default is localhost:27017)
|
||||
//
|
||||
|
||||
MongoClient mongoClient = new MongoClient("localhost", 27017);
|
||||
MongoDatabase database = mongoClient.getDatabase("baeldung");
|
||||
MongoCollection<Document> collection = database.getCollection("employee");
|
||||
MongoClient mongoClient = new MongoClient("localhost", 27017);
|
||||
MongoDatabase database = mongoClient.getDatabase("baeldung");
|
||||
MongoCollection<Document> collection = database.getCollection("employee");
|
||||
|
||||
//
|
||||
// Filter on the basis of employee_id
|
||||
//
|
||||
//
|
||||
// Filter on the basis of employee_id
|
||||
//
|
||||
|
||||
BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
|
||||
BasicDBObject searchQuery = new BasicDBObject("employee_id", 794875);
|
||||
|
||||
//
|
||||
// Update the fields in Document
|
||||
//
|
||||
//
|
||||
// Update the fields in Document
|
||||
//
|
||||
|
||||
BasicDBObject updateFields = new BasicDBObject();
|
||||
updateFields.append("department_id", 3);
|
||||
updateFields.append("job", "Sales Manager");
|
||||
BasicDBObject setQuery = new BasicDBObject();
|
||||
setQuery.append("$set", updateFields);
|
||||
UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
|
||||
BasicDBObject updateFields = new BasicDBObject();
|
||||
updateFields.append("department_id", 3);
|
||||
updateFields.append("job", "Sales Manager");
|
||||
BasicDBObject setQuery = new BasicDBObject();
|
||||
setQuery.append("$set", updateFields);
|
||||
UpdateResult updateResult = collection.updateMany(searchQuery, setQuery);
|
||||
|
||||
System.out.println("updateResult:- " + updateResult);
|
||||
System.out.println("updateResult:- " + updateResult.getModifiedCount());
|
||||
System.out.println("updateResult:- " + updateResult);
|
||||
System.out.println("updateResult:- " + updateResult.getModifiedCount());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,26 +11,25 @@ import com.mongodb.client.result.UpdateResult;
|
|||
|
||||
public class UpdateMultipleFields {
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) {
|
||||
|
||||
//
|
||||
// Connect to cluster
|
||||
//
|
||||
//
|
||||
// Connect to cluster
|
||||
//
|
||||
|
||||
MongoClient mongoClient = new MongoClient("localhost", 27007);
|
||||
MongoDatabase database = mongoClient.getDatabase("baeldung");
|
||||
MongoCollection<Document> collection = database.getCollection("employee");
|
||||
MongoClient mongoClient = new MongoClient("localhost", 27007);
|
||||
MongoDatabase database = mongoClient.getDatabase("baeldung");
|
||||
MongoCollection<Document> collection = database.getCollection("employee");
|
||||
|
||||
//
|
||||
// Update query
|
||||
//
|
||||
//
|
||||
// Update query
|
||||
//
|
||||
|
||||
UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875),
|
||||
Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
|
||||
UpdateResult updateResult = collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
|
||||
|
||||
System.out.println("updateResult:- " + updateResult);
|
||||
System.out.println("updateResult:- " + updateResult.getModifiedCount());
|
||||
System.out.println("updateResult:- " + updateResult);
|
||||
System.out.println("updateResult:- " + updateResult.getModifiedCount());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@ package com.baeldung.update;
|
|||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Before;
|
||||
|
@ -15,7 +13,6 @@ import com.mongodb.client.MongoCollection;
|
|||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import com.mongodb.client.model.Updates;
|
||||
import com.mongodb.client.result.UpdateResult;
|
||||
|
||||
public class UpdateMultipleFieldsLiveTest {
|
||||
|
||||
|
@ -30,8 +27,7 @@ public class UpdateMultipleFieldsLiveTest {
|
|||
db = mongoClient.getDatabase("baeldung");
|
||||
collection = db.getCollection("employee");
|
||||
|
||||
collection.insertOne(Document.parse(
|
||||
"{'employee_id':794875,'employee_name': 'David smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}"));
|
||||
collection.insertOne(Document.parse("{'employee_id':794875,'employee_name': 'David Smith','job': 'Sales Representative','department_id': 2,'salary': 20000,'hire_date': NumberLong(\"1643969311817\")}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +43,8 @@ public class UpdateMultipleFieldsLiveTest {
|
|||
|
||||
collection.updateMany(searchQuery, setQuery);
|
||||
|
||||
Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first();
|
||||
Document nameDoc = collection.find(Filters.eq("employee_id", 794875))
|
||||
.first();
|
||||
assertNotNull(nameDoc);
|
||||
assertFalse(nameDoc.isEmpty());
|
||||
|
||||
|
@ -62,10 +59,10 @@ public class UpdateMultipleFieldsLiveTest {
|
|||
@Test
|
||||
public void updateMultipleFieldsUsingDocument() {
|
||||
|
||||
collection.updateMany(Filters.eq("employee_id", 794875),
|
||||
Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
|
||||
collection.updateMany(Filters.eq("employee_id", 794875), Updates.combine(Updates.set("department_id", 4), Updates.set("job", "Sales Manager")));
|
||||
|
||||
Document nameDoc = collection.find(Filters.eq("employee_id", 794875)).first();
|
||||
Document nameDoc = collection.find(Filters.eq("employee_id", 794875))
|
||||
.first();
|
||||
assertNotNull(nameDoc);
|
||||
assertFalse(nameDoc.isEmpty());
|
||||
|
||||
|
@ -78,3 +75,4 @@ public class UpdateMultipleFieldsLiveTest {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -518,7 +518,7 @@
|
|||
<module>micronaut</module>
|
||||
<module>microprofile</module>
|
||||
<module>msf4j</module>
|
||||
<!-- <module>muleesb</module> --> <!-- Module broken, fixing in https://team.baeldung.com/browse/JAVA-10335 -->
|
||||
<module>muleesb</module>
|
||||
<module>mustache</module>
|
||||
<module>mybatis</module>
|
||||
|
||||
|
@ -1001,7 +1001,7 @@
|
|||
<module>micronaut</module>
|
||||
<module>microprofile</module>
|
||||
<module>msf4j</module>
|
||||
<!-- <module>muleesb</module> --> <!-- Module broken, fixing in https://team.baeldung.com/browse/JAVA-10335 -->
|
||||
<module>muleesb</module>
|
||||
<module>mustache</module>
|
||||
<module>mybatis</module>
|
||||
|
||||
|
|
|
@ -9,3 +9,4 @@ This module contains articles about Spring Cloud Gateway
|
|||
- [Spring Cloud Gateway Routing Predicate Factories](https://www.baeldung.com/spring-cloud-gateway-routing-predicate-factories)
|
||||
- [Spring Cloud Gateway WebFilter Factories](https://www.baeldung.com/spring-cloud-gateway-webfilter-factories)
|
||||
- [Using Spring Cloud Gateway with OAuth 2.0 Patterns](https://www.baeldung.com/spring-cloud-gateway-oauth2)
|
||||
- [URL Rewriting With Spring Cloud Gateway](https://www.baeldung.com/spring-cloud-gateway-url-rewriting)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.oauth2resttemplate;
|
||||
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
|
||||
@Controller
|
||||
public class AppController {
|
||||
|
||||
OAuth2RestTemplate restTemplate;
|
||||
|
||||
public AppController(OAuth2RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
}
|
||||
|
||||
@GetMapping("/home")
|
||||
public String welcome(Model model, Principal principal) {
|
||||
model.addAttribute("name", principal.getName());
|
||||
return "home";
|
||||
}
|
||||
|
||||
@GetMapping("/repos")
|
||||
public String repos(Model model) {
|
||||
Collection<GithubRepo> repos = restTemplate.getForObject("https://api.github.com/user/repos", Collection.class);
|
||||
model.addAttribute("repos", repos);
|
||||
return "repositories";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.oauth2resttemplate;
|
||||
|
||||
public class GithubRepo {
|
||||
Long id;
|
||||
String name;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package com.baeldung.oauth2resttemplate;
|
||||
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
|
||||
import org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.client.OAuth2ClientContext;
|
||||
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
|
||||
import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
|
||||
import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
@Configuration
|
||||
@EnableOAuth2Client
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
OAuth2ClientContext oauth2ClientContext;
|
||||
|
||||
public SecurityConfig(OAuth2ClientContext oauth2ClientContext) {
|
||||
this.oauth2ClientContext = oauth2ClientContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests().antMatchers("/", "/login**", "/error**")
|
||||
.permitAll().anyRequest().authenticated()
|
||||
.and().logout().logoutUrl("/logout").logoutSuccessUrl("/")
|
||||
.and().addFilterBefore(oauth2ClientFilter(), BasicAuthenticationFilter.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
|
||||
FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(filter);
|
||||
registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public OAuth2RestTemplate restTemplate() {
|
||||
return new OAuth2RestTemplate(githubClient(), oauth2ClientContext);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties("github.client")
|
||||
public AuthorizationCodeResourceDetails githubClient() {
|
||||
return new AuthorizationCodeResourceDetails();
|
||||
}
|
||||
|
||||
private Filter oauth2ClientFilter() {
|
||||
OAuth2ClientAuthenticationProcessingFilter oauth2ClientFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/github");
|
||||
OAuth2RestTemplate restTemplate = restTemplate();
|
||||
oauth2ClientFilter.setRestTemplate(restTemplate);
|
||||
UserInfoTokenServices tokenServices = new UserInfoTokenServices(githubResource().getUserInfoUri(), githubClient().getClientId());
|
||||
tokenServices.setRestTemplate(restTemplate);
|
||||
oauth2ClientFilter.setTokenServices(tokenServices);
|
||||
return oauth2ClientFilter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties("github.resource")
|
||||
public ResourceServerProperties githubResource() {
|
||||
return new ResourceServerProperties();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.oauth2resttemplate;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@SpringBootApplication
|
||||
@PropertySource("classpath:application-oauth2-rest-template.properties")
|
||||
public class SpringSecurityOauth2ClientApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringSecurityOauth2ClientApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
github.client.clientId=[CLIENT_ID]
|
||||
github.client.clientSecret=[CLIENT_SECRET]
|
||||
github.client.userAuthorizationUri=https://github.com/login/oauth/authorize
|
||||
github.client.accessTokenUri=https://github.com/login/oauth/access_token
|
||||
github.client.clientAuthenticationScheme=form
|
||||
|
||||
github.resource.userInfoUri=https://api.github.com/user
|
||||
|
||||
spring.thymeleaf.prefix=classpath:/templates/oauth2resttemplate/
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Error</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>An error occurred.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Home</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Welcome <b th:inline="text"> [[${name}]] </b>
|
||||
</p>
|
||||
<h3>
|
||||
<a href="/repos">View Repositories</a><br/><br/>
|
||||
</h3>
|
||||
|
||||
<form th:action="@{/logout}" method="POST">
|
||||
<input type="submit" value="Logout"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>OAuth2Client</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>
|
||||
<a href="/home" th:href="@{/home}" th:if="${#httpServletRequest?.remoteUser != undefined }">
|
||||
Go to Home
|
||||
</a>
|
||||
<a href="/login/github" th:href="@{/login/github}" th:if="${#httpServletRequest?.remoteUser == undefined }">
|
||||
GitHub Login
|
||||
</a>
|
||||
</h3>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Repositories</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<h2>Repos</h2>
|
||||
</p>
|
||||
<ul th:each="repo: ${repos}">
|
||||
<li th:text="${repo.name}"></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
|
@ -12,4 +12,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com
|
|||
- [Spring Security – Cache Control Headers](https://www.baeldung.com/spring-security-cache-control-headers)
|
||||
- [Fixing 401s with CORS Preflights and Spring Security](https://www.baeldung.com/spring-security-cors-preflight)
|
||||
- [Content Security Policy with Spring Security](https://www.baeldung.com/spring-security-csp)
|
||||
- [Enable Logging for Spring Security](https://www.baeldung.com/spring-security-enable-logging)
|
||||
- More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-2)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<spring-cloud-sleuth.version>2.0.2.RELEASE</spring-cloud-sleuth.version>
|
||||
<spring-cloud-sleuth.version>3.1.0</spring-cloud-sleuth.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.sleuth.traceid;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SleuthCurrentTraceIdApp {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SleuthCurrentTraceIdApp.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.sleuth.traceid;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import brave.Span;
|
||||
import brave.Tracer;
|
||||
|
||||
@RestController
|
||||
public class SleuthTraceIdController {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SleuthTraceIdController.class);
|
||||
|
||||
@Autowired
|
||||
private Tracer tracer;
|
||||
|
||||
@GetMapping("/traceid")
|
||||
public String getSleuthTraceId() {
|
||||
logger.info("Hello with Sleuth");
|
||||
Span span = tracer.currentSpan();
|
||||
if (span != null) {
|
||||
logger.info("Span ID hex {}", span.context().spanIdString());
|
||||
logger.info("Span ID decimal {}", span.context().spanId());
|
||||
logger.info("Trace ID hex {}", span.context().traceIdString());
|
||||
logger.info("Trace ID decimal {}", span.context().traceId());
|
||||
}
|
||||
return "Hello from Sleuth";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue