[BAEL-9696] - Fixed conflicts
This commit is contained in:
commit
571c21b555
10
README.md
10
README.md
|
@ -26,3 +26,13 @@ To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false`
|
|||
Building a single module
|
||||
====================
|
||||
To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory
|
||||
|
||||
|
||||
Running a Spring Boot module
|
||||
====================
|
||||
To run a Spring Boot module run the command: `mvn spring-boot:run -Dgib.enabled=false` in the module directory
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -31,3 +31,6 @@
|
|||
- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
|
||||
- [Merge Sort in Java](https://www.baeldung.com/java-merge-sort)
|
||||
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
|
||||
- [Quicksort Algorithm Implementation in Java](https://www.baeldung.com/java-quicksort)
|
||||
- [Insertion Sort in Java](https://www.baeldung.com/java-insertion-sort)
|
||||
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
|
||||
|
|
|
@ -7,7 +7,7 @@ public class BubbleSort {
|
|||
void bubbleSort(Integer[] arr) {
|
||||
int n = arr.length;
|
||||
IntStream.range(0, n - 1)
|
||||
.flatMap(i -> IntStream.range(i + 1, n - i))
|
||||
.flatMap(i -> IntStream.range(1, n - i))
|
||||
.forEach(j -> {
|
||||
if (arr[j - 1] > arr[j]) {
|
||||
int temp = arr[j];
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.baeldung.algorithms.bubblesort;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BubbleSortUnitTest {
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode)
|
|
@ -0,0 +1,8 @@
|
|||
.classpath
|
||||
.project
|
||||
.settings
|
||||
target
|
||||
.idea
|
||||
*.iml
|
||||
.gradle/
|
||||
build/
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung.pulsar</groupId>
|
||||
<artifactId>pulsar-java</artifactId>
|
||||
<version>0.0.1</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.pulsar</groupId>
|
||||
<artifactId>pulsar-client</artifactId>
|
||||
<version>2.1.1-incubating</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
</properties>
|
||||
</project>
|
|
@ -0,0 +1,48 @@
|
|||
package com.baeldung;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.pulsar.client.api.Consumer;
|
||||
import org.apache.pulsar.client.api.Message;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.SubscriptionType;
|
||||
|
||||
public class ConsumerTest {
|
||||
|
||||
private static final String SERVICE_URL = "pulsar://localhost:6650";
|
||||
private static final String TOPIC_NAME = "test-topic";
|
||||
private static final String SUBSCRIPTION_NAME = "test-subscription";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Create a Pulsar client instance. A single instance can be shared across many
|
||||
// producers and consumer within the same application
|
||||
PulsarClient client = PulsarClient.builder()
|
||||
.serviceUrl(SERVICE_URL)
|
||||
.build();
|
||||
|
||||
//Configure consumer specific settings.
|
||||
Consumer<byte[]> consumer = client.newConsumer()
|
||||
.topic(TOPIC_NAME)
|
||||
// Allow multiple consumers to attach to the same subscription
|
||||
// and get messages dispatched as a queue
|
||||
.subscriptionType(SubscriptionType.Shared)
|
||||
.subscriptionName(SUBSCRIPTION_NAME)
|
||||
.subscribe();
|
||||
|
||||
|
||||
// Once the consumer is created, it can be used for the entire application lifecycle
|
||||
System.out.println("Created consumer for the topic "+ TOPIC_NAME);
|
||||
|
||||
do {
|
||||
// Wait until a message is available
|
||||
Message<byte[]> msg = consumer.receive();
|
||||
|
||||
// Extract the message as a printable string and then log
|
||||
String content = new String(msg.getData());
|
||||
System.out.println("Received message '"+content+"' with ID "+msg.getMessageId());
|
||||
|
||||
// Acknowledge processing of the message so that it can be deleted
|
||||
consumer.acknowledge(msg);
|
||||
} while (true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.baeldung;
|
||||
|
||||
import org.apache.pulsar.client.api.CompressionType;
|
||||
import org.apache.pulsar.client.api.Message;
|
||||
import org.apache.pulsar.client.api.MessageBuilder;
|
||||
import org.apache.pulsar.client.api.MessageId;
|
||||
import org.apache.pulsar.client.api.Producer;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.PulsarClientException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ProducerTest {
|
||||
|
||||
private static final String SERVICE_URL = "pulsar://localhost:6650";
|
||||
private static final String TOPIC_NAME = "test-topic";
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Create a Pulsar client instance. A single instance can be shared across many
|
||||
// producers and consumer within the same application
|
||||
PulsarClient client = PulsarClient.builder()
|
||||
.serviceUrl(SERVICE_URL)
|
||||
.build();
|
||||
|
||||
// Configure producer specific settings
|
||||
Producer<byte[]> producer = client.newProducer()
|
||||
// Set the topic
|
||||
.topic(TOPIC_NAME)
|
||||
// Enable compression
|
||||
.compressionType(CompressionType.LZ4)
|
||||
.create();
|
||||
|
||||
// Once the producer is created, it can be used for the entire application life-cycle
|
||||
System.out.println("Created producer for the topic "+TOPIC_NAME);
|
||||
|
||||
// Send 5 test messages
|
||||
IntStream.range(1, 5).forEach(i -> {
|
||||
String content = String.format("hi-pulsar-%d", i);
|
||||
|
||||
// Build a message object
|
||||
Message<byte[]> msg = MessageBuilder.create()
|
||||
.setContent(content.getBytes())
|
||||
.build();
|
||||
|
||||
// Send each message and log message content and ID when successfully received
|
||||
try {
|
||||
MessageId msgId = producer.send(msg);
|
||||
|
||||
System.out.println("Published message '"+content+"' with the ID "+msgId);
|
||||
} catch (PulsarClientException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
client.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package com.baeldung.subscriptions;
|
||||
|
||||
import org.apache.pulsar.client.api.ConsumerBuilder;
|
||||
import org.apache.pulsar.client.api.Message;
|
||||
import org.apache.pulsar.client.api.MessageBuilder;
|
||||
import org.apache.pulsar.client.api.Producer;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.PulsarClientException;
|
||||
import org.apache.pulsar.client.api.SubscriptionType;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ExclusiveSubscriptionTest {
|
||||
private static final String SERVICE_URL = "pulsar://localhost:6650";
|
||||
private static final String TOPIC_NAME = "test-topic";
|
||||
private static final String SUBSCRIPTION_NAME = "test-subscription";
|
||||
private static final SubscriptionType SUBSCRIPTION_TYPE = SubscriptionType.Exclusive;
|
||||
|
||||
public static void main(String[] args) throws PulsarClientException {
|
||||
PulsarClient client = PulsarClient.builder()
|
||||
.serviceUrl(SERVICE_URL)
|
||||
.build();
|
||||
|
||||
Producer<byte[]> producer = client.newProducer()
|
||||
.topic(TOPIC_NAME)
|
||||
.create();
|
||||
|
||||
ConsumerBuilder<byte[]> consumer1 = client.newConsumer()
|
||||
.topic(TOPIC_NAME)
|
||||
.subscriptionName(SUBSCRIPTION_NAME)
|
||||
.subscriptionType(SUBSCRIPTION_TYPE);
|
||||
|
||||
ConsumerBuilder<byte[]> consumer2 = client.newConsumer()
|
||||
.topic(TOPIC_NAME)
|
||||
.subscriptionName(SUBSCRIPTION_NAME)
|
||||
.subscriptionType(SUBSCRIPTION_TYPE);
|
||||
|
||||
IntStream.range(0, 999).forEach(i -> {
|
||||
Message<byte[]> msg = MessageBuilder.create()
|
||||
.setContent(String.format("message-%d", i).getBytes())
|
||||
.build();
|
||||
try {
|
||||
producer.send(msg);
|
||||
} catch (PulsarClientException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
// Consumer 1 can subscribe to the topic
|
||||
consumer1.subscribe();
|
||||
|
||||
// Consumer 2 cannot due to the exclusive subscription held by consumer 1
|
||||
consumer2.subscribeAsync()
|
||||
.handle((consumer, exception) -> {
|
||||
System.out.println(exception.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.subscriptions;
|
||||
|
||||
import org.apache.pulsar.client.api.Consumer;
|
||||
import org.apache.pulsar.client.api.ConsumerBuilder;
|
||||
import org.apache.pulsar.client.api.Message;
|
||||
import org.apache.pulsar.client.api.MessageBuilder;
|
||||
import org.apache.pulsar.client.api.Producer;
|
||||
import org.apache.pulsar.client.api.PulsarClient;
|
||||
import org.apache.pulsar.client.api.PulsarClientException;
|
||||
import org.apache.pulsar.client.api.SubscriptionType;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class FailoverSubscriptionTest {
|
||||
private static final String SERVICE_URL = "pulsar://localhost:6650";
|
||||
private static final String TOPIC_NAME = "failover-subscription-test-topic";
|
||||
private static final String SUBSCRIPTION_NAME = "test-subscription";
|
||||
private static final SubscriptionType SUBSCRIPTION_TYPE = SubscriptionType.Failover;
|
||||
private static final int NUM_MSGS = 10;
|
||||
|
||||
public static void main(String[] args) throws PulsarClientException {
|
||||
PulsarClient client = PulsarClient.builder()
|
||||
.serviceUrl(SERVICE_URL)
|
||||
.build();
|
||||
|
||||
Producer<byte[]> producer = client.newProducer()
|
||||
.topic(TOPIC_NAME)
|
||||
.create();
|
||||
|
||||
ConsumerBuilder<byte[]> consumerBuilder = client.newConsumer()
|
||||
.topic(TOPIC_NAME)
|
||||
.subscriptionName(SUBSCRIPTION_NAME)
|
||||
.subscriptionType(SUBSCRIPTION_TYPE);
|
||||
|
||||
Consumer<byte[]> mainConsumer = consumerBuilder
|
||||
.consumerName("consumer-a")
|
||||
.messageListener((consumer, msg) -> {
|
||||
System.out.println("Message received by main consumer");
|
||||
|
||||
try {
|
||||
consumer.acknowledge(msg);
|
||||
} catch (PulsarClientException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
})
|
||||
.subscribe();
|
||||
|
||||
Consumer<byte[]> failoverConsumer = consumerBuilder
|
||||
.consumerName("consumer-b")
|
||||
.messageListener((consumer, msg) -> {
|
||||
System.out.println("Message received by failover consumer");
|
||||
|
||||
try {
|
||||
consumer.acknowledge(msg);
|
||||
} catch (PulsarClientException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
})
|
||||
.subscribe();
|
||||
|
||||
IntStream.range(0, NUM_MSGS).forEach(i -> {
|
||||
Message<byte[]> msg = MessageBuilder.create()
|
||||
.setContent(String.format("message-%d", i).getBytes())
|
||||
.build();
|
||||
try {
|
||||
producer.send(msg);
|
||||
|
||||
Thread.sleep(100);
|
||||
|
||||
if (i > 5) mainConsumer.close();
|
||||
} catch (InterruptedException | PulsarClientException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,13 +1,20 @@
|
|||
package com.baeldung.java8;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Java8ForEachUnitTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Java8ForEachUnitTest.class);
|
||||
|
@ -29,8 +36,18 @@ public class Java8ForEachUnitTest {
|
|||
}
|
||||
|
||||
// Java 8 - forEach
|
||||
LOG.debug("--- forEach method ---");
|
||||
names.forEach(name -> LOG.debug(name));
|
||||
names.forEach(name -> {
|
||||
System.out.println(name);
|
||||
});
|
||||
|
||||
LOG.debug("--- Print Consumer ---");
|
||||
Consumer<String> printConsumer = new Consumer<String>() {
|
||||
public void accept(String name) {
|
||||
System.out.println(name);
|
||||
};
|
||||
};
|
||||
|
||||
names.forEach(printConsumer);
|
||||
|
||||
// Anonymous inner class that implements Consumer interface
|
||||
LOG.debug("--- Anonymous inner class ---");
|
||||
|
@ -40,17 +57,55 @@ public class Java8ForEachUnitTest {
|
|||
}
|
||||
});
|
||||
|
||||
// Create a Consumer implementation to then use in a forEach method
|
||||
Consumer<String> consumerNames = name -> {
|
||||
LOG.debug(name);
|
||||
};
|
||||
LOG.debug("--- Implementation of Consumer interface ---");
|
||||
names.forEach(consumerNames);
|
||||
// Java 8 - forEach - Lambda Syntax
|
||||
LOG.debug("--- forEach method ---");
|
||||
names.forEach(name -> LOG.debug(name));
|
||||
|
||||
// Print elements using a Method Reference
|
||||
// Java 8 - forEach - Print elements using a Method Reference
|
||||
LOG.debug("--- Method Reference ---");
|
||||
names.forEach(LOG::debug);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenList_thenIterateAndPrintResults() {
|
||||
List<String> names = Arrays.asList("Larry", "Steve", "James");
|
||||
|
||||
names.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSet_thenIterateAndPrintResults() {
|
||||
Set<String> uniqueNames = new HashSet<>(Arrays.asList("Larry", "Steve", "James"));
|
||||
|
||||
uniqueNames.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenQueue_thenIterateAndPrintResults() {
|
||||
Queue<String> namesQueue = new ArrayDeque<>(Arrays.asList("Larry", "Steve", "James"));
|
||||
|
||||
namesQueue.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMap_thenIterateAndPrintResults() {
|
||||
Map<Integer, String> namesMap = new HashMap<>();
|
||||
namesMap.put(1, "Larry");
|
||||
namesMap.put(2, "Steve");
|
||||
namesMap.put(3, "James");
|
||||
|
||||
namesMap.entrySet()
|
||||
.forEach(entry -> System.out.println(entry.getKey() + " " + entry.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMap_whenUsingBiConsumer_thenIterateAndPrintResults2() {
|
||||
Map<Integer, String> namesMap = new HashMap<>();
|
||||
namesMap.put(1, "Larry");
|
||||
namesMap.put(2, "Steve");
|
||||
namesMap.put(3, "James");
|
||||
|
||||
namesMap.forEach((key, value) -> System.out.println(key + " " + value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,3 +38,4 @@
|
|||
- [Time Complexity of Java Collections](https://www.baeldung.com/java-collections-complexity)
|
||||
- [Operating on and Removing an Item from Stream](https://www.baeldung.com/java-use-remove-item-stream)
|
||||
- [An Introduction to Synchronized Java Collections](https://www.baeldung.com/java-synchronized-collections)
|
||||
- [Guide to EnumSet](https://www.baeldung.com/java-enumset)
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.junit.Test;
|
|||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -15,26 +16,28 @@ public class SemaphoresManualTest {
|
|||
// ========= login queue ======
|
||||
|
||||
@Test
|
||||
public void givenLoginQueue_whenReachLimit_thenBlocked() {
|
||||
public void givenLoginQueue_whenReachLimit_thenBlocked() throws InterruptedException {
|
||||
final int slots = 10;
|
||||
final ExecutorService executorService = Executors.newFixedThreadPool(slots);
|
||||
final LoginQueueUsingSemaphore loginQueue = new LoginQueueUsingSemaphore(slots);
|
||||
IntStream.range(0, slots)
|
||||
.forEach(user -> executorService.execute(loginQueue::tryLogin));
|
||||
executorService.shutdown();
|
||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(0, loginQueue.availableSlots());
|
||||
assertFalse(loginQueue.tryLogin());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenLoginQueue_whenLogout_thenSlotsAvailable() {
|
||||
public void givenLoginQueue_whenLogout_thenSlotsAvailable() throws InterruptedException {
|
||||
final int slots = 10;
|
||||
final ExecutorService executorService = Executors.newFixedThreadPool(slots);
|
||||
final LoginQueueUsingSemaphore loginQueue = new LoginQueueUsingSemaphore(slots);
|
||||
IntStream.range(0, slots)
|
||||
.forEach(user -> executorService.execute(loginQueue::tryLogin));
|
||||
executorService.shutdown();
|
||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(0, loginQueue.availableSlots());
|
||||
loginQueue.logout();
|
||||
|
@ -45,13 +48,14 @@ public class SemaphoresManualTest {
|
|||
// ========= delay queue =======
|
||||
|
||||
@Test
|
||||
public void givenDelayQueue_whenReachLimit_thenBlocked() {
|
||||
public void givenDelayQueue_whenReachLimit_thenBlocked() throws InterruptedException {
|
||||
final int slots = 50;
|
||||
final ExecutorService executorService = Executors.newFixedThreadPool(slots);
|
||||
final DelayQueueUsingTimedSemaphore delayQueue = new DelayQueueUsingTimedSemaphore(1, slots);
|
||||
IntStream.range(0, slots)
|
||||
.forEach(user -> executorService.execute(delayQueue::tryAdd));
|
||||
executorService.shutdown();
|
||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(0, delayQueue.availableSlots());
|
||||
assertFalse(delayQueue.tryAdd());
|
||||
|
@ -65,6 +69,7 @@ public class SemaphoresManualTest {
|
|||
IntStream.range(0, slots)
|
||||
.forEach(user -> executorService.execute(delayQueue::tryAdd));
|
||||
executorService.shutdown();
|
||||
executorService.awaitTermination(10, TimeUnit.SECONDS);
|
||||
|
||||
assertEquals(0, delayQueue.availableSlots());
|
||||
Thread.sleep(1000);
|
||||
|
|
|
@ -31,4 +31,5 @@
|
|||
- [Create a Symbolic Link with Java](http://www.baeldung.com/java-symlink)
|
||||
- [Quick Use of FilenameFilter](http://www.baeldung.com/java-filename-filter)
|
||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||
- [ Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||
- [Read a File into an ArrayList](https://www.baeldung.com/java-file-to-arraylist)
|
||||
- [Guide to Java OutputStream](https://www.baeldung.com/java-outputstream)
|
||||
|
|
|
@ -154,6 +154,12 @@
|
|||
<artifactId>async-http-client</artifactId>
|
||||
<version>${async-http-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>${opencsv.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -247,7 +253,7 @@
|
|||
<protonpack.version>1.13</protonpack.version>
|
||||
<streamex.version>0.6.5</streamex.version>
|
||||
<vavr.version>0.9.0</vavr.version>
|
||||
|
||||
<opencsv.version>4.1</opencsv.version>
|
||||
<!-- testing -->
|
||||
<assertj.version>3.6.1</assertj.version>
|
||||
<avaitility.version>1.7.0</avaitility.version>
|
||||
|
|
|
@ -9,13 +9,13 @@ import java.util.zip.ZipInputStream;
|
|||
|
||||
public class UnzipFile {
|
||||
public static void main(final String[] args) throws IOException {
|
||||
final String fileZip = "src/main/resources/compressed.zip";
|
||||
final String fileZip = "src/main/resources/unzipTest/compressed.zip";
|
||||
final File destDir = new File("src/main/resources/unzipTest");
|
||||
final byte[] buffer = new byte[1024];
|
||||
final ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip));
|
||||
ZipEntry zipEntry = zis.getNextEntry();
|
||||
while (zipEntry != null) {
|
||||
final String fileName = zipEntry.getName();
|
||||
final File newFile = new File("src/main/resources/unzipTest/" + fileName);
|
||||
final File newFile = newFile(destDir, zipEntry);
|
||||
final FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
|
@ -27,4 +27,20 @@ public class UnzipFile {
|
|||
zis.closeEntry();
|
||||
zis.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://snyk.io/research/zip-slip-vulnerability
|
||||
*/
|
||||
public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
|
||||
File destFile = new File(destinationDir, zipEntry.getName());
|
||||
|
||||
String destDirPath = destinationDir.getCanonicalPath();
|
||||
String destFilePath = destFile.getCanonicalPath();
|
||||
|
||||
if (!destFilePath.startsWith(destDirPath + File.separator)) {
|
||||
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
|
||||
}
|
||||
|
||||
return destFile;
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,106 @@
|
|||
package com.baeldung.csv;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.opencsv.CSVReader;
|
||||
|
||||
public class ReadCSVInArrayUnitTest {
|
||||
public static final String COMMA_DELIMITER = ",";
|
||||
public static final String CSV_FILE = "src/test/resources/book.csv";
|
||||
public static final List<List<String>> EXPECTED_ARRAY = Collections.unmodifiableList(new ArrayList<List<String>>() {
|
||||
{
|
||||
add(new ArrayList<String>() {
|
||||
{
|
||||
add("Mary Kom");
|
||||
add("Unbreakable");
|
||||
}
|
||||
});
|
||||
add(new ArrayList<String>() {
|
||||
{
|
||||
add("Kapil Isapuari");
|
||||
add("Farishta");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@Test
|
||||
public void givenCSVFile_whenBufferedReader_thenContentsAsExpected() throws IOException {
|
||||
List<List<String>> records = new ArrayList<List<String>>();
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(CSV_FILE))) {
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] values = line.split(COMMA_DELIMITER);
|
||||
records.add(Arrays.asList(values));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
|
||||
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
|
||||
.toArray(),
|
||||
records.get(i)
|
||||
.toArray());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCSVFile_whenScanner_thenContentsAsExpected() throws IOException {
|
||||
List<List<String>> records = new ArrayList<List<String>>();
|
||||
try (Scanner scanner = new Scanner(new File(CSV_FILE));) {
|
||||
while (scanner.hasNextLine()) {
|
||||
records.add(getRecordFromLine(scanner.nextLine()));
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
|
||||
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
|
||||
.toArray(),
|
||||
records.get(i)
|
||||
.toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getRecordFromLine(String line) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
try (Scanner rowScanner = new Scanner(line)) {
|
||||
rowScanner.useDelimiter(COMMA_DELIMITER);
|
||||
while (rowScanner.hasNext()) {
|
||||
values.add(rowScanner.next());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCSVFile_whenOpencsv_thenContentsAsExpected() throws IOException {
|
||||
List<List<String>> records = new ArrayList<List<String>>();
|
||||
try (CSVReader csvReader = new CSVReader(new FileReader(CSV_FILE));) {
|
||||
String[] values = null;
|
||||
while ((values = csvReader.readNext()) != null) {
|
||||
records.add(Arrays.asList(values));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for (int i = 0; i < EXPECTED_ARRAY.size(); i++) {
|
||||
Assert.assertArrayEquals(EXPECTED_ARRAY.get(i)
|
||||
.toArray(),
|
||||
records.get(i)
|
||||
.toArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
Mary Kom,Unbreakable
|
||||
Kapil Isapuari,Farishta
|
|
|
@ -157,3 +157,4 @@
|
|||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
||||
- [Java Switch Statement](https://www.baeldung.com/java-switch)
|
||||
- [The Modulo Operator in Java](https://www.baeldung.com/modulo-java)
|
||||
- [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.ssl.example;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.Socket;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
public class SimpleClient {
|
||||
static void startClient(String host, int port) throws IOException {
|
||||
SocketFactory factory = SSLSocketFactory.getDefault();
|
||||
try (Socket connection = factory.createSocket(host, port)) {
|
||||
((SSLSocket) connection).setEnabledCipherSuites(
|
||||
new String[] { "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"});
|
||||
((SSLSocket) connection).setEnabledProtocols(
|
||||
new String[] { "TLSv1.2"});
|
||||
BufferedReader input = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream()));
|
||||
System.out.println(input.readLine());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
startClient("localhost", 1234);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.ssl.example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.net.ServerSocketFactory;
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
|
||||
public class SimpleServer {
|
||||
static void startServer(int port) throws IOException {
|
||||
ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
|
||||
try (ServerSocket listener = factory.createServerSocket(port)) {
|
||||
((SSLServerSocket) listener).setNeedClientAuth(true);
|
||||
((SSLServerSocket) listener).setEnabledCipherSuites(
|
||||
new String[] { "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"});
|
||||
((SSLServerSocket) listener).setEnabledProtocols(
|
||||
new String[] { "TLSv1.2"});
|
||||
while (true) {
|
||||
try (Socket socket = listener.accept()) {
|
||||
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
|
||||
out.println(new Date().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
startServer(1234);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class DoubleToString {
|
||||
|
||||
public static String truncateByCast(double d) {
|
||||
return String.valueOf((int) d);
|
||||
}
|
||||
|
||||
public static String roundWithStringFormat(double d) {
|
||||
return String.format("%.0f", d);
|
||||
}
|
||||
|
||||
public static String truncateWithNumberFormat(double d) {
|
||||
NumberFormat nf = NumberFormat.getInstance();
|
||||
nf.setMaximumFractionDigits(0);
|
||||
nf.setRoundingMode(RoundingMode.FLOOR);
|
||||
return nf.format(d);
|
||||
}
|
||||
|
||||
public static String roundWithNumberFormat(double d) {
|
||||
NumberFormat nf = NumberFormat.getInstance();
|
||||
nf.setMaximumFractionDigits(0);
|
||||
return nf.format(d);
|
||||
}
|
||||
|
||||
public static String truncateWithDecimalFormat(double d) {
|
||||
DecimalFormat df = new DecimalFormat("#,###");
|
||||
df.setRoundingMode(RoundingMode.FLOOR);
|
||||
return df.format(d);
|
||||
}
|
||||
|
||||
public static String roundWithDecimalFormat(double d) {
|
||||
DecimalFormat df = new DecimalFormat("#,###");
|
||||
return df.format(d);
|
||||
}
|
||||
|
||||
}
|
|
@ -7,14 +7,12 @@ import org.junit.runner.RunWith;
|
|||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NthRootCalculatorUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private NthRootCalculator nthRootCalculator;
|
||||
private NthRootCalculator nthRootCalculator = new NthRootCalculator();
|
||||
|
||||
@Test
|
||||
public void giventThatTheBaseIs125_andTheExpIs3_whenCalculateIsCalled_thenTheResultIsTheCorrectOne() {
|
||||
public void whenBaseIs125AndNIs3_thenNthRootIs5() {
|
||||
Double result = nthRootCalculator.calculate(125.0, 3.0);
|
||||
assertEquals(result, (Double) 5.0d);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.simpledateformat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class SimpleDateFormatUnitTest {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SimpleDateFormatUnitTest.class.getName());
|
||||
|
||||
@Test
|
||||
public void givenSpecificDate_whenFormatted_thenCheckFormatCorrect() throws Exception {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
|
||||
assertEquals("24-05-1977", formatter.format(new Date(233345223232L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSpecificDate_whenFormattedUsingDateFormat_thenCheckFormatCorrect() throws Exception {
|
||||
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT);
|
||||
assertEquals("5/24/77", formatter.format(new Date(233345223232L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringDate_whenParsed_thenCheckDateCorrect() throws Exception{
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("Europe/London"));
|
||||
Date myDate = new Date(233276400000L);
|
||||
Date parsedDate = formatter.parse("24-05-1977");
|
||||
assertEquals(myDate.getTime(), parsedDate.getTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFranceLocale_whenFormatted_thenCheckFormatCorrect() throws Exception{
|
||||
SimpleDateFormat franceDateFormatter = new SimpleDateFormat("EEEEE dd-MMMMMMM-yyyy", Locale.FRANCE);
|
||||
Date myWednesday = new Date(1539341312904L);
|
||||
assertTrue(franceDateFormatter.format(myWednesday).startsWith("vendredi"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void given2TimeZones_whenFormatted_thenCheckTimeDifference() throws Exception {
|
||||
Date now = new Date();
|
||||
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE dd-MMM-yy HH:mm:ssZ");
|
||||
|
||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"));
|
||||
logger.info(simpleDateFormat.format(now));
|
||||
//change the date format
|
||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));
|
||||
logger.info(simpleDateFormat.format(now));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.string;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DoubleToStringUnitTest {
|
||||
|
||||
private static final double DOUBLE_VALUE = 3.56;
|
||||
private static final String TRUNCATED_DOUBLE = "3";
|
||||
private static final String ROUNDED_UP_DOUBLE = "4";
|
||||
|
||||
|
||||
@Test
|
||||
public void truncateByCastTest() {
|
||||
assertThat(DoubleToString.truncateByCast(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundingWithStringFormatTest() {
|
||||
assertThat(DoubleToString.roundWithStringFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void truncateWithNumberFormatTest() {
|
||||
assertThat(DoubleToString.truncateWithNumberFormat(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundWithNumberFormatTest() {
|
||||
assertThat(DoubleToString.roundWithNumberFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void truncateWithDecimalFormatTest() {
|
||||
assertThat(DoubleToString.truncateWithDecimalFormat(DOUBLE_VALUE)).isEqualTo(TRUNCATED_DOUBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundWithDecimalFormatTest() {
|
||||
assertThat(DoubleToString.roundWithDecimalFormat(DOUBLE_VALUE)).isEqualTo(ROUNDED_UP_DOUBLE);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -39,3 +39,4 @@
|
|||
- [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant)
|
||||
- [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class)
|
||||
- [Concatenate Strings in Kotlin](https://www.baeldung.com/kotlin-concatenate-strings)
|
||||
- [Kotlin return, break, continue Keywords](https://www.baeldung.com/kotlin-return-break-continue)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.thread
|
||||
|
||||
class SimpleRunnable: Runnable {
|
||||
|
||||
override fun run() {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.baeldung.thread
|
||||
|
||||
class SimpleThread: Thread() {
|
||||
|
||||
override fun run() {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
|
@ -24,14 +24,15 @@ internal class SliceTest {
|
|||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenSlicingBeyondTheRangeOfTheArray_thenContainManyNulls() {
|
||||
val original = arrayOf(12, 3, 34, 4)
|
||||
val actual = original.slice(3..8)
|
||||
val expected = listOf(4, null, null, null, null, null)
|
||||
|
||||
assertIterableEquals(expected, actual)
|
||||
}
|
||||
// From the 1.3 version of Kotlin APIs, slice doesn't return array of nulls but throw IndexOutOfBoundsException
|
||||
// @Test
|
||||
// fun whenSlicingBeyondTheRangeOfTheArray_thenContainManyNulls() {
|
||||
// val original = arrayOf(12, 3, 34, 4)
|
||||
// val actual = original.slice(3..8)
|
||||
// val expected = listOf(4, null, null, null, null, null)
|
||||
//
|
||||
// assertIterableEquals(expected, actual)
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun whenSlicingBeyondRangeOfArrayWithStep_thenOutOfBoundsException() {
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
package com.baeldung.fuel
|
||||
|
||||
import awaitObjectResult
|
||||
import awaitStringResponse
|
||||
import com.github.kittinunf.fuel.Fuel
|
||||
import com.github.kittinunf.fuel.core.FuelManager
|
||||
import com.github.kittinunf.fuel.core.Request
|
||||
import com.github.kittinunf.fuel.core.interceptors.cUrlLoggingRequestInterceptor
|
||||
import com.github.kittinunf.fuel.gson.responseObject
|
||||
import com.github.kittinunf.fuel.httpGet
|
||||
import com.github.kittinunf.fuel.rx.rx_object
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.experimental.runBlocking
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.File
|
||||
|
@ -226,32 +222,26 @@ internal class FuelHttpUnitTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMakeGETRequestUsingCoroutines_thenResponseStatusCode200() {
|
||||
|
||||
runBlocking {
|
||||
val (request, response, result) = Fuel.get("http://httpbin.org/get").awaitStringResponse()
|
||||
// The new 1.3 coroutine APIs, aren't implemented yet in Fuel Library
|
||||
// @Test
|
||||
// fun whenMakeGETRequestUsingCoroutines_thenResponseStatusCode200() = runBlocking {
|
||||
// val (request, response, result) = Fuel.get("http://httpbin.org/get").awaitStringResponse()
|
||||
//
|
||||
// result.fold({ data ->
|
||||
// Assertions.assertEquals(200, response.statusCode)
|
||||
//
|
||||
// }, { error -> })
|
||||
// }
|
||||
|
||||
result.fold({ data ->
|
||||
Assertions.assertEquals(200, response.statusCode)
|
||||
|
||||
}, { error -> })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenMakeGETRequestUsingCoroutines_thenDeserializeResponse() {
|
||||
|
||||
|
||||
runBlocking {
|
||||
Fuel.get("https://jsonplaceholder.typicode.com/posts?id=1").awaitObjectResult(Post.Deserializer())
|
||||
.fold({ data ->
|
||||
Assertions.assertEquals(1, data.get(0).userId)
|
||||
}, { error -> })
|
||||
}
|
||||
|
||||
}
|
||||
// The new 1.3 coroutine APIs, aren't implemented yet in Fuel Library
|
||||
// @Test
|
||||
// fun whenMakeGETRequestUsingCoroutines_thenDeserializeResponse() = runBlocking {
|
||||
// Fuel.get("https://jsonplaceholder.typicode.com/posts?id=1").awaitObjectResult(Post.Deserializer())
|
||||
// .fold({ data ->
|
||||
// Assertions.assertEquals(1, data.get(0).userId)
|
||||
// }, { error -> })
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun whenMakeGETPostRequestUsingRoutingAPI_thenDeserializeResponse() {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package com.baeldung.kotlin
|
||||
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ArrayInitializationTest {
|
||||
|
||||
@Test
|
||||
fun givenArrayOfStrings_thenValuesPopulated() {
|
||||
val strings = arrayOf("January", "February", "March")
|
||||
|
||||
assertEquals(3, strings.size)
|
||||
assertEquals("March", strings[2])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfIntegers_thenValuesPopulated() {
|
||||
val integers = intArrayOf(1, 2, 3, 4)
|
||||
|
||||
assertEquals(4, integers.size)
|
||||
assertEquals(1, integers[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenArrayOfNulls_whenPopulated_thenValuesPresent() {
|
||||
val array = arrayOfNulls<Number>(5)
|
||||
|
||||
for (i in array.indices) {
|
||||
array[i] = i * i
|
||||
}
|
||||
|
||||
assertEquals(16, array[4])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenGeneratorUsed_thenValuesPresent() {
|
||||
val generatedArray = IntArray(10) { i -> i * i }
|
||||
|
||||
assertEquals(81, generatedArray[9])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenStringGenerated_thenValuesPresent() {
|
||||
val generatedStringArray = Array(10) { i -> "Number of index: $i" }
|
||||
|
||||
assertEquals("Number of index: 0", generatedStringArray[0])
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package com.baeldung.kotlin
|
||||
|
||||
import kotlinx.coroutines.experimental.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.junit.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
import kotlin.system.measureTimeMillis
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
@ -14,7 +13,7 @@ class CoroutinesTest {
|
|||
@Test
|
||||
fun givenBuildSequence_whenTakeNElements_thenShouldReturnItInALazyWay() {
|
||||
//given
|
||||
val fibonacciSeq = buildSequence {
|
||||
val fibonacciSeq = sequence {
|
||||
var a = 0
|
||||
var b = 1
|
||||
|
||||
|
@ -39,7 +38,7 @@ class CoroutinesTest {
|
|||
@Test
|
||||
fun givenLazySeq_whenTakeNElements_thenShouldReturnAllElements() {
|
||||
//given
|
||||
val lazySeq = buildSequence {
|
||||
val lazySeq = sequence {
|
||||
print("START ")
|
||||
for (i in 1..5) {
|
||||
yield(i)
|
||||
|
@ -60,8 +59,8 @@ class CoroutinesTest {
|
|||
val res = mutableListOf<String>()
|
||||
|
||||
//when
|
||||
runBlocking<Unit> {
|
||||
val promise = launch(CommonPool) { expensiveComputation(res) }
|
||||
runBlocking {
|
||||
val promise = launch(Dispatchers.Default) { expensiveComputation(res) }
|
||||
res.add("Hello,")
|
||||
promise.join()
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ class CoroutinesTest {
|
|||
|
||||
//when
|
||||
val jobs = List(numberOfCoroutines) {
|
||||
launch(CommonPool) {
|
||||
launch(Dispatchers.Default) {
|
||||
delay(1L)
|
||||
counter.incrementAndGet()
|
||||
}
|
||||
|
@ -101,7 +100,7 @@ class CoroutinesTest {
|
|||
fun givenCancellableJob_whenRequestForCancel_thenShouldQuit() {
|
||||
runBlocking<Unit> {
|
||||
//given
|
||||
val job = launch(CommonPool) {
|
||||
val job = launch(Dispatchers.Default) {
|
||||
while (isActive) {
|
||||
//println("is working")
|
||||
}
|
||||
|
@ -135,8 +134,8 @@ class CoroutinesTest {
|
|||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(CommonPool) { someExpensiveComputation(delay) }
|
||||
val two = async(CommonPool) { someExpensiveComputation(delay) }
|
||||
val one = async(Dispatchers.Default) { someExpensiveComputation(delay) }
|
||||
val two = async(Dispatchers.Default) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
|
@ -156,8 +155,8 @@ class CoroutinesTest {
|
|||
val delay = 1000L
|
||||
val time = measureTimeMillis {
|
||||
//given
|
||||
val one = async(CommonPool, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
val two = async(CommonPool, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
val one = async(Dispatchers.Default, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
val two = async(Dispatchers.Default, CoroutineStart.LAZY) { someExpensiveComputation(delay) }
|
||||
|
||||
//when
|
||||
runBlocking {
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.thread
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class CoroutineUnitTest {
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithoutContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithDefaultContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(Dispatchers.Default) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithUnconfinedContext_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(Dispatchers.Unconfined) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateCoroutineWithLaunchWithDedicatedThread_thenRun() = runBlocking {
|
||||
|
||||
val job = launch(newSingleThreadContext("dedicatedThread")) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateAsyncCoroutine_thenRun() = runBlocking {
|
||||
|
||||
val deferred = async(Dispatchers.IO) {
|
||||
return@async "${Thread.currentThread()} has run."
|
||||
}
|
||||
|
||||
val result = deferred.await()
|
||||
println(result)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.thread
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ThreadUnitTest {
|
||||
|
||||
@Test
|
||||
fun whenCreateThread_thenRun() {
|
||||
|
||||
val thread = SimpleThread()
|
||||
thread.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithRunnable_thenRun() {
|
||||
|
||||
val threadWithRunnable = Thread(SimpleRunnable())
|
||||
threadWithRunnable.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithSAMConversions_thenRun() {
|
||||
|
||||
val thread = Thread {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
thread.start()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCreateThreadWithMethodExtension_thenRun() {
|
||||
|
||||
thread(start = true) {
|
||||
println("${Thread.currentThread()} has run.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,3 +16,4 @@
|
|||
- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort)
|
||||
- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max)
|
||||
- [Merging Two Maps with Java 8](https://www.baeldung.com/java-merge-maps)
|
||||
- [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists)
|
||||
|
|
|
@ -21,4 +21,5 @@
|
|||
- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end)
|
||||
- [Calculate Age in Java](http://www.baeldung.com/java-get-age)
|
||||
- [Increment Date in Java](http://www.baeldung.com/java-increment-date)
|
||||
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
|
||||
- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
|
||||
- [Guide to DateTimeFormatter](https://www.baeldung.com/java-datetimeformatter)
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
package com.baeldung.zoneddatetime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ZonedDateTimeUnitTest {
|
||||
|
||||
private static final Logger log = Logger.getLogger(ZonedDateTimeUnitTest.class.getName());
|
||||
|
||||
@Test
|
||||
public void testZonedDateTimeToString() {
|
||||
public void givenZonedDateTime_whenConvertToString_thenOk() {
|
||||
|
||||
ZonedDateTime zonedDateTimeNow = ZonedDateTime.now(ZoneId.of("UTC"));
|
||||
ZonedDateTime zonedDateTimeOf = ZonedDateTime.of(2018, 01, 01, 0, 0, 0, 0, ZoneId.of("UTC"));
|
||||
|
@ -21,10 +24,10 @@ public class ZonedDateTimeUnitTest {
|
|||
LocalDateTime localDateTime = LocalDateTime.now();
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC"));
|
||||
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy - hh:mm:ss Z");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy - HH:mm:ss Z");
|
||||
String formattedString = zonedDateTime.format(formatter);
|
||||
|
||||
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy - hh:mm:ss z");
|
||||
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/dd/yyyy - HH:mm:ss z");
|
||||
String formattedString2 = zonedDateTime.format(formatter2);
|
||||
|
||||
log.info(formattedString);
|
||||
|
@ -33,9 +36,21 @@ public class ZonedDateTimeUnitTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testZonedDateTimeFromString() {
|
||||
public void givenString_whenParseZonedDateTime_thenOk() {
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2011-12-03T10:15:30+01:00");
|
||||
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2011-12-03T10:15:30+01:00", DateTimeFormatter.ISO_ZONED_DATE_TIME);
|
||||
log.info(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenString_whenParseZonedDateTimeWithoutZone_thenException() {
|
||||
assertThrows(DateTimeParseException.class, () -> ZonedDateTime.parse("2011-12-03T10:15:30", DateTimeFormatter.ISO_DATE_TIME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenString_whenParseLocalDateTimeAtZone_thenOk() {
|
||||
ZoneId timeZone = ZoneId.systemDefault();
|
||||
ZonedDateTime zonedDateTime = LocalDateTime.parse("2011-12-03T10:15:30", DateTimeFormatter.ISO_DATE_TIME).atZone(timeZone);
|
||||
|
||||
log.info(zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
|
||||
}
|
||||
|
|
|
@ -12,3 +12,4 @@
|
|||
- [BigDecimal and BigInteger in Java](http://www.baeldung.com/java-bigdecimal-biginteger)
|
||||
- [Find All Pairs of Numbers in an Array That Add Up to a Given Sum](http://www.baeldung.com/java-algorithm-number-pairs-sum)
|
||||
- [Java – Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double)
|
||||
- [Using Math.sin with Degrees](https://www.baeldung.com/java-math-sin-degrees)
|
||||
|
|
|
@ -4,10 +4,9 @@ import com.codepoetics.protonpack.Indexed;
|
|||
import com.codepoetics.protonpack.StreamUtils;
|
||||
import com.codepoetics.protonpack.collectors.CollectorUtils;
|
||||
import com.codepoetics.protonpack.collectors.NonUniqueValueException;
|
||||
import com.codepoetics.protonpack.selectors.Selector;
|
||||
import com.codepoetics.protonpack.selectors.Selectors;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
@ -21,7 +20,6 @@ import static java.util.Arrays.stream;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ProtonpackUnitTest {
|
||||
@Test
|
||||
public void whenTakeWhile_thenTakenWhile() {
|
||||
|
@ -39,17 +37,18 @@ public class ProtonpackUnitTest {
|
|||
|
||||
@Test
|
||||
public void givenMultipleStream_whenZipped_thenZipped() {
|
||||
String[] clubs = { "Juventus", "Barcelona", "Liverpool", "PSG" };
|
||||
String[] players = { "Ronaldo", "Messi", "Salah" };
|
||||
Set<String> zippedFrom2Sources = StreamUtils.zip(stream(clubs), stream(players), (club, player) -> club + " " + player)
|
||||
.collect(Collectors.toSet());
|
||||
String[] clubs = {"Juventus", "Barcelona", "Liverpool", "PSG"};
|
||||
String[] players = {"Ronaldo", "Messi", "Salah"};
|
||||
Set<String> zippedFrom2Sources = StreamUtils
|
||||
.zip(stream(clubs), stream(players), (club, player) -> club + " " + player)
|
||||
.collect(Collectors.toSet());
|
||||
assertThat(zippedFrom2Sources).contains("Juventus Ronaldo", "Barcelona Messi", "Liverpool Salah");
|
||||
|
||||
String[] leagues = { "Serie A", "La Liga", "Premier League" };
|
||||
String[] leagues = {"Serie A", "La Liga", "Premier League"};
|
||||
Set<String> zippedFrom3Sources = StreamUtils.zip(stream(clubs), stream(players), stream(leagues),
|
||||
(club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet());
|
||||
(club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet());
|
||||
assertThat(zippedFrom3Sources).contains("Juventus Ronaldo Serie A", "Barcelona Messi La Liga",
|
||||
"Liverpool Salah Premier League");
|
||||
"Liverpool Salah Premier League");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -57,7 +56,7 @@ public class ProtonpackUnitTest {
|
|||
Stream<String> streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool");
|
||||
Set<Indexed<String>> zipsWithIndex = StreamUtils.zipWithIndex(streamOfClubs).collect(Collectors.toSet());
|
||||
assertThat(zipsWithIndex).contains(Indexed.index(0, "Juventus"), Indexed.index(1, "Barcelona"),
|
||||
Indexed.index(2, "Liverpool"));
|
||||
Indexed.index(2, "Liverpool"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -67,9 +66,10 @@ public class ProtonpackUnitTest {
|
|||
Stream<String> streamOfLeagues = Stream.of("Serie A", "La Liga", "Premier League");
|
||||
|
||||
Set<String> merged = StreamUtils.merge(() -> "", (valOne, valTwo) -> valOne + " " + valTwo, streamOfClubs,
|
||||
streamOfPlayers, streamOfLeagues).collect(Collectors.toSet());
|
||||
streamOfPlayers, streamOfLeagues).collect(Collectors.toSet());
|
||||
|
||||
assertThat(merged).contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League",
|
||||
assertThat(merged)
|
||||
.contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League",
|
||||
" PSG");
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class ProtonpackUnitTest {
|
|||
Stream<String> streamOfPlayers = Stream.of("Ronaldo", "Messi");
|
||||
|
||||
List<List<String>> mergedListOfList = StreamUtils.mergeToList(streamOfClubs, streamOfPlayers)
|
||||
.collect(Collectors.toList());
|
||||
.collect(Collectors.toList());
|
||||
assertThat(mergedListOfList.get(0)).isInstanceOf(List.class);
|
||||
assertThat(mergedListOfList.get(0)).containsExactly("Juventus", "Ronaldo");
|
||||
assertThat(mergedListOfList.get(1)).containsExactly("Barcelona", "Messi");
|
||||
|
@ -92,72 +92,67 @@ public class ProtonpackUnitTest {
|
|||
Stream<String> streamOfPlayers = Stream.of("Ronaldo", "Messi");
|
||||
Stream<String> streamOfLeagues = Stream.of("Serie A", "La Liga");
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
Selector roundRobinSelector = (o) -> {
|
||||
Object[] vals = (Object[]) o;
|
||||
while (counter.get() >= vals.length || vals[counter.get()] == null) {
|
||||
if (counter.incrementAndGet() >= vals.length)
|
||||
counter.set(0);
|
||||
}
|
||||
return counter.getAndIncrement();
|
||||
};
|
||||
Stream<String> interleavedStream = StreamUtils.interleave(roundRobinSelector, streamOfClubs, streamOfPlayers,
|
||||
streamOfLeagues);
|
||||
List<String> interleavedList = interleavedStream.collect(Collectors.toList());
|
||||
assertThat(interleavedList).containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga",
|
||||
"Liverpool");
|
||||
List<String> interleavedList = StreamUtils
|
||||
.interleave(Selectors.roundRobin(), streamOfClubs, streamOfPlayers, streamOfLeagues)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(interleavedList)
|
||||
.hasSize(7)
|
||||
.containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga", "Liverpool");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSkippedUntil_thenSkippedUntil() {
|
||||
Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
List<Integer> skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5).collect(Collectors.toList());
|
||||
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
List<Integer> skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(skippedUntilGreaterThan5).containsExactly(6, 7, 8, 9, 10);
|
||||
|
||||
List<Integer> skippedUntilLessThanEquals5 = StreamUtils.skipUntil(stream(numbers), i -> i <= 5)
|
||||
.collect(Collectors.toList());
|
||||
.collect(Collectors.toList());
|
||||
assertThat(skippedUntilLessThanEquals5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSkippedWhile_thenSkippedWhile() {
|
||||
Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
List<Integer> skippedWhileLessThanEquals5 = StreamUtils.skipWhile(stream(numbers), i -> i <= 5)
|
||||
.collect(Collectors.toList());
|
||||
.collect(Collectors.toList());
|
||||
assertThat(skippedWhileLessThanEquals5).containsExactly(6, 7, 8, 9, 10);
|
||||
|
||||
List<Integer> skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5).collect(Collectors.toList());
|
||||
List<Integer> skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(skippedWhileGreaterThan5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFibonacciGenerator_whenUnfolded_thenUnfolded() {
|
||||
AtomicInteger lastValue = new AtomicInteger(0);
|
||||
Function<Integer, Optional<Integer>> fibonacciGenerator = (i) -> (i < 10) ?
|
||||
Optional.of(i + lastValue.getAndSet(i)) :
|
||||
Optional.empty();
|
||||
Stream<Integer> unfolded = StreamUtils.unfold(2, i -> (i < 100) ? Optional.of(i * i) : Optional.empty());
|
||||
|
||||
List<Integer> fib = StreamUtils.unfold(1, fibonacciGenerator).collect(Collectors.toList());
|
||||
assertThat(fib).containsExactly(1, 1, 2, 3, 5, 8, 13);
|
||||
assertThat(unfolded.collect(Collectors.toList())).containsExactly(2, 4, 16, 256);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenWindowed_thenWindowed() {
|
||||
Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
Integer[] numbers = {1, 2, 3, 4, 5, 6, 7};
|
||||
|
||||
List<List<Integer>> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1).collect(Collectors.toList());
|
||||
assertThat(windowedWithSkip1).containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6),
|
||||
List<List<Integer>> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(windowedWithSkip1)
|
||||
.containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6),
|
||||
asList(5, 6, 7));
|
||||
|
||||
List<List<Integer>> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2).collect(Collectors.toList());
|
||||
List<List<Integer>> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(windowedWithSkip2).containsExactly(asList(1, 2, 3), asList(3, 4, 5), asList(5, 6, 7));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAggregated_thenAggregated() {
|
||||
Integer[] numbers = { 1, 2, 2, 3, 4, 4, 4, 5 };
|
||||
List<List<Integer>> aggregated = StreamUtils.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0)
|
||||
.collect(Collectors.toList());
|
||||
Integer[] numbers = {1, 2, 2, 3, 4, 4, 4, 5};
|
||||
List<List<Integer>> aggregated = StreamUtils
|
||||
.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(aggregated).containsExactly(asList(1), asList(2, 2), asList(3), asList(4, 4, 4), asList(5));
|
||||
|
||||
List<List<Integer>> aggregatedFixSize = StreamUtils.aggregate(stream(numbers), 5).collect(Collectors.toList());
|
||||
|
@ -166,20 +161,20 @@ public class ProtonpackUnitTest {
|
|||
|
||||
@Test
|
||||
public void whenGroupedRun_thenGroupedRun() {
|
||||
Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
|
||||
Integer[] numbers = {1, 1, 2, 3, 4, 4, 5};
|
||||
List<List<Integer>> grouped = StreamUtils.groupRuns(stream(numbers)).collect(Collectors.toList());
|
||||
assertThat(grouped).containsExactly(asList(1, 1), asList(2), asList(3), asList(4, 4), asList(5));
|
||||
|
||||
Integer[] numbers2 = { 1, 2, 3, 1 };
|
||||
Integer[] numbers2 = {1, 2, 3, 1};
|
||||
List<List<Integer>> grouped2 = StreamUtils.groupRuns(stream(numbers2)).collect(Collectors.toList());
|
||||
assertThat(grouped2).containsExactly(asList(1), asList(2), asList(3), asList(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAggregatedOnListCondition_thenAggregatedOnListCondition() {
|
||||
Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
|
||||
Integer[] numbers = {1, 1, 2, 3, 4, 4, 5};
|
||||
Stream<List<Integer>> aggregated = StreamUtils.aggregateOnListCondition(stream(numbers),
|
||||
(currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5);
|
||||
(currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5);
|
||||
assertThat(aggregated).containsExactly(asList(1, 1, 2), asList(3), asList(4), asList(4), asList(5));
|
||||
}
|
||||
|
||||
|
@ -187,15 +182,14 @@ public class ProtonpackUnitTest {
|
|||
public void givenProjectionFunction_whenMaxedBy_thenMaxedBy() {
|
||||
Stream<String> clubs = Stream.of("Juventus", "Barcelona", "PSG");
|
||||
Optional<String> longestName = clubs.collect(CollectorUtils.maxBy(String::length));
|
||||
assertThat(longestName.get()).isEqualTo("Barcelona");
|
||||
assertThat(longestName).contains("Barcelona");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStreamOfMultipleElem_whenUniqueCollector_thenValueReturned() {
|
||||
Stream<Integer> singleElement = Stream.of(1);
|
||||
Optional<Integer> unique = singleElement.collect(CollectorUtils.unique());
|
||||
assertThat(unique.get()).isEqualTo(1);
|
||||
|
||||
assertThat(unique).contains(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -205,5 +199,4 @@ public class ProtonpackUnitTest {
|
|||
multipleElement.collect(CollectorUtils.unique());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,6 +68,21 @@
|
|||
<artifactId>emoji-java</artifactId>
|
||||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Added for password generation -->
|
||||
<dependency>
|
||||
<groupId>org.passay</groupId>
|
||||
|
@ -79,6 +94,7 @@
|
|||
<artifactId>commons-text</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -115,4 +131,4 @@
|
|||
<guava.version>26.0-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.string.searching;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WordIndexer {
|
||||
|
||||
public List<Integer> findWord(String textString, String word) {
|
||||
int index = 0;
|
||||
List<Integer> indexes = new ArrayList<Integer>();
|
||||
String lowerCaseTextString = textString.toLowerCase();
|
||||
String lowerCaseWord = word.toLowerCase();
|
||||
|
||||
while(index != -1){
|
||||
index = lowerCaseTextString.indexOf(lowerCaseWord, index + 1);
|
||||
if (index != -1) {
|
||||
indexes.add(index);
|
||||
}
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<Integer> findWordUpgrade(String textString, String word) {
|
||||
int index = 0;
|
||||
List<Integer> indexes = new ArrayList<Integer>();
|
||||
StringBuilder output = new StringBuilder();
|
||||
String lowerCaseTextString = textString.toLowerCase();
|
||||
String lowerCaseWord = word.toLowerCase();
|
||||
int wordLength = 0;
|
||||
|
||||
while(index != -1){
|
||||
index = lowerCaseTextString.indexOf(lowerCaseWord, index + wordLength); // Slight improvement
|
||||
if (index != -1) {
|
||||
indexes.add(index);
|
||||
}
|
||||
wordLength = word.length();
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.baeldung.string.searching;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
public class WordIndexerUnitTest {
|
||||
|
||||
String theString;
|
||||
WordIndexer wordIndexer;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
wordIndexer = new WordIndexer();
|
||||
|
||||
theString = "To be, or not to be: that is the question: "
|
||||
+ "Whether 'tis nobler in the mind to suffer "
|
||||
+ "The slings and arrows of outrageous fortune, "
|
||||
+ "Or to take arms against a sea of troubles, "
|
||||
+ "And by opposing end them? To die: to sleep; "
|
||||
+ "No more; and by a sleep to say we end "
|
||||
+ "The heart-ache and the thousand natural shocks "
|
||||
+ "That flesh is heir to, 'tis a consummation "
|
||||
+ "Devoutly to be wish'd. To die, to sleep; "
|
||||
+ "To sleep: perchance to dream: ay, there's the rub: "
|
||||
+ "For in that sleep of death what dreams may come,";
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
public void givenWord_whenSearching_thenFindAllIndexedLocations() {
|
||||
List<Integer> expectedResult = Arrays.asList(7, 122, 130, 221, 438);
|
||||
|
||||
List<Integer> actualResult = wordIndexer.findWord(theString, "or");
|
||||
|
||||
assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenWordWithNoRepeatCharacters_whenImprovedSearching_thenFindAllIndexedLocations() {
|
||||
List<Integer> expectedResult = Arrays.asList(7, 122, 130, 221, 438);
|
||||
|
||||
List<Integer> actualResult = wordIndexer.findWordUpgrade(theString, "or");
|
||||
|
||||
assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenWord_whenSearching_thenFindAtEndOfString() {
|
||||
List<Integer> expectedResult = Arrays.asList(480);
|
||||
|
||||
List<Integer> actualResult = wordIndexer.findWordUpgrade(theString, "come,");
|
||||
|
||||
assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
}
|
|
@ -22,16 +22,6 @@
|
|||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator-annotation-processor</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>javax.el-api</artifactId>
|
||||
<version>${javax.el-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.el</artifactId>
|
||||
|
@ -60,13 +50,11 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<validation-api.version>2.0.1.Final</validation-api.version>
|
||||
<hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
|
||||
<javax.el-api.version>3.0.0</javax.el-api.version>
|
||||
<javax.el.version>3.0.0</javax.el.version>
|
||||
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
</properties>
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.jsonjava;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class JSONArrayGetValueByKey {
|
||||
|
||||
public List<String> getValuesByKeyInJSONArray(String jsonArrayStr, String key) {
|
||||
List<String> values = new ArrayList<>();
|
||||
JSONArray jsonArray = new JSONArray(jsonArrayStr);
|
||||
for (int idx = 0; idx < jsonArray.length(); idx++) {
|
||||
JSONObject jsonObj = jsonArray.getJSONObject(idx);
|
||||
values.add(jsonObj.optString(key));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public List<String> getValuesByKeyInJSONArrayUsingJava8(String jsonArrayStr, String key) {
|
||||
JSONArray jsonArray = new JSONArray(jsonArrayStr);
|
||||
return IntStream.range(0, jsonArray.length())
|
||||
.mapToObj(index -> ((JSONObject) jsonArray.get(index)).optString(key))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.jsonjava;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
||||
public class JSONArrayGetValueByKeyUnitTest {
|
||||
|
||||
private static final JSONArrayGetValueByKey obj = new JSONArrayGetValueByKey();
|
||||
|
||||
@Test
|
||||
public void givenJSONArrayAndAKey_thenReturnAllValuesForGivenKey() {
|
||||
String jsonStr = "[" + " {" + " \"name\": \"John\"," + " \"city\": \"chicago\"," + " \"age\": \"22\" " + "}," + " { " + "\"name\": \"Gary\"," + " \"city\": \"florida\"," + " \"age\": \"35\" " + "}," + " { " + "\"name\": \"Selena\","
|
||||
+ " \"city\": \"vegas\"," + " \"age\": \"18\" " + "} " + "]";
|
||||
|
||||
List<String> actualValues = obj.getValuesByKeyInJSONArray(jsonStr, "name");
|
||||
|
||||
assertThat(actualValues, equalTo(Arrays.asList("John", "Gary", "Selena")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJSONArrayAndAKey_whenUsingJava8Syntax_thenReturnAllValuesForGivenKey() {
|
||||
String jsonStr = "[" + " {" + " \"name\": \"John\"," + " \"city\": \"chicago\"," + " \"age\": \"22\" " + "}," + " { " + "\"name\": \"Gary\"," + " \"city\": \"florida\"," + " \"age\": \"35\" " + "}," + " { " + "\"name\": \"Selena\","
|
||||
+ " \"city\": \"vegas\"," + " \"age\": \"18\" " + "} " + "]";
|
||||
|
||||
List<String> actualValues = obj.getValuesByKeyInJSONArrayUsingJava8(jsonStr, "name");
|
||||
|
||||
assertThat(actualValues, equalTo(Arrays.asList("John", "Gary", "Selena")));
|
||||
}
|
||||
|
||||
}
|
|
@ -259,6 +259,11 @@
|
|||
<artifactId>slf4j-api</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.storm</groupId>
|
||||
<artifactId>storm-core</artifactId>
|
||||
<version>${storm.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
|
@ -432,6 +437,7 @@
|
|||
</repositories>
|
||||
|
||||
<properties>
|
||||
<storm.version>1.2.2</storm.version>
|
||||
<kryo.version>4.0.1</kryo.version>
|
||||
<h2.version>1.4.196</h2.version>
|
||||
<reladomo.version>16.5.1</reladomo.version>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.storm;
|
||||
|
||||
import com.baeldung.storm.bolt.AggregatingBolt;
|
||||
import com.baeldung.storm.bolt.FileWritingBolt;
|
||||
import com.baeldung.storm.bolt.FilteringBolt;
|
||||
import com.baeldung.storm.bolt.PrintingBolt;
|
||||
import com.baeldung.storm.spout.RandomNumberSpout;
|
||||
import org.apache.storm.Config;
|
||||
import org.apache.storm.LocalCluster;
|
||||
import org.apache.storm.topology.TopologyBuilder;
|
||||
import org.apache.storm.topology.base.BaseWindowedBolt;
|
||||
|
||||
public class TopologyRunner {
|
||||
public static void main(String[] args) {
|
||||
runTopology();
|
||||
}
|
||||
|
||||
public static void runTopology() {
|
||||
String filePath = "./src/main/resources/operations.txt";
|
||||
TopologyBuilder builder = new TopologyBuilder();
|
||||
builder.setSpout("randomNumberSpout", new RandomNumberSpout());
|
||||
builder.setBolt("filteringBolt", new FilteringBolt()).shuffleGrouping("randomNumberSpout");
|
||||
builder.setBolt("aggregatingBolt", new AggregatingBolt()
|
||||
.withTimestampField("timestamp")
|
||||
.withLag(BaseWindowedBolt.Duration.seconds(1))
|
||||
.withWindow(BaseWindowedBolt.Duration.seconds(5))).shuffleGrouping("filteringBolt");
|
||||
builder.setBolt("fileBolt", new FileWritingBolt(filePath)).shuffleGrouping("aggregatingBolt");
|
||||
|
||||
Config config = new Config();
|
||||
config.setDebug(false);
|
||||
LocalCluster cluster = new LocalCluster();
|
||||
cluster.submitTopology("Test", config, builder.createTopology());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.baeldung.storm.bolt;
|
||||
|
||||
import org.apache.storm.task.OutputCollector;
|
||||
import org.apache.storm.task.TopologyContext;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseWindowedBolt;
|
||||
import org.apache.storm.tuple.Fields;
|
||||
import org.apache.storm.tuple.Tuple;
|
||||
import org.apache.storm.tuple.Values;
|
||||
import org.apache.storm.windowing.TupleWindow;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AggregatingBolt extends BaseWindowedBolt {
|
||||
private OutputCollector outputCollector;
|
||||
@Override
|
||||
public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
|
||||
this.outputCollector = collector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer declarer) {
|
||||
declarer.declare(new Fields("sumOfOperations", "beginningTimestamp", "endTimestamp"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(TupleWindow tupleWindow) {
|
||||
List<Tuple> tuples = tupleWindow.get();
|
||||
tuples.sort(Comparator.comparing(a -> a.getLongByField("timestamp")));
|
||||
//This is safe since the window is calculated basing on Tuple's timestamp, thus it can't really be empty
|
||||
Long beginningTimestamp = tuples.get(0).getLongByField("timestamp");
|
||||
Long endTimestamp = tuples.get(tuples.size() - 1).getLongByField("timestamp");
|
||||
int sumOfOperations = tuples.stream().mapToInt(tuple -> tuple.getIntegerByField("operation")).sum();
|
||||
Values values = new Values(sumOfOperations, beginningTimestamp, endTimestamp);
|
||||
outputCollector.emit(values);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.baeldung.storm.bolt;
|
||||
|
||||
import com.baeldung.storm.model.AggregatedWindow;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.storm.task.OutputCollector;
|
||||
import org.apache.storm.task.TopologyContext;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseRichBolt;
|
||||
import org.apache.storm.tuple.Tuple;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
public class FileWritingBolt extends BaseRichBolt {
|
||||
public static Logger logger = LoggerFactory.getLogger(FileWritingBolt.class);
|
||||
private BufferedWriter writer;
|
||||
private String filePath;
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Override
|
||||
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
|
||||
objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||
try {
|
||||
writer = new BufferedWriter(new FileWriter(filePath));
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to open a file for writing.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Tuple tuple) {
|
||||
int sumOfOperations = tuple.getIntegerByField("sumOfOperations");
|
||||
long beginningTimestamp = tuple.getLongByField("beginningTimestamp");
|
||||
long endTimestamp = tuple.getLongByField("endTimestamp");
|
||||
|
||||
if(sumOfOperations > 200) {
|
||||
AggregatedWindow aggregatedWindow = new AggregatedWindow(sumOfOperations, beginningTimestamp, endTimestamp);
|
||||
try {
|
||||
writer.write(objectMapper.writeValueAsString(aggregatedWindow));
|
||||
writer.write("\n");
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to write data to file.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FileWritingBolt(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to close the writer!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.storm.bolt;
|
||||
|
||||
import org.apache.storm.topology.BasicOutputCollector;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseBasicBolt;
|
||||
import org.apache.storm.tuple.Fields;
|
||||
import org.apache.storm.tuple.Tuple;
|
||||
|
||||
public class FilteringBolt extends BaseBasicBolt {
|
||||
@Override
|
||||
public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
|
||||
int operation = tuple.getIntegerByField("operation");
|
||||
if(operation > 0 ) {
|
||||
basicOutputCollector.emit(tuple.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
|
||||
outputFieldsDeclarer.declare(new Fields("operation", "timestamp"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.storm.bolt;
|
||||
|
||||
import org.apache.storm.topology.BasicOutputCollector;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseBasicBolt;
|
||||
import org.apache.storm.tuple.Tuple;
|
||||
|
||||
public class PrintingBolt extends BaseBasicBolt {
|
||||
@Override
|
||||
public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
|
||||
System.out.println(tuple);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.storm.model;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize
|
||||
public class AggregatedWindow {
|
||||
int sumOfOperations;
|
||||
long beginningTimestamp;
|
||||
long endTimestamp;
|
||||
|
||||
public AggregatedWindow(int sumOfOperations, long beginningTimestamp, long endTimestamp) {
|
||||
this.sumOfOperations = sumOfOperations;
|
||||
this.beginningTimestamp = beginningTimestamp;
|
||||
this.endTimestamp = endTimestamp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.storm.model;
|
||||
|
||||
public class User {
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private int age;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.storm.serialization;
|
||||
|
||||
|
||||
import com.baeldung.storm.model.User;
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
import com.esotericsoftware.kryo.Serializer;
|
||||
import com.esotericsoftware.kryo.io.Input;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
|
||||
public class UserSerializer extends Serializer<User>{
|
||||
@Override
|
||||
public void write(Kryo kryo, Output output, User user) {
|
||||
output.writeString(user.getEmail());
|
||||
output.writeString(user.getUsername());
|
||||
output.write(user.getAge());
|
||||
}
|
||||
|
||||
@Override
|
||||
public User read(Kryo kryo, Input input, Class<User> aClass) {
|
||||
User user = new User();
|
||||
String email = input.readString();
|
||||
String name = input.readString();
|
||||
int age = input.read();
|
||||
user.setAge(age);
|
||||
user.setEmail(email);
|
||||
user.setUsername(name);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.storm.spout;
|
||||
|
||||
import org.apache.storm.spout.SpoutOutputCollector;
|
||||
import org.apache.storm.task.TopologyContext;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseRichSpout;
|
||||
import org.apache.storm.tuple.Fields;
|
||||
import org.apache.storm.tuple.Values;
|
||||
import org.apache.storm.utils.Utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomIntSpout extends BaseRichSpout {
|
||||
|
||||
private Random random;
|
||||
private SpoutOutputCollector outputCollector;
|
||||
|
||||
@Override
|
||||
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
|
||||
random = new Random();
|
||||
outputCollector = spoutOutputCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextTuple() {
|
||||
Utils.sleep(1000);
|
||||
outputCollector.emit(new Values(random.nextInt(), System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
|
||||
outputFieldsDeclarer.declare(new Fields("randomInt", "timestamp"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.baeldung.storm.spout;
|
||||
|
||||
import org.apache.storm.spout.SpoutOutputCollector;
|
||||
import org.apache.storm.task.OutputCollector;
|
||||
import org.apache.storm.task.TopologyContext;
|
||||
import org.apache.storm.topology.OutputFieldsDeclarer;
|
||||
import org.apache.storm.topology.base.BaseRichSpout;
|
||||
import org.apache.storm.tuple.Fields;
|
||||
import org.apache.storm.tuple.Values;
|
||||
import org.apache.storm.utils.Utils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomNumberSpout extends BaseRichSpout {
|
||||
private Random random;
|
||||
private SpoutOutputCollector collector;
|
||||
|
||||
@Override
|
||||
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
|
||||
random = new Random();
|
||||
collector = spoutOutputCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextTuple() {
|
||||
Utils.sleep(1000);
|
||||
//This will select random int from the range (0, 100)
|
||||
int operation = random.nextInt(101);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
Values values = new Values(operation, timestamp);
|
||||
collector.emit(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
|
||||
outputFieldsDeclarer.declare(new Fields("operation", "timestamp"));
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Guide to ScribeJava](https://www.baeldung.com/scribejava)
|
||||
- [Guide to Passay](https://www.baeldung.com/java-passay)
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
- [Using Lombok’s @Builder Annotation](http://www.baeldung.com/lombok-builder)
|
||||
- [Using Lombok’s @Getter for Boolean Fields](https://www.baeldung.com/lombok-getter-boolean)
|
||||
- [Lombok @Builder with Inheritance](https://www.baeldung.com/lombok-builder-inheritance)
|
||||
- [Lombok Builder with Default Value](https://www.baeldung.com/lombok-builder-default-value)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
To run the maven-polyglot-json-app successfully, you first have to build the maven-polyglot-json-extension module using: mvn clean install.
|
||||
|
||||
Related Articles:
|
||||
### Relevant Articles:
|
||||
- [Maven Polyglot](https://www.baeldung.com/maven-polyglot)
|
||||
|
|
|
@ -10,3 +10,6 @@
|
|||
- [Build a Jar with Maven and Ignore the Test Results](http://www.baeldung.com/maven-ignore-test-results)
|
||||
- [Maven Project with Multiple Source Directories](https://www.baeldung.com/maven-project-multiple-src-directories)
|
||||
- [Integration Testing with Maven](https://www.baeldung.com/maven-integration-test)
|
||||
- [Apache Maven Standard Directory Layout](https://www.baeldung.com/maven-directory-structure)
|
||||
- [Apache Maven Tutorial](https://www.baeldung.com/maven)
|
||||
- [Use the Latest Version of a Dependency in Maven](https://www.baeldung.com/maven-dependency-latest-version)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [SHA-256 Hashing in Java](http://www.baeldung.com/sha-256-hashing-java)
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [A Guide to Java Enums](http://www.baeldung.com/a-guide-to-java-enums)
|
|
@ -1,5 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [A Guide To UDP In Java](http://www.baeldung.com/udp-in-java)
|
||||
- [A Guide To HTTP Cookies In Java](http://www.baeldung.com/cookies-java)
|
||||
- [A Guide to the Java URL](http://www.baeldung.com/java-url)
|
||||
- [Working with Network Interfaces in Java](http://www.baeldung.com/java-network-interfaces)
|
|
@ -1 +0,0 @@
|
|||
Premain-class: com.baeldung.objectsize.InstrumentationAgent
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [How to Print Screen in Java](http://www.baeldung.com/print-screen-in-java)
|
|
@ -1,2 +0,0 @@
|
|||
-d javac-target -verbose
|
||||
com/baeldung/javac/Data.java
|
|
@ -1,2 +0,0 @@
|
|||
-d javac-target
|
||||
-verbose
|
|
@ -1 +0,0 @@
|
|||
com/baeldung/javac/Data.java
|
|
@ -1,3 +0,0 @@
|
|||
-d javac-target
|
||||
-Xlint:rawtypes,unchecked,static,cast,serial,fallthrough
|
||||
com/baeldung/javac/Data.java
|
|
@ -1,9 +0,0 @@
|
|||
# Set root logger level to DEBUG and its only appender to A1.
|
||||
log4j.rootLogger=DEBUG, A1
|
||||
|
||||
# A1 is set to be a ConsoleAppender.
|
||||
log4j.appender.A1=org.apache.log4j.ConsoleAppender
|
||||
|
||||
# A1 uses PatternLayout.
|
||||
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro)
|
|
@ -1,2 +0,0 @@
|
|||
### Relevant Articles:
|
||||
- [Convert Hex to ASCII in Java](http://www.baeldung.com/java-convert-hex-to-ascii)
|
|
@ -1,2 +0,0 @@
|
|||
Relevant Articles:
|
||||
- [Java String Conversions](http://www.baeldung.com/java-string-conversions)
|
Binary file not shown.
|
@ -42,6 +42,10 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<configuration>
|
||||
<mainClass>${start-class}</mainClass>
|
||||
<!-- this is necessary as we're not using the Boot parent -->
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
|
|
@ -22,7 +22,18 @@
|
|||
<id>kotlin-ktor</id>
|
||||
<url>https://dl.bintray.com/kotlin/ktor/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>kotlin-eap</id>
|
||||
<url>http://dl.bintray.com/kotlin/kotlin-eap</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>kotlin-eap</id>
|
||||
<url>http://dl.bintray.com/kotlin/kotlin-eap</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
@ -42,6 +53,11 @@
|
|||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
|
@ -157,6 +173,7 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<dependencies>
|
||||
|
@ -185,8 +202,8 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<kotlin.version>1.2.61</kotlin.version>
|
||||
<kotlinx.version>0.25.0</kotlinx.version>
|
||||
<kotlin.version>1.3.0-rc-146</kotlin.version>
|
||||
<kotlinx.version>0.26.1-eap13</kotlinx.version>
|
||||
<ktor.io.version>0.9.3</ktor.io.version>
|
||||
<assertj.version>3.11.0</assertj.version>
|
||||
<junit.platform.version>1.2.0</junit.platform.version>
|
||||
|
|
|
@ -17,3 +17,4 @@
|
|||
- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class)
|
||||
- [@JoinColumn Annotation Explained](https://www.baeldung.com/jpa-join-column)
|
||||
- [Hibernate 5 Naming Strategy Configuration](https://www.baeldung.com/hibernate-naming-strategy)
|
||||
- [Proxy in Hibernate load() Method](https://www.baeldung.com/hibernate-proxy-load-method)
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.time.LocalDate;
|
|||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
|
||||
public class HibernateCustomTypesUnitTest {
|
||||
public class HibernateCustomTypesManualTest {
|
||||
|
||||
@Test
|
||||
public void givenEmployee_whenSavedWithCustomTypes_thenEntityIsSaved() throws IOException {
|
|
@ -23,7 +23,7 @@
|
|||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<!-- The main class to start by executing java -jar -->
|
||||
<start-class>com.mycorp.starter.HelloWorldApplication</start-class>
|
||||
<start-class>com.baeldung.h2db.demo.server.SpringBootApp</start-class>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -16,22 +16,35 @@
|
|||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2database.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-jdbc</artifactId>
|
||||
<version>${tomcat-jdbc.version}</version>
|
||||
|
@ -41,20 +54,14 @@
|
|||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${mysql-connector-java.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>${h2database.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<mysql-connector-java.version>8.0.12</mysql-connector-java.version>
|
||||
<tomcat-jdbc.version>9.0.10</tomcat-jdbc.version>
|
||||
<h2database.version>1.4.197</h2database.version>
|
||||
<mockito.version>2.23.0</mockito.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.springbootcrudapp.application;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan(basePackages={"com.baeldung.springbootcrudapp.application"})
|
||||
@EnableJpaRepositories(basePackages="com.baeldung.springbootcrudapp.application.repositories")
|
||||
@EnableTransactionManagement
|
||||
@EntityScan(basePackages="com.baeldung.springbootcrudapp.application.entities")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.springbootcrudapp.application.controllers;
|
||||
|
||||
import com.baeldung.springbootcrudapp.application.repositories.UserRepository;
|
||||
import com.baeldung.springbootcrudapp.application.entities.User;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
@Controller
|
||||
public class UserController {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
public UserController(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/signup")
|
||||
public String showSignUpForm(User user) {
|
||||
return "add-user";
|
||||
}
|
||||
|
||||
@PostMapping("/adduser")
|
||||
public String addUser(@Valid User user, BindingResult result, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
return "add-user";
|
||||
}
|
||||
|
||||
userRepository.save(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
public String showUpdateForm(@PathVariable("id") long id, Model model) {
|
||||
User user = userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
|
||||
model.addAttribute("user", user);
|
||||
return "update-user";
|
||||
}
|
||||
|
||||
@PostMapping("/update/{id}")
|
||||
public String updateUser(@PathVariable("id") long id, @Valid User user, BindingResult result, Model model) {
|
||||
if (result.hasErrors()) {
|
||||
user.setId(id);
|
||||
return "update-user";
|
||||
}
|
||||
|
||||
userRepository.save(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
public String deleteUser(@PathVariable("id") long id, Model model) {
|
||||
User user = userRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id));
|
||||
userRepository.delete(user);
|
||||
model.addAttribute("users", userRepository.findAll());
|
||||
return "index";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package com.baeldung.springbootcrudapp.application.entities;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
@NotBlank(message = "Name is mandatory")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "Email is mandatory")
|
||||
private String email;
|
||||
|
||||
public User() {}
|
||||
|
||||
public User(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" + "id=" + id + ", name=" + name + ", email=" + email + '}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.springbootcrudapp.application.repositories;
|
||||
|
||||
import com.baeldung.springbootcrudapp.application.entities.User;
|
||||
import java.util.List;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends CrudRepository<User, Long> {
|
||||
|
||||
List<User> findByName(String name);
|
||||
|
||||
}
|
2
persistence-modules/spring-boot-persistence/src/main/resources/css/shards.min.css
vendored
Normal file
2
persistence-modules/spring-boot-persistence/src/main/resources/css/shards.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Add User</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container my-5">
|
||||
<h2 class="mb-5">New User</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form action="#" th:action="@{/adduser}" th:object="${user}" method="post">
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="name" class="col-form-label">Name</label>
|
||||
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name">
|
||||
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="email" class="col-form-label">Email</label>
|
||||
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email">
|
||||
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mt-5">
|
||||
<input type="submit" class="btn btn-primary" value="Add User">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Users</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div th:switch="${users}" class="container my-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h2 th:case="null">No users yet!</h2>
|
||||
<div th:case="*">
|
||||
<h2 class="my-5">Users</h2>
|
||||
<table class="table table-striped table-responsive-md">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Edit</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="user : ${users}">
|
||||
<td th:text="${user.name}"></td>
|
||||
<td th:text="${user.email}"></td>
|
||||
<td><a th:href="@{/edit/{id}(id=${user.id})}" class="btn btn-primary"><i class="fas fa-user-edit ml-2"></i></a></td>
|
||||
<td><a th:href="@{/delete/{id}(id=${user.id})}" class="btn btn-primary"><i class="fas fa-user-times ml-2"></i></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="my-5"><a href="/signup" class="btn btn-primary"><i class="fas fa-user-plus ml-2"></i></a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<title>Update User</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css" integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="../css/shards.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container my-5">
|
||||
<h2 class="mb-5">Update User</h2>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<form action="#" th:action="@{/update/{id}(id=${user.id})}" th:object="${user}" method="post">
|
||||
<div class="row">
|
||||
<div class="form-group col-md-6">
|
||||
<label for="name" class="col-form-label">Name</label>
|
||||
<input type="text" th:field="*{name}" class="form-control" id="name" placeholder="Name">
|
||||
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group col-md-6">
|
||||
<label for="email" class="col-form-label">Email</label>
|
||||
<input type="text" th:field="*{email}" class="form-control" id="email" placeholder="Email">
|
||||
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 mt-5">
|
||||
<input type="submit" class="btn btn-primary" value="Update User">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,81 @@
|
|||
package com.baeldung.springbootcrudapp.application.tests;
|
||||
|
||||
import com.baeldung.springbootcrudapp.application.controllers.UserController;
|
||||
import com.baeldung.springbootcrudapp.application.entities.User;
|
||||
import com.baeldung.springbootcrudapp.application.repositories.UserRepository;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
||||
public class UserControllerUnitTest {
|
||||
|
||||
private static UserController userController;
|
||||
private static UserRepository mockedUserRepository;
|
||||
private static BindingResult mockedBindingResult;
|
||||
private static Model mockedModel;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpUserControllerInstance() {
|
||||
mockedUserRepository = mock(UserRepository.class);
|
||||
mockedBindingResult = mock(BindingResult.class);
|
||||
mockedModel = mock(Model.class);
|
||||
userController = new UserController(mockedUserRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledshowSignUpForm_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
assertThat(userController.showSignUpForm(user)).isEqualTo("add-user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledaddUserAndValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(false);
|
||||
|
||||
assertThat(userController.addUser(user, mockedBindingResult, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledaddUserAndInValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(true);
|
||||
|
||||
assertThat(userController.addUser(user, mockedBindingResult, mockedModel)).isEqualTo("add-user");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenCalledshowUpdateForm_thenIllegalArgumentException() {
|
||||
assertThat(userController.showUpdateForm(0, mockedModel)).isEqualTo("update-user");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledupdateUserAndValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(false);
|
||||
|
||||
assertThat(userController.updateUser(1l, user, mockedBindingResult, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledupdateUserAndInValidUser_thenCorrect() {
|
||||
User user = new User("John", "john@domain.com");
|
||||
|
||||
when(mockedBindingResult.hasErrors()).thenReturn(true);
|
||||
|
||||
assertThat(userController.updateUser(1l, user, mockedBindingResult, mockedModel)).isEqualTo("update-user");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void whenCalleddeleteUser_thenIllegalArgumentException() {
|
||||
assertThat(userController.deleteUser(1l, mockedModel)).isEqualTo("index");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.springbootcrudapp.application.tests;
|
||||
|
||||
import com.baeldung.springbootcrudapp.application.entities.User;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UserUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenCalledGetName_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
assertThat(user.getName()).isEqualTo("Julie");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledGetEmail_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
assertThat(user.getEmail()).isEqualTo("julie@domain.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledSetName_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
user.setName("John");
|
||||
|
||||
assertThat(user.getName()).isEqualTo("John");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledSetEmail_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
|
||||
user.setEmail("john@domain.com");
|
||||
|
||||
assertThat(user.getEmail()).isEqualTo("john@domain.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCalledtoString_thenCorrect() {
|
||||
User user = new User("Julie", "julie@domain.com");
|
||||
assertThat(user.toString()).isEqualTo("User{id=0, name=Julie, email=julie@domain.com}");
|
||||
}
|
||||
}
|
|
@ -11,3 +11,4 @@
|
|||
- [Introduction to Spring Data MongoDB](http://www.baeldung.com/spring-data-mongodb-tutorial)
|
||||
- [Spring Data MongoDB: Projections and Aggregations](http://www.baeldung.com/spring-data-mongodb-projections-aggregations)
|
||||
- [Spring Data Annotations](http://www.baeldung.com/spring-data-annotations)
|
||||
- [Spring Data MongoDB Transactions](https://www.baeldung.com/spring-data-mongodb-transactions )
|
||||
|
|
|
@ -23,23 +23,19 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@PropertySource({ "classpath:persistence-jndi.properties" })
|
||||
@ComponentScan({ "org.baeldung.persistence" })
|
||||
@PropertySource("classpath:persistence-jndi.properties")
|
||||
@ComponentScan("org.baeldung.persistence")
|
||||
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao")
|
||||
public class PersistenceJNDIConfig {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
public PersistenceJNDIConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
|
||||
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
|
||||
em.setDataSource(dataSource());
|
||||
em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" });
|
||||
em.setPackagesToScan("org.baeldung.persistence.model");
|
||||
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
|
||||
em.setJpaProperties(additionalProperties());
|
||||
return em;
|
||||
|
@ -52,9 +48,7 @@ public class PersistenceJNDIConfig {
|
|||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
|
||||
final JpaTransactionManager transactionManager = new JpaTransactionManager();
|
||||
transactionManager.setEntityManagerFactory(emf);
|
||||
return transactionManager;
|
||||
return new JpaTransactionManager(emf);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
|
|
@ -25,7 +25,7 @@ public class Foo implements Serializable {
|
|||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@Column(name = "ID")
|
||||
private long id;
|
||||
private Long id;
|
||||
@Column(name = "NAME")
|
||||
private String name;
|
||||
|
||||
|
@ -41,11 +41,11 @@ public class Foo implements Serializable {
|
|||
this.bar = bar;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final int id) {
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
|
44
pom.xml
44
pom.xml
|
@ -517,25 +517,7 @@
|
|||
<module>spring-jms</module>
|
||||
<module>spring-jooq</module>
|
||||
<module>persistence-modules/spring-jpa</module>
|
||||
<module>spring-kafka</module>
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-ldap</module>
|
||||
<module>spring-mockito</module>
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-forms-thymeleaf</module>
|
||||
<module>spring-mvc-java</module>
|
||||
<module>spring-mvc-velocity</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-mvc-kotlin</module>
|
||||
<module>spring-protobuf</module>
|
||||
<module>spring-quartz</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-full</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<!-- <module>spring-rest</module> --> <!-- temporarily disabled -->
|
||||
<!-- <module>spring-rest-simple</module> --> <!-- temporarily disabled -->
|
||||
<module>spring-resttemplate</module>
|
||||
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
@ -661,7 +643,6 @@
|
|||
<module>spring-boot-autoconfiguration</module>
|
||||
<module>spring-boot-custom-starter</module>
|
||||
<module>spring-boot-jasypt</module>
|
||||
<module>spring-custom-aop</module>
|
||||
<module>spring-data-rest-querydsl</module>
|
||||
<module>spring-groovy</module>
|
||||
<module>spring-mobile</module>
|
||||
|
@ -730,7 +711,27 @@
|
|||
<module>spring-security-rest-custom</module>
|
||||
<module>spring-security-rest</module>
|
||||
<module>spring-security-sso</module>
|
||||
<module>spring-security-x509</module>
|
||||
<module>spring-security-x509</module>
|
||||
|
||||
<module>spring-kafka</module>
|
||||
<module>spring-katharsis</module>
|
||||
<module>spring-ldap</module>
|
||||
<module>spring-mockito</module>
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-forms-thymeleaf</module>
|
||||
<module>spring-mvc-java</module>
|
||||
<module>spring-mvc-velocity</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-mvc-kotlin</module>
|
||||
<module>spring-protobuf</module>
|
||||
<module>spring-quartz</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-full</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<!-- <module>spring-rest</module> --> <!-- temporarily disabled -->
|
||||
<!-- <module>spring-rest-simple</module> --> <!-- temporarily disabled -->
|
||||
<module>spring-resttemplate</module>
|
||||
</modules>
|
||||
|
||||
</profile>
|
||||
|
@ -1159,7 +1160,6 @@
|
|||
<module>spring-boot-autoconfiguration</module>
|
||||
<module>spring-boot-custom-starter</module>
|
||||
<module>spring-boot-jasypt</module>
|
||||
<module>spring-custom-aop</module>
|
||||
<module>spring-data-rest-querydsl</module>
|
||||
<module>spring-groovy</module>
|
||||
<module>spring-mobile</module>
|
||||
|
|
|
@ -1,44 +1,22 @@
|
|||
package com.baeldung.reactor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class ItemProducerCreate {
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(NetworTrafficProducerPush.class);
|
||||
public class ItemProducerCreate {
|
||||
|
||||
Consumer<List<String>> listener;
|
||||
|
||||
public void create() {
|
||||
public Flux<String> create() {
|
||||
Flux<String> articlesFlux = Flux.create((sink) -> {
|
||||
ItemProducerCreate.this.listener = (items) -> {
|
||||
items.stream()
|
||||
.forEach(article -> sink.next(article));
|
||||
};
|
||||
});
|
||||
articlesFlux.subscribe(ItemProducerCreate.this.logger::info);
|
||||
return articlesFlux;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ItemProducerCreate producer = new ItemProducerCreate();
|
||||
producer.create();
|
||||
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<String> items = new ArrayList<>();
|
||||
items.add("Item 1");
|
||||
items.add("Item 2");
|
||||
items.add("Item 3");
|
||||
producer.listener.accept(items);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
package com.baeldung.reactor;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.FluxSink.OverflowStrategy;
|
||||
|
||||
public class NetworTrafficProducerPush {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(NetworTrafficProducerPush.class);
|
||||
|
||||
Consumer<String> listener;
|
||||
|
||||
public void subscribe(Consumer<String> consumer) {
|
||||
Flux<String> flux = Flux.push(sink -> {
|
||||
NetworTrafficProducerPush.this.listener = (t) -> sink.next(t);
|
||||
}, OverflowStrategy.DROP);
|
||||
flux.subscribe(consumer);
|
||||
}
|
||||
|
||||
public void onPacket(String packet) {
|
||||
listener.accept(packet);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
NetworTrafficProducerPush trafficProducer = new NetworTrafficProducerPush();
|
||||
trafficProducer.subscribe(trafficProducer.logger::info);
|
||||
trafficProducer.onPacket("Packet[A18]");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.reactor;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.FluxSink.OverflowStrategy;
|
||||
|
||||
public class NetworkTrafficProducerPush {
|
||||
|
||||
Consumer<String> listener;
|
||||
|
||||
public void subscribe(Consumer<String> consumer) {
|
||||
Flux<String> flux = Flux.push(sink -> {
|
||||
NetworkTrafficProducerPush.this.listener = (t) -> sink.next(t);
|
||||
}, OverflowStrategy.DROP);
|
||||
flux.subscribe(consumer);
|
||||
}
|
||||
|
||||
public void onPacket(String packet) {
|
||||
listener.accept(packet);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue