Merge branch 'eugenp:master' into master
This commit is contained in:
@@ -5,7 +5,7 @@ title: '[ISSUE] '
|
||||
---
|
||||
|
||||
**Article and Module Links**
|
||||
A link to the affected article and the affected module. The link to the module is the one in the "over on GitHub" standard phrase.
|
||||
A link to the affected article and the affected module. You can find the link to the module in the Conclusion section in the "on Github" standard phase.
|
||||
|
||||
**Describe the Issue**
|
||||
A clear and concise description of what the issue is.
|
||||
@@ -30,9 +30,3 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional Context**
|
||||
Add any other context about the issue here.
|
||||
|
||||
Note that, unfortunately, we can only help with issues that are specifically and directly related to the article - not with your own, custom application.
|
||||
|
||||
StackOverflow is a great place to ask more general questions.
|
||||
|
||||
That's primarily because we get a large number of questions and - while we do try to go through as much as everything and help wherever we can, we can't really get back to all of them.
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package com.baeldung.algorithms.rotatearray;
|
||||
|
||||
/**
|
||||
* To speed up the rotation, we narrow k rotations to the remainder of k divided by the array length, or k module the array length.
|
||||
* Therefore, a large rotation number will be translated into the relative smallest rotation.
|
||||
* All solutions replace the original array, although they might use an extra array to compute the rotation.
|
||||
*/
|
||||
public class RotateArray {
|
||||
|
||||
private RotateArray() {
|
||||
throw new IllegalStateException("Rotate array algorithm utility methods class");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arr array to apply rotation to
|
||||
* @param k number of rotations
|
||||
*/
|
||||
public static void bruteForce(int[] arr, int k) {
|
||||
checkInvalidInput(arr, k);
|
||||
|
||||
k %= arr.length;
|
||||
int temp;
|
||||
int previous;
|
||||
for (int i = 0; i < k; i++) {
|
||||
previous = arr[arr.length - 1];
|
||||
for (int j = 0; j < arr.length; j++) {
|
||||
temp = arr[j];
|
||||
arr[j] = previous;
|
||||
previous = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arr array to apply rotation to
|
||||
* @param k number of rotations
|
||||
*/
|
||||
public static void withExtraArray(int[] arr, int k) {
|
||||
checkInvalidInput(arr, k);
|
||||
|
||||
int[] extraArray = new int[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
extraArray[(i + k) % arr.length] = arr[i];
|
||||
}
|
||||
System.arraycopy(extraArray, 0, arr, 0, arr.length);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arr array to apply rotation to
|
||||
* @param k number of rotations
|
||||
*/
|
||||
public static void cyclicReplacement(int[] arr, int k) {
|
||||
checkInvalidInput(arr, k);
|
||||
|
||||
k = k % arr.length;
|
||||
int count = 0;
|
||||
for (int start = 0; count < arr.length; start++) {
|
||||
int current = start;
|
||||
int prev = arr[start];
|
||||
do {
|
||||
int next = (current + k) % arr.length;
|
||||
int temp = arr[next];
|
||||
arr[next] = prev;
|
||||
prev = temp;
|
||||
current = next;
|
||||
count++;
|
||||
} while (start != current);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param arr array to apply rotation to
|
||||
* @param k number of rotations
|
||||
*/
|
||||
public static void reverse(int[] arr, int k) {
|
||||
checkInvalidInput(arr, k);
|
||||
|
||||
k %= arr.length;
|
||||
reverse(arr, 0, arr.length - 1);
|
||||
reverse(arr, 0, k - 1);
|
||||
reverse(arr, k, arr.length - 1);
|
||||
}
|
||||
|
||||
private static void reverse(int[] nums, int start, int end) {
|
||||
while (start < end) {
|
||||
int temp = nums[start];
|
||||
nums[start] = nums[end];
|
||||
nums[end] = temp;
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkInvalidInput(int[] arr, int rotation) {
|
||||
if (rotation < 1 || arr == null)
|
||||
throw new IllegalArgumentException("Rotation must be greater than zero or array must be not null");
|
||||
}
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package com.baeldung.algorithms.rotatearray;
|
||||
|
||||
import static com.baeldung.algorithms.rotatearray.RotateArray.bruteForce;
|
||||
import static com.baeldung.algorithms.rotatearray.RotateArray.cyclicReplacement;
|
||||
import static com.baeldung.algorithms.rotatearray.RotateArray.reverse;
|
||||
import static com.baeldung.algorithms.rotatearray.RotateArray.withExtraArray;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class RotateArrayUnitTest {
|
||||
|
||||
private final int[] arr = { 1, 2, 3, 4, 5, 6 };
|
||||
private final int rotationLtArrayLength = 1;
|
||||
private final int rotationGtArrayLength = arr.length + 2;
|
||||
private final int[] ltArrayLengthRotation = { 6, 1, 2, 3, 4, 5 };
|
||||
private final int[] gtArrayLengthRotation = { 5, 6, 1, 2, 3, 4 };
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenNoRotationOrEmptyArray_thenThrowIllegalArgumentException() {
|
||||
final int noRotation = 0;
|
||||
final int someRotation = arr.length - 1;
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> bruteForce(arr, noRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> withExtraArray(arr, noRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> cyclicReplacement(arr, noRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> reverse(arr, noRotation));
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> bruteForce(null, someRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> withExtraArray(null, someRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> cyclicReplacement(null, someRotation));
|
||||
assertThrows(IllegalArgumentException.class, () -> reverse(null, someRotation));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseBruteForceRotationLtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
bruteForce(arr, rotationLtArrayLength);
|
||||
assertArrayEquals(ltArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseBruteForceRotationGtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
bruteForce(arr, rotationGtArrayLength);
|
||||
assertArrayEquals(gtArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseBruteForceRotationEqArrayLength_thenDoNothing() {
|
||||
int[] expected = arr.clone();
|
||||
|
||||
bruteForce(arr, arr.length);
|
||||
assertArrayEquals(expected, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseExtraArrayRotationLtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
withExtraArray(arr, rotationLtArrayLength);
|
||||
assertArrayEquals(ltArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseExtraArrayRotationGtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
withExtraArray(arr, rotationGtArrayLength);
|
||||
assertArrayEquals(gtArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseExtraArrayWithRotationEqArrayLength_thenDoNothing() {
|
||||
int[] clone = arr.clone();
|
||||
|
||||
withExtraArray(arr, arr.length);
|
||||
assertArrayEquals(clone, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseCyclicReplacementRotationLtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
cyclicReplacement(arr, rotationLtArrayLength);
|
||||
assertArrayEquals(ltArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseCyclicReplacementRotationGtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
cyclicReplacement(arr, rotationGtArrayLength);
|
||||
assertArrayEquals(gtArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseCyclicReplacementRotationEqArrayLength_thenDoNothing() {
|
||||
int[] clone = arr.clone();
|
||||
|
||||
cyclicReplacement(arr, arr.length);
|
||||
assertArrayEquals(clone, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseReverseRotationLtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
reverse(arr, rotationLtArrayLength);
|
||||
assertArrayEquals(ltArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseReverseRotationGtArrayLength_thenRotateArrayOk() {
|
||||
|
||||
reverse(arr, rotationGtArrayLength);
|
||||
assertArrayEquals(gtArrayLengthRotation, arr);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenInputArray_whenUseReverseRotationEqArrayLength_thenDoNothing() {
|
||||
|
||||
int[] clone = arr.clone();
|
||||
|
||||
reverse(arr, arr.length);
|
||||
assertArrayEquals(clone, arr);
|
||||
}
|
||||
}
|
||||
@@ -13,3 +13,4 @@ You can build the project from the command line using: *mvn clean install*, or i
|
||||
- [Read Data From the Beginning Using Kafka Consumer API](https://www.baeldung.com/java-kafka-consumer-api-read)
|
||||
- [Get Partition Count for a Topic in Kafka](https://www.baeldung.com/java-kafka-partition-count-topic)
|
||||
- [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server)
|
||||
- [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka)
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package com.baeldung.kafka.multipletopics;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.consumer.KafkaConsumer;
|
||||
import org.apache.kafka.clients.producer.KafkaProducer;
|
||||
import org.apache.kafka.clients.producer.ProducerConfig;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testcontainers.containers.KafkaContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
import org.testcontainers.utility.DockerImageName;
|
||||
|
||||
// This live test needs a Docker Daemon running so that a kafka container can be created
|
||||
|
||||
@Testcontainers
|
||||
public class MultipleTopicsLiveTest {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(MultipleTopicsLiveTest.class);
|
||||
|
||||
private static final String CARD_PAYMENTS_TOPIC = "card-payments";
|
||||
private static final String BANK_TRANSFERS_TOPIC = "bank-transfers";
|
||||
private static KafkaProducer<String, String> producer;
|
||||
private static KafkaConsumer<String, String> consumer;
|
||||
|
||||
@Container
|
||||
private static final KafkaContainer KAFKA_CONTAINER = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:latest"));
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
KAFKA_CONTAINER.addExposedPort(9092);
|
||||
producer = new KafkaProducer<>(getProducerProperties());
|
||||
consumer = new KafkaConsumer<>(getConsumerProperties());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void destroy() {
|
||||
KAFKA_CONTAINER.stop();
|
||||
}
|
||||
|
||||
private static Properties getProducerProperties() {
|
||||
Properties producerProperties = new Properties();
|
||||
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||
producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
|
||||
return producerProperties;
|
||||
}
|
||||
|
||||
private static Properties getConsumerProperties() {
|
||||
Properties consumerProperties = new Properties();
|
||||
consumerProperties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_CONTAINER.getBootstrapServers());
|
||||
consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
|
||||
consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
|
||||
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "payments");
|
||||
return consumerProperties;
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSendingMessagesOnTwoTopics_thenConsumerReceivesMessages() throws Exception {
|
||||
publishMessages();
|
||||
|
||||
consumer.subscribe(Arrays.asList(CARD_PAYMENTS_TOPIC, BANK_TRANSFERS_TOPIC));
|
||||
|
||||
int eventsProcessed = 0;
|
||||
for (ConsumerRecord<String, String> record : consumer.poll(Duration.ofSeconds(10))) {
|
||||
log.info("Event on topic={}, payload={}", record.topic(), record.value());
|
||||
eventsProcessed++;
|
||||
}
|
||||
|
||||
assertThat(eventsProcessed).isEqualTo(2);
|
||||
}
|
||||
|
||||
private void publishMessages() throws ExecutionException, InterruptedException {
|
||||
ProducerRecord<String, String> cardPayment = new ProducerRecord<>(CARD_PAYMENTS_TOPIC, createCardPayment());
|
||||
producer.send(cardPayment).get();
|
||||
|
||||
ProducerRecord<String, String> bankTransfer = new ProducerRecord<>(BANK_TRANSFERS_TOPIC, createBankTransfer());
|
||||
producer.send(bankTransfer).get();
|
||||
}
|
||||
|
||||
private String createCardPayment() {
|
||||
return "{\"paymentReference\":\"A184028KM0013790\", \"type\":\"card\", \"amount\":\"275\", \"currency\":\"GBP\"}";
|
||||
}
|
||||
|
||||
private String createBankTransfer() {
|
||||
return "{\"paymentReference\":\"19ae2-18mk73-009\", \"type\":\"bank\", \"amount\":\"150\", \"currency\":\"EUR\"}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
## Relevant Articles
|
||||
- [How To Convert Excel Data Into List Of Java Objects](https://www.baeldung.com/java-convert-excel-data-into-list)
|
||||
- [Expand Columns with Apache POI](https://www.baeldung.com/java-apache-poi-expand-columns)
|
||||
@@ -0,0 +1,2 @@
|
||||
/target/
|
||||
.idea/
|
||||
@@ -0,0 +1,7 @@
|
||||
## AWS DYNAMODB
|
||||
|
||||
This module contains articles about AWS DynamoDB
|
||||
|
||||
### Relevant articles
|
||||
- [Integration Testing with a Local DynamoDB Instance](https://www.baeldung.com/dynamodb-local-integration-tests)
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aws-dynamodb</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<name>aws-dynamodb</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>aws-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk</artifactId>
|
||||
<version>${aws-java-sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>DynamoDBLocal</artifactId>
|
||||
<version>${dynamodblocal.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>${maven-shade-plugin.version}</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>${maven-plugins-version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<includeScope></includeScope>
|
||||
<includeTypes>so,dll,dylib</includeTypes>
|
||||
<outputDirectory>native-libs</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<gson.version>2.8.0</gson.version>
|
||||
<dynamodblocal.version>1.21.1</dynamodblocal.version>
|
||||
<maven-plugins-version>3.1.1</maven-plugins-version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+4
-4
@@ -49,10 +49,10 @@ public class ProductInfoRepositoryIntegrationTest {
|
||||
@BeforeClass
|
||||
public static void setupClass() {
|
||||
Properties testProperties = loadFromFileInClasspath("test.properties")
|
||||
.filter(properties -> !isEmpty(properties.getProperty(AWS_ACCESSKEY)))
|
||||
.filter(properties -> !isEmpty(properties.getProperty(AWS_SECRETKEY)))
|
||||
.filter(properties -> !isEmpty(properties.getProperty(DYNAMODB_ENDPOINT)))
|
||||
.orElseThrow(() -> new RuntimeException("Unable to get all of the required test property values"));
|
||||
.filter(properties -> !isEmpty(properties.getProperty(AWS_ACCESSKEY)))
|
||||
.filter(properties -> !isEmpty(properties.getProperty(AWS_SECRETKEY)))
|
||||
.filter(properties -> !isEmpty(properties.getProperty(DYNAMODB_ENDPOINT)))
|
||||
.orElseThrow(() -> new RuntimeException("Unable to get all of the required test property values"));
|
||||
|
||||
String amazonAWSAccessKey = testProperties.getProperty(AWS_ACCESSKEY);
|
||||
String amazonAWSSecretKey = testProperties.getProperty(AWS_SECRETKEY);
|
||||
@@ -16,31 +16,9 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk</artifactId>
|
||||
<version>${aws-java-sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-lambda-java-core</artifactId>
|
||||
<version>${aws-lambda-java-core.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-lambda-java-events</artifactId>
|
||||
<version>${aws-lambda-java-events.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<groupId>software.amazon.awssdk</groupId>
|
||||
<artifactId>aws-sdk-java</artifactId>
|
||||
<version>${aws-java-sdk-v2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
@@ -52,12 +30,6 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>DynamoDBLocal</artifactId>
|
||||
<version>${dynamodblocal.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -101,8 +73,6 @@
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
|
||||
<aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version>
|
||||
<gson.version>2.8.0</gson.version>
|
||||
<dynamodblocal.version>1.21.1</dynamodblocal.version>
|
||||
<commons-codec-version>1.10.L001</commons-codec-version>
|
||||
|
||||
@@ -2,136 +2,148 @@ package com.baeldung.ec2;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentials;
|
||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.ec2.AmazonEC2;
|
||||
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
|
||||
import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
|
||||
import com.amazonaws.services.ec2.model.CreateKeyPairRequest;
|
||||
import com.amazonaws.services.ec2.model.CreateKeyPairResult;
|
||||
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
|
||||
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
|
||||
import com.amazonaws.services.ec2.model.DescribeKeyPairsRequest;
|
||||
import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
|
||||
import com.amazonaws.services.ec2.model.IpPermission;
|
||||
import com.amazonaws.services.ec2.model.IpRange;
|
||||
import com.amazonaws.services.ec2.model.MonitorInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.RebootInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.RunInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.StartInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.StopInstancesRequest;
|
||||
import com.amazonaws.services.ec2.model.UnmonitorInstancesRequest;
|
||||
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.ec2.Ec2Client;
|
||||
import software.amazon.awssdk.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.CreateKeyPairRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.CreateKeyPairResponse;
|
||||
import software.amazon.awssdk.services.ec2.model.CreateSecurityGroupRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
|
||||
import software.amazon.awssdk.services.ec2.model.DescribeKeyPairsRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.DescribeKeyPairsResponse;
|
||||
import software.amazon.awssdk.services.ec2.model.IpPermission;
|
||||
import software.amazon.awssdk.services.ec2.model.IpRange;
|
||||
import software.amazon.awssdk.services.ec2.model.MonitorInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.RebootInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.RunInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.RunInstancesResponse;
|
||||
import software.amazon.awssdk.services.ec2.model.StartInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.StartInstancesResponse;
|
||||
import software.amazon.awssdk.services.ec2.model.StopInstancesRequest;
|
||||
import software.amazon.awssdk.services.ec2.model.UnmonitorInstancesRequest;
|
||||
|
||||
public class EC2Application {
|
||||
|
||||
private static final AWSCredentials credentials;
|
||||
|
||||
static {
|
||||
// put your accesskey and secretkey here
|
||||
credentials = new BasicAWSCredentials(
|
||||
"<AWS accesskey>",
|
||||
"<AWS secretkey>"
|
||||
);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Set up the client
|
||||
AmazonEC2 ec2Client = AmazonEC2ClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withRegion(Regions.US_EAST_1)
|
||||
Ec2Client ec2Client = Ec2Client.builder()
|
||||
.credentialsProvider(ProfileCredentialsProvider.create("default"))
|
||||
.region(Region.US_EAST_1)
|
||||
.build();
|
||||
|
||||
// Create a security group
|
||||
CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest().withGroupName("BaeldungSecurityGroup")
|
||||
.withDescription("Baeldung Security Group");
|
||||
CreateSecurityGroupRequest createSecurityGroupRequest = CreateSecurityGroupRequest.builder()
|
||||
.groupName("BaeldungSecurityGroup")
|
||||
.description("Baeldung Security Group")
|
||||
.build();
|
||||
|
||||
ec2Client.createSecurityGroup(createSecurityGroupRequest);
|
||||
|
||||
// Allow HTTP and SSH traffic
|
||||
IpRange ipRange1 = new IpRange().withCidrIp("0.0.0.0/0");
|
||||
IpRange ipRange1 = IpRange.builder()
|
||||
.cidrIp("0.0.0.0/0")
|
||||
.build();
|
||||
|
||||
IpPermission ipPermission1 = new IpPermission().withIpv4Ranges(Arrays.asList(new IpRange[] { ipRange1 }))
|
||||
.withIpProtocol("tcp")
|
||||
.withFromPort(80)
|
||||
.withToPort(80);
|
||||
IpPermission ipPermission1 = IpPermission.builder()
|
||||
.ipRanges(Arrays.asList(ipRange1))
|
||||
.ipProtocol("tcp")
|
||||
.fromPort(80)
|
||||
.toPort(80)
|
||||
.build();
|
||||
|
||||
IpPermission ipPermission2 = new IpPermission().withIpv4Ranges(Arrays.asList(new IpRange[] { ipRange1 }))
|
||||
.withIpProtocol("tcp")
|
||||
.withFromPort(22)
|
||||
.withToPort(22);
|
||||
IpPermission ipPermission2 = IpPermission.builder()
|
||||
.ipRanges(Arrays.asList(ipRange1))
|
||||
.ipProtocol("tcp")
|
||||
.fromPort(22)
|
||||
.toPort(22)
|
||||
.build();
|
||||
|
||||
AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest = new AuthorizeSecurityGroupIngressRequest()
|
||||
.withGroupName("BaeldungSecurityGroup")
|
||||
.withIpPermissions(ipPermission1, ipPermission2);
|
||||
AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest = AuthorizeSecurityGroupIngressRequest
|
||||
.builder()
|
||||
.groupName("BaeldungSecurityGroup")
|
||||
.ipPermissions(ipPermission1, ipPermission2)
|
||||
.build();
|
||||
|
||||
ec2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
|
||||
|
||||
// Create KeyPair
|
||||
CreateKeyPairRequest createKeyPairRequest = new CreateKeyPairRequest()
|
||||
.withKeyName("baeldung-key-pair");
|
||||
CreateKeyPairResult createKeyPairResult = ec2Client.createKeyPair(createKeyPairRequest);
|
||||
String privateKey = createKeyPairResult
|
||||
.getKeyPair()
|
||||
.getKeyMaterial(); // make sure you keep it, the private key, Amazon doesn't store the private key
|
||||
CreateKeyPairRequest createKeyPairRequest = CreateKeyPairRequest.builder()
|
||||
.keyName("baeldung-key-pair")
|
||||
.build();
|
||||
|
||||
CreateKeyPairResponse createKeyPairResponse = ec2Client.createKeyPair(createKeyPairRequest);
|
||||
String privateKey = createKeyPairResponse.keyMaterial();
|
||||
// make sure you keep it, the private key, Amazon doesn't store the private key
|
||||
|
||||
// See what key-pairs you've got
|
||||
DescribeKeyPairsRequest describeKeyPairsRequest = new DescribeKeyPairsRequest();
|
||||
DescribeKeyPairsResult describeKeyPairsResult = ec2Client.describeKeyPairs(describeKeyPairsRequest);
|
||||
DescribeKeyPairsRequest describeKeyPairsRequest = DescribeKeyPairsRequest.builder()
|
||||
.build();
|
||||
DescribeKeyPairsResponse describeKeyPairsResponse = ec2Client.describeKeyPairs(describeKeyPairsRequest);
|
||||
|
||||
// Launch an Amazon Instance
|
||||
RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-97785bed") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html | https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/usingsharedamis-finding.html
|
||||
.withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
|
||||
.withMinCount(1)
|
||||
.withMaxCount(1)
|
||||
.withKeyName("baeldung-key-pair") // optional - if not present, can't connect to instance
|
||||
.withSecurityGroups("BaeldungSecurityGroup");
|
||||
RunInstancesRequest runInstancesRequest = RunInstancesRequest.builder()
|
||||
.imageId("ami-97785bed")
|
||||
.instanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
|
||||
.minCount(1)
|
||||
.maxCount(1)
|
||||
.keyName("baeldung-key-pair") // optional - if not present, can't connect to instance
|
||||
.securityGroups("BaeldungSecurityGroup")
|
||||
.build();
|
||||
|
||||
String yourInstanceId = ec2Client.runInstances(runInstancesRequest).getReservation().getInstances().get(0).getInstanceId();
|
||||
RunInstancesResponse runInstancesResponse = ec2Client.runInstances(runInstancesRequest);
|
||||
String yourInstanceId = runInstancesResponse.instances().get(0).instanceId();
|
||||
|
||||
// Start an Instance
|
||||
StartInstancesRequest startInstancesRequest = new StartInstancesRequest()
|
||||
.withInstanceIds(yourInstanceId);
|
||||
StartInstancesRequest startInstancesRequest = StartInstancesRequest.builder()
|
||||
.instanceIds(yourInstanceId)
|
||||
.build();
|
||||
|
||||
StartInstancesResponse startInstancesResponse = ec2Client.startInstances(startInstancesRequest);
|
||||
|
||||
ec2Client.startInstances(startInstancesRequest);
|
||||
|
||||
// Monitor Instances
|
||||
MonitorInstancesRequest monitorInstancesRequest = new MonitorInstancesRequest()
|
||||
.withInstanceIds(yourInstanceId);
|
||||
MonitorInstancesRequest monitorInstancesRequest = MonitorInstancesRequest.builder()
|
||||
.instanceIds(yourInstanceId)
|
||||
.build();
|
||||
|
||||
|
||||
ec2Client.monitorInstances(monitorInstancesRequest);
|
||||
|
||||
UnmonitorInstancesRequest unmonitorInstancesRequest = new UnmonitorInstancesRequest()
|
||||
.withInstanceIds(yourInstanceId);
|
||||
UnmonitorInstancesRequest unmonitorInstancesRequest = UnmonitorInstancesRequest.builder()
|
||||
.instanceIds(yourInstanceId)
|
||||
.build();
|
||||
|
||||
ec2Client.unmonitorInstances(unmonitorInstancesRequest);
|
||||
|
||||
// Reboot an Instance
|
||||
|
||||
RebootInstancesRequest rebootInstancesRequest = new RebootInstancesRequest()
|
||||
.withInstanceIds(yourInstanceId);
|
||||
RebootInstancesRequest rebootInstancesRequest = RebootInstancesRequest.builder()
|
||||
.instanceIds(yourInstanceId)
|
||||
.build();
|
||||
|
||||
ec2Client.rebootInstances(rebootInstancesRequest);
|
||||
|
||||
// Stop an Instance
|
||||
StopInstancesRequest stopInstancesRequest = new StopInstancesRequest()
|
||||
.withInstanceIds(yourInstanceId);
|
||||
StopInstancesRequest stopInstancesRequest = StopInstancesRequest.builder()
|
||||
.instanceIds(yourInstanceId)
|
||||
.build();
|
||||
|
||||
|
||||
ec2Client.stopInstances(stopInstancesRequest)
|
||||
.getStoppingInstances()
|
||||
.stoppingInstances()
|
||||
.get(0)
|
||||
.getPreviousState()
|
||||
.getName();
|
||||
.previousState()
|
||||
.name();
|
||||
|
||||
// Describe an Instance
|
||||
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest();
|
||||
DescribeInstancesResult response = ec2Client.describeInstances(describeInstancesRequest);
|
||||
System.out.println(response.getReservations()
|
||||
DescribeInstancesRequest describeInstancesRequest = DescribeInstancesRequest.builder().build();
|
||||
DescribeInstancesResponse response = ec2Client.describeInstances(describeInstancesRequest);
|
||||
System.out.println(response.reservations()
|
||||
.get(0)
|
||||
.getInstances()
|
||||
.instances()
|
||||
.get(0)
|
||||
.getKernelId());
|
||||
.kernelId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package com.baeldung.rds;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.rds.AmazonRDS;
|
||||
import com.amazonaws.services.rds.AmazonRDSClientBuilder;
|
||||
import com.amazonaws.services.rds.model.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
@@ -16,12 +8,22 @@ import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.rds.RdsClient;
|
||||
import software.amazon.awssdk.services.rds.model.CreateDbInstanceRequest;
|
||||
import software.amazon.awssdk.services.rds.model.CreateDbInstanceResponse;
|
||||
import software.amazon.awssdk.services.rds.model.DBInstance;
|
||||
import software.amazon.awssdk.services.rds.model.DeleteDbInstanceRequest;
|
||||
import software.amazon.awssdk.services.rds.model.DeleteDbInstanceResponse;
|
||||
import software.amazon.awssdk.services.rds.model.DescribeDbInstancesResponse;
|
||||
import software.amazon.awssdk.services.rds.model.Endpoint;
|
||||
|
||||
public class AWSRDSService {
|
||||
|
||||
|
||||
final static Logger logger = Logger.getLogger(AWSRDSService.class.getName());
|
||||
private AWSCredentialsProvider credentials;
|
||||
private AmazonRDS amazonRDS;
|
||||
private RdsClient rdsClient;
|
||||
private String db_username;
|
||||
private String db_password;
|
||||
private String db_database;
|
||||
@@ -34,22 +36,17 @@ public class AWSRDSService {
|
||||
* **/
|
||||
public AWSRDSService() throws IOException {
|
||||
//Init RDS client with credentials and region.
|
||||
credentials = new
|
||||
AWSStaticCredentialsProvider(new
|
||||
BasicAWSCredentials("<ACCESS_KEY>",
|
||||
"<SECRET_KEY>"));
|
||||
amazonRDS = AmazonRDSClientBuilder.standard().withCredentials(credentials)
|
||||
.withRegion(Regions.AP_SOUTHEAST_2).build();
|
||||
Properties prop = new Properties();
|
||||
InputStream input = AWSRDSService.class.getClassLoader().getResourceAsStream("db.properties");
|
||||
prop.load(input);
|
||||
db_username = prop.getProperty("db_username");
|
||||
db_password = prop.getProperty("db_password");
|
||||
db_database = prop.getProperty("db_database");
|
||||
}
|
||||
|
||||
public AWSRDSService(AmazonRDS amazonRDS){
|
||||
this.amazonRDS = amazonRDS;
|
||||
rdsClient = RdsClient.builder()
|
||||
.region(Region.AP_SOUTHEAST_2)
|
||||
.credentialsProvider(ProfileCredentialsProvider.create("default"))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,29 +57,29 @@ public class AWSRDSService {
|
||||
public String launchInstance() {
|
||||
|
||||
String identifier = "";
|
||||
CreateDBInstanceRequest request = new CreateDBInstanceRequest();
|
||||
// RDS instance name
|
||||
request.setDBInstanceIdentifier("Sydney");
|
||||
request.setEngine("postgres");
|
||||
request.setMultiAZ(false);
|
||||
request.setMasterUsername(db_username);
|
||||
request.setMasterUserPassword(db_password);
|
||||
request.setDBName(db_database);
|
||||
request.setStorageType("gp2");
|
||||
request.setAllocatedStorage(10);
|
||||
CreateDbInstanceRequest instanceRequest = CreateDbInstanceRequest.builder()
|
||||
.dbInstanceIdentifier("Sydney")
|
||||
.engine("postgres")
|
||||
.multiAZ(false)
|
||||
.masterUsername(db_username)
|
||||
.masterUserPassword(db_password)
|
||||
.dbName(db_database)
|
||||
.storageType("gp2")
|
||||
.allocatedStorage(10)
|
||||
.build();
|
||||
|
||||
DBInstance instance = amazonRDS.createDBInstance(request);
|
||||
CreateDbInstanceResponse createDbInstanceResponse = rdsClient.createDBInstance(instanceRequest);
|
||||
|
||||
// Information about the new RDS instance
|
||||
identifier = instance.getDBInstanceIdentifier();
|
||||
String status = instance.getDBInstanceStatus();
|
||||
Endpoint endpoint = instance.getEndpoint();
|
||||
String endpoint_url = "Endpoint URL not available yet.";
|
||||
identifier = createDbInstanceResponse.dbInstance().dbInstanceIdentifier();
|
||||
String status = createDbInstanceResponse.dbInstance().dbInstanceStatus();
|
||||
Endpoint endpoint = createDbInstanceResponse.dbInstance().endpoint();
|
||||
String endpointUrl = "Endpoint URL not available yet.";
|
||||
if (endpoint != null) {
|
||||
endpoint_url = endpoint.toString();
|
||||
endpointUrl = endpoint.toString();
|
||||
}
|
||||
logger.info(identifier + "\t" + status);
|
||||
logger.info(endpoint_url);
|
||||
logger.info(endpointUrl);
|
||||
|
||||
return identifier;
|
||||
|
||||
@@ -90,44 +87,44 @@ public class AWSRDSService {
|
||||
|
||||
// Describe DB instances
|
||||
public void listInstances() {
|
||||
DescribeDBInstancesResult result = amazonRDS.describeDBInstances();
|
||||
List<DBInstance> instances = result.getDBInstances();
|
||||
DescribeDbInstancesResponse response = rdsClient.describeDBInstances();
|
||||
List<DBInstance> instances = response.dbInstances();
|
||||
for (DBInstance instance : instances) {
|
||||
// Information about each RDS instance
|
||||
String identifier = instance.getDBInstanceIdentifier();
|
||||
String engine = instance.getEngine();
|
||||
String status = instance.getDBInstanceStatus();
|
||||
Endpoint endpoint = instance.getEndpoint();
|
||||
String endpoint_url = "Endpoint URL not available yet.";
|
||||
String identifier = instance.dbInstanceIdentifier();
|
||||
String engine = instance.engine();
|
||||
String status = instance.dbInstanceStatus();
|
||||
Endpoint endpoint = instance.endpoint();
|
||||
String endpointUrl = "Endpoint URL not available yet.";
|
||||
if (endpoint != null) {
|
||||
endpoint_url = endpoint.toString();
|
||||
endpointUrl = endpoint.toString();
|
||||
}
|
||||
logger.info(identifier + "\t" + engine + "\t" + status);
|
||||
logger.info("\t" + endpoint_url);
|
||||
logger.info("\t" + endpointUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Delete RDS instance
|
||||
public void terminateInstance(String identifier) {
|
||||
|
||||
DeleteDBInstanceRequest request = new DeleteDBInstanceRequest();
|
||||
request.setDBInstanceIdentifier(identifier);
|
||||
request.setSkipFinalSnapshot(true);
|
||||
DeleteDbInstanceRequest request = DeleteDbInstanceRequest.builder()
|
||||
.dbInstanceIdentifier(identifier)
|
||||
.skipFinalSnapshot(true)
|
||||
.build();
|
||||
|
||||
// Delete the RDS instance
|
||||
DBInstance instance = amazonRDS.deleteDBInstance(request);
|
||||
DeleteDbInstanceResponse response = rdsClient.deleteDBInstance(request);
|
||||
|
||||
// Information about the RDS instance being deleted
|
||||
String status = instance.getDBInstanceStatus();
|
||||
Endpoint endpoint = instance.getEndpoint();
|
||||
String endpoint_url = "Endpoint URL not available yet.";
|
||||
String status = response.dbInstance().dbInstanceStatus();
|
||||
Endpoint endpoint = response.dbInstance().endpoint();
|
||||
String endpointUrl = "Endpoint URL not available yet.";
|
||||
if (endpoint != null) {
|
||||
endpoint_url = endpoint.toString();
|
||||
endpointUrl = endpoint.toString();
|
||||
}
|
||||
|
||||
logger.info(identifier + "\t" + status);
|
||||
logger.info(endpoint_url);
|
||||
logger.info(endpointUrl);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,140 +5,190 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentials;
|
||||
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
||||
import com.amazonaws.auth.BasicAWSCredentials;
|
||||
import com.amazonaws.regions.Regions;
|
||||
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
|
||||
import com.amazonaws.services.sqs.model.CreateQueueRequest;
|
||||
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
|
||||
import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
|
||||
import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
|
||||
import com.amazonaws.services.sqs.model.MessageAttributeValue;
|
||||
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
|
||||
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
|
||||
import com.amazonaws.services.sqs.model.SendMessageRequest;
|
||||
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
|
||||
import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
|
||||
import com.amazonaws.services.sqs.model.Message;
|
||||
import com.amazonaws.services.sqs.AmazonSQS;
|
||||
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.sqs.SqsClient;
|
||||
import software.amazon.awssdk.services.sqs.model.CreateQueueRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.DeleteMessageRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.GetQueueAttributesResponse;
|
||||
import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse;
|
||||
import software.amazon.awssdk.services.sqs.model.Message;
|
||||
import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
|
||||
import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
|
||||
import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequestEntry;
|
||||
import software.amazon.awssdk.services.sqs.model.SendMessageRequest;
|
||||
import software.amazon.awssdk.services.sqs.model.SetQueueAttributesRequest;
|
||||
|
||||
public class SQSApplication {
|
||||
|
||||
private static final AWSCredentials credentials;
|
||||
|
||||
static {
|
||||
// put your accesskey and secretkey here
|
||||
credentials = new BasicAWSCredentials(
|
||||
"<AWS accesskey>",
|
||||
"<AWS secretkey>"
|
||||
);
|
||||
}
|
||||
private static final String STANDARD_QUEUE_NAME = "baeldung-queue";
|
||||
private static final String FIFO_QUEUE_NAME = "baeldung-queue.fifo";
|
||||
private static final String DEAD_LETTER_QUEUE_NAME = "baeldung-dead-letter-queue";
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Set up the client
|
||||
AmazonSQS sqs = AmazonSQSClientBuilder.standard()
|
||||
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
||||
.withRegion(Regions.US_EAST_1)
|
||||
SqsClient sqsClient = SqsClient.builder()
|
||||
.region(Region.US_EAST_1)
|
||||
.credentialsProvider(ProfileCredentialsProvider.create())
|
||||
.build();
|
||||
|
||||
// Create a standard queue
|
||||
CreateQueueRequest createStandardQueueRequest = CreateQueueRequest.builder()
|
||||
.queueName(STANDARD_QUEUE_NAME)
|
||||
.build();
|
||||
|
||||
CreateQueueRequest createStandardQueueRequest = new CreateQueueRequest("baeldung-queue");
|
||||
String standardQueueUrl = sqs.createQueue(createStandardQueueRequest)
|
||||
.getQueueUrl();
|
||||
sqsClient.createQueue(createStandardQueueRequest);
|
||||
|
||||
System.out.println("\nGet queue url");
|
||||
|
||||
GetQueueUrlResponse getQueueUrlResponse = sqsClient.getQueueUrl(GetQueueUrlRequest.builder()
|
||||
.queueName(STANDARD_QUEUE_NAME)
|
||||
.build());
|
||||
String standardQueueUrl = getQueueUrlResponse.queueUrl();
|
||||
|
||||
System.out.println(standardQueueUrl);
|
||||
|
||||
// Create a fifo queue
|
||||
Map<QueueAttributeName, String> queueAttributes = new HashMap<>();
|
||||
queueAttributes.put(QueueAttributeName.FIFO_QUEUE, "true");
|
||||
queueAttributes.put(QueueAttributeName.CONTENT_BASED_DEDUPLICATION, "true");
|
||||
|
||||
Map<String, String> queueAttributes = new HashMap<String, String>();
|
||||
queueAttributes.put("FifoQueue", "true");
|
||||
queueAttributes.put("ContentBasedDeduplication", "true");
|
||||
CreateQueueRequest createFifoQueueRequest = CreateQueueRequest.builder()
|
||||
.queueName(FIFO_QUEUE_NAME)
|
||||
.attributes(queueAttributes)
|
||||
.build();
|
||||
|
||||
CreateQueueRequest createFifoQueueRequest = new CreateQueueRequest("baeldung-queue.fifo").withAttributes(queueAttributes);
|
||||
String fifoQueueUrl = sqs.createQueue(createFifoQueueRequest)
|
||||
.getQueueUrl();
|
||||
sqsClient.createQueue(createFifoQueueRequest);
|
||||
|
||||
GetQueueUrlResponse getFifoQueueUrlResponse = sqsClient.getQueueUrl(GetQueueUrlRequest.builder()
|
||||
.queueName(FIFO_QUEUE_NAME)
|
||||
.build());
|
||||
|
||||
String fifoQueueUrl = getFifoQueueUrlResponse.queueUrl();
|
||||
|
||||
System.out.println(fifoQueueUrl);
|
||||
|
||||
// Set up a dead letter queue
|
||||
CreateQueueRequest createDeadLetterQueueRequest = CreateQueueRequest.builder()
|
||||
.queueName(DEAD_LETTER_QUEUE_NAME)
|
||||
.build();
|
||||
|
||||
String deadLetterQueueUrl = sqs.createQueue("baeldung-dead-letter-queue")
|
||||
.getQueueUrl();
|
||||
String deadLetterQueueUrl = sqsClient.createQueue(createDeadLetterQueueRequest)
|
||||
.queueUrl();
|
||||
|
||||
GetQueueAttributesResult deadLetterQueueAttributes = sqs.getQueueAttributes(new GetQueueAttributesRequest(deadLetterQueueUrl).withAttributeNames("QueueArn"));
|
||||
GetQueueAttributesRequest getQueueAttributesRequest = GetQueueAttributesRequest.builder()
|
||||
.queueUrl(deadLetterQueueUrl)
|
||||
.attributeNames(QueueAttributeName.QUEUE_ARN)
|
||||
.build();
|
||||
|
||||
String deadLetterQueueARN = deadLetterQueueAttributes.getAttributes()
|
||||
GetQueueAttributesResponse deadLetterQueueAttributes = sqsClient.getQueueAttributes(getQueueAttributesRequest);
|
||||
|
||||
String deadLetterQueueARN = deadLetterQueueAttributes.attributes()
|
||||
.get("QueueArn");
|
||||
|
||||
SetQueueAttributesRequest queueAttributesRequest = new SetQueueAttributesRequest().withQueueUrl(standardQueueUrl)
|
||||
.addAttributesEntry("RedrivePolicy", "{\"maxReceiveCount\":\"2\", " + "\"deadLetterTargetArn\":\"" + deadLetterQueueARN + "\"}");
|
||||
Map<QueueAttributeName, String> attributes = new HashMap<>();
|
||||
attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\"maxReceiveCount\":\"5\", \"deadLetterTargetArn\":\"" + deadLetterQueueARN + "\"}");
|
||||
|
||||
sqs.setQueueAttributes(queueAttributesRequest);
|
||||
SetQueueAttributesRequest queueAttributesRequest = SetQueueAttributesRequest.builder()
|
||||
.queueUrl(standardQueueUrl)
|
||||
.attributes(attributes)
|
||||
.build();
|
||||
|
||||
sqsClient.setQueueAttributes(queueAttributesRequest);
|
||||
|
||||
// Send a message to a standard queue
|
||||
|
||||
Map<String, MessageAttributeValue> messageAttributes = new HashMap<>();
|
||||
MessageAttributeValue messageAttributeValue = MessageAttributeValue.builder()
|
||||
.stringValue("This is an attribute")
|
||||
.dataType("String")
|
||||
.build();
|
||||
|
||||
messageAttributes.put("AttributeOne", new MessageAttributeValue().withStringValue("This is an attribute")
|
||||
.withDataType("String"));
|
||||
messageAttributes.put("AttributeOne", messageAttributeValue);
|
||||
|
||||
SendMessageRequest sendMessageStandardQueue = new SendMessageRequest().withQueueUrl(standardQueueUrl)
|
||||
.withMessageBody("A simple message.")
|
||||
.withDelaySeconds(30) // Message will arrive in the queue after 30 seconds. We can use this only in standard queues
|
||||
.withMessageAttributes(messageAttributes);
|
||||
SendMessageRequest sendMessageStandardQueue = SendMessageRequest.builder()
|
||||
.queueUrl(standardQueueUrl)
|
||||
.messageBody("A simple message.")
|
||||
.delaySeconds(30) // Message will arrive in the queue after 30 seconds. We can use this only in standard queues
|
||||
.messageAttributes(messageAttributes)
|
||||
.build();
|
||||
|
||||
sqs.sendMessage(sendMessageStandardQueue);
|
||||
sqsClient.sendMessage(sendMessageStandardQueue);
|
||||
|
||||
// Send a message to a fifo queue
|
||||
|
||||
SendMessageRequest sendMessageFifoQueue = new SendMessageRequest().withQueueUrl(fifoQueueUrl)
|
||||
.withMessageBody("FIFO Queue")
|
||||
.withMessageGroupId("baeldung-group-1")
|
||||
.withMessageAttributes(messageAttributes);
|
||||
SendMessageRequest sendMessageFifoQueue = SendMessageRequest.builder()
|
||||
.queueUrl(fifoQueueUrl)
|
||||
.messageBody("FIFO Queue")
|
||||
.messageGroupId("baeldung-group-1")
|
||||
.messageAttributes(messageAttributes)
|
||||
.build();
|
||||
|
||||
sqs.sendMessage(sendMessageFifoQueue);
|
||||
sqsClient.sendMessage(sendMessageFifoQueue);
|
||||
|
||||
// Send multiple messages
|
||||
|
||||
List<SendMessageBatchRequestEntry> messageEntries = new ArrayList<>();
|
||||
messageEntries.add(new SendMessageBatchRequestEntry().withId("id-1")
|
||||
.withMessageBody("batch-1")
|
||||
.withMessageGroupId("baeldung-group-1"));
|
||||
messageEntries.add(new SendMessageBatchRequestEntry().withId("id-2")
|
||||
.withMessageBody("batch-2")
|
||||
.withMessageGroupId("baeldung-group-1"));
|
||||
SendMessageBatchRequestEntry messageBatchRequestEntry1 = SendMessageBatchRequestEntry.builder()
|
||||
.id("id-1")
|
||||
.messageBody("batch-1")
|
||||
.messageGroupId("baeldung-group-1")
|
||||
.build();
|
||||
|
||||
SendMessageBatchRequest sendMessageBatchRequest = new SendMessageBatchRequest(fifoQueueUrl, messageEntries);
|
||||
sqs.sendMessageBatch(sendMessageBatchRequest);
|
||||
SendMessageBatchRequestEntry messageBatchRequestEntry2 = SendMessageBatchRequestEntry.builder()
|
||||
.id("id-2")
|
||||
.messageBody("batch-2")
|
||||
.messageGroupId("baeldung-group-1")
|
||||
.build();
|
||||
|
||||
messageEntries.add(messageBatchRequestEntry1);
|
||||
messageEntries.add(messageBatchRequestEntry2);
|
||||
|
||||
SendMessageBatchRequest sendMessageBatchRequest = SendMessageBatchRequest.builder()
|
||||
.queueUrl(fifoQueueUrl)
|
||||
.entries(messageEntries)
|
||||
.build();
|
||||
|
||||
sqsClient.sendMessageBatch(sendMessageBatchRequest);
|
||||
|
||||
// Read a message from a queue
|
||||
|
||||
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(fifoQueueUrl).withWaitTimeSeconds(10) // Long polling;
|
||||
.withMaxNumberOfMessages(1); // Max is 10
|
||||
ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
|
||||
.waitTimeSeconds(10)
|
||||
.maxNumberOfMessages(10)
|
||||
.build();
|
||||
|
||||
List<Message> sqsMessages = sqs.receiveMessage(receiveMessageRequest)
|
||||
.getMessages();
|
||||
List<Message> sqsMessages = sqsClient.receiveMessage(receiveMessageRequest)
|
||||
.messages();
|
||||
|
||||
sqsMessages.get(0)
|
||||
.getAttributes();
|
||||
.attributes();
|
||||
sqsMessages.get(0)
|
||||
.getBody();
|
||||
.body();
|
||||
|
||||
// Delete a message from a queue
|
||||
DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
|
||||
.queueUrl(fifoQueueUrl)
|
||||
.receiptHandle(sqsMessages.get(0)
|
||||
.receiptHandle())
|
||||
.build();
|
||||
|
||||
sqs.deleteMessage(new DeleteMessageRequest().withQueueUrl(fifoQueueUrl)
|
||||
.withReceiptHandle(sqsMessages.get(0)
|
||||
.getReceiptHandle()));
|
||||
sqsClient.deleteMessage(deleteMessageRequest);
|
||||
|
||||
// Monitoring
|
||||
GetQueueAttributesRequest getQueueAttributesRequest = new GetQueueAttributesRequest(standardQueueUrl).withAttributeNames("All");
|
||||
GetQueueAttributesResult getQueueAttributesResult = sqs.getQueueAttributes(getQueueAttributesRequest);
|
||||
System.out.println(String.format("The number of messages on the queue: %s", getQueueAttributesResult.getAttributes()
|
||||
GetQueueAttributesRequest getQueueAttributesRequestForMonitoring = GetQueueAttributesRequest.builder()
|
||||
.queueUrl(standardQueueUrl)
|
||||
.build();
|
||||
|
||||
GetQueueAttributesResponse attributesResponse = sqsClient.getQueueAttributes(getQueueAttributesRequestForMonitoring);
|
||||
System.out.println(String.format("The number of messages on the queue: %s", attributesResponse.attributes()
|
||||
.get("ApproximateNumberOfMessages")));
|
||||
System.out.println(String.format("The number of messages in flight: %s", getQueueAttributesResult.getAttributes()
|
||||
System.out.println(String.format("The number of messages in flight: %s", attributesResponse.attributes()
|
||||
.get("ApproximateNumberOfMessagesNotVisible")));
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>aws-modules</artifactId>
|
||||
<name>aws-modules</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-dynamodb</artifactId>
|
||||
<version>1.12.523</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
@@ -15,6 +23,7 @@
|
||||
|
||||
<modules>
|
||||
<module>aws-app-sync</module>
|
||||
<module>aws-dynamodb</module>
|
||||
<module>aws-lambda-modules</module>
|
||||
<module>aws-miscellaneous</module>
|
||||
<module>aws-reactive</module>
|
||||
@@ -24,6 +33,7 @@
|
||||
|
||||
<properties>
|
||||
<aws-java-sdk.version>1.12.331</aws-java-sdk.version>
|
||||
<aws-java-sdk-v2.version>2.20.147</aws-java-sdk-v2.version>
|
||||
<maven-shade-plugin.version>3.0.0</maven-shade-plugin.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -5,3 +5,4 @@
|
||||
- [Collecting Stream Elements into a List in Java](https://www.baeldung.com/java-stream-to-list-collecting)
|
||||
- [New Features in Java 16](https://www.baeldung.com/java-16-new-features)
|
||||
- [Guide to Java 8 groupingBy Collector](https://www.baeldung.com/java-groupingby-collector)
|
||||
- [Value-Based Classes in Java](https://www.baeldung.com/java-value-based-classes)
|
||||
|
||||
@@ -30,6 +30,11 @@ public final class Point {
|
||||
return new Point(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Point{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == null || getClass() != other.getClass())
|
||||
|
||||
+6
-3
@@ -1,14 +1,17 @@
|
||||
package com.baeldung.value_based_class;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ValueBasedClassUnitTest {
|
||||
@Test
|
||||
public void givenAutoboxedAndPrimitive_whenCompared_thenReturnEquals() {
|
||||
int primitive_a = 125;
|
||||
Integer obj_a = 125; // this is autoboxed
|
||||
Assert.assertSame(primitive_a, obj_a);
|
||||
List<Integer> list = new ArrayList<>();
|
||||
list.add(1); // this is autoboxed
|
||||
Assert.assertEquals(list.get(0), Integer.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.baeldung.recordproperties;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
record Player(String name, int age, Long score) {
|
||||
}
|
||||
|
||||
public class ReadRecordPropertiesByReflectionUnitTest {
|
||||
private static final Player ERIC = new Player("Eric", 28, 4242L);
|
||||
|
||||
@Test
|
||||
void whenUsingRecordComponent_thenGetExpectedResult() {
|
||||
var fields = new ArrayList<Field>();
|
||||
RecordComponent[] components = Player.class.getRecordComponents();
|
||||
for (var comp : components) {
|
||||
try {
|
||||
Field field = ERIC.getClass()
|
||||
.getDeclaredField(comp.getName());
|
||||
field.setAccessible(true);
|
||||
fields.add(field);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// for simplicity, error handling is skipped
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(3, fields.size());
|
||||
|
||||
var nameField = fields.get(0);
|
||||
var ageField = fields.get(1);
|
||||
var scoreField = fields.get(2);
|
||||
try {
|
||||
assertEquals("name", nameField.getName());
|
||||
assertEquals(String.class, nameField.getType());
|
||||
assertEquals("Eric", nameField.get(ERIC));
|
||||
|
||||
assertEquals("age", ageField.getName());
|
||||
assertEquals(int.class, ageField.getType());
|
||||
assertEquals(28, ageField.get(ERIC));
|
||||
|
||||
assertEquals("score", scoreField.getName());
|
||||
assertEquals(Long.class, scoreField.getType());
|
||||
assertEquals(4242L, scoreField.get(ERIC));
|
||||
} catch (IllegalAccessException exception) {
|
||||
// for simplicity, error handling is skipped
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingClassGetDeclaredField_thenGetExpectedResult() {
|
||||
// record has no public fields
|
||||
assertEquals(0, Player.class.getFields().length);
|
||||
|
||||
var fields = new ArrayList<Field>();
|
||||
for (var field : Player.class.getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
fields.add(field);
|
||||
}
|
||||
|
||||
assertEquals(3, fields.size());
|
||||
var nameField = fields.get(0);
|
||||
var ageField = fields.get(1);
|
||||
var scoreField = fields.get(2);
|
||||
|
||||
try {
|
||||
assertEquals("name", nameField.getName());
|
||||
assertEquals(String.class, nameField.getType());
|
||||
assertEquals("Eric", nameField.get(ERIC));
|
||||
|
||||
assertEquals("age", ageField.getName());
|
||||
assertEquals(int.class, ageField.getType());
|
||||
assertEquals(28, ageField.get(ERIC));
|
||||
|
||||
assertEquals("score", scoreField.getName());
|
||||
assertEquals(Long.class, scoreField.getType());
|
||||
assertEquals(4242L, scoreField.get(ERIC));
|
||||
} catch (IllegalAccessException ex) {
|
||||
// for simplicity, error handling is skipped
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-18</artifactId>
|
||||
<name>core-java-18</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<release>${maven.compiler.release}</release>
|
||||
<compilerArgs>--enable-preview</compilerArgs>
|
||||
<source>${maven.compiler.source.version}</source>
|
||||
<target>${maven.compiler.target.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire.plugin.version}</version>
|
||||
<configuration>
|
||||
<forkCount>1</forkCount>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.surefire</groupId>
|
||||
<artifactId>surefire-api</artifactId>
|
||||
<version>${surefire.plugin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source.version>18</maven.compiler.source.version>
|
||||
<maven.compiler.target.version>18</maven.compiler.target.version>
|
||||
<maven.compiler.release>18</maven.compiler.release>
|
||||
<surefire.plugin.version>3.0.0-M5</surefire.plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.finalization_closeable_cleaner;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FinalizationExamples {
|
||||
FileInputStream fis = null;
|
||||
|
||||
public void readFileOperationWithFinalization() throws IOException {
|
||||
try {
|
||||
fis = new FileInputStream("input.txt");
|
||||
// perform operation on the file
|
||||
System.out.println(fis.readAllBytes().length);
|
||||
|
||||
} finally {
|
||||
if (fis != null)
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void readFileOperationWithTryWith() throws IOException {
|
||||
try (FileInputStream fis = new FileInputStream("input.txt")) {
|
||||
// perform operations
|
||||
System.out.println(fis.readAllBytes().length);
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.finalization_closeable_cleaner;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
|
||||
public class MyCleanerResourceClass implements AutoCloseable {
|
||||
private static Resource resource;
|
||||
|
||||
private static final Cleaner cleaner = Cleaner.create();
|
||||
private final Cleaner.Cleanable cleanable;
|
||||
|
||||
public MyCleanerResourceClass() {
|
||||
resource = new Resource();
|
||||
this.cleanable = cleaner.register(this, new CleaningState());
|
||||
}
|
||||
|
||||
public void useResource() {
|
||||
// using the resource here
|
||||
resource.use();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// perform actions to close all underlying resources
|
||||
this.cleanable.clean();
|
||||
}
|
||||
|
||||
static class CleaningState implements Runnable {
|
||||
CleaningState() {
|
||||
// constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// some cleanup action
|
||||
System.out.println("Cleanup done");
|
||||
}
|
||||
}
|
||||
|
||||
static class Resource {
|
||||
void use() {
|
||||
System.out.println("Using the resource");
|
||||
}
|
||||
|
||||
void close() {
|
||||
System.out.println("Cleanup done");
|
||||
}
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.finalization_closeable_cleaner;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MyCloseableResourceClass implements AutoCloseable {
|
||||
|
||||
private final FileInputStream fis;
|
||||
|
||||
public MyCloseableResourceClass() throws FileNotFoundException {
|
||||
this.fis = new FileInputStream("src/main/resources/file.txt");
|
||||
|
||||
}
|
||||
|
||||
public int getByteLength() throws IOException {
|
||||
System.out.println("Some operation");
|
||||
return this.fis.readAllBytes().length;
|
||||
}
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
System.out.println("Finalized object");
|
||||
this.fis.close();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user