Revert "BAEL-4134"
This commit is contained in:
committed by
GitHub
parent
4a35b97bad
commit
7ab2f437ee
@@ -0,0 +1,5 @@
|
||||
bk/bookkeeper/*
|
||||
bk1/bookkeeper/*
|
||||
bk2/bookkeeper/*
|
||||
zk/*
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/bookkeeper/
|
||||
@@ -0,0 +1 @@
|
||||
/bookkeeper/
|
||||
@@ -0,0 +1,71 @@
|
||||
version: '3.0'
|
||||
services:
|
||||
zk:
|
||||
image: zookeeper:3.6.1
|
||||
restart: always
|
||||
ports:
|
||||
- "2181:2181"
|
||||
volumes:
|
||||
- ./data/zk:/data
|
||||
|
||||
bookie_init:
|
||||
image: apache/bookkeeper:4.10.0
|
||||
environment:
|
||||
BK_zkServers: "zk:2181"
|
||||
BK_advertisedAddress: ${BK_PUBLIC_IP}
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- zk
|
||||
command: /opt/bookkeeper/bin/bookkeeper shell metaformat -nonInteractive
|
||||
|
||||
bookie:
|
||||
image: apache/bookkeeper:4.10.0
|
||||
restart: on-failure
|
||||
environment:
|
||||
BK_zkServers: "zk:2181"
|
||||
BK_advertisedAddress: ${BK_PUBLIC_IP}
|
||||
BK_httpServerPort: 3182
|
||||
ports:
|
||||
- "3181:3181"
|
||||
- "3182:3182"
|
||||
volumes:
|
||||
- ./data/bk:/data
|
||||
depends_on:
|
||||
- zk
|
||||
- bookie_init
|
||||
|
||||
bookie1:
|
||||
image: apache/bookkeeper:4.10.0
|
||||
restart: on-failure
|
||||
environment:
|
||||
BOOKIE_PORT: 4181
|
||||
BK_zkServers: "zk:2181"
|
||||
BK_advertisedAddress: ${BK_PUBLIC_IP}
|
||||
BK_httpServerPort: 3182
|
||||
ports:
|
||||
- "4181:4181"
|
||||
volumes:
|
||||
- ./data/bk1:/data
|
||||
depends_on:
|
||||
- zk
|
||||
- bookie_init
|
||||
|
||||
bookie2:
|
||||
image: apache/bookkeeper:4.10.0
|
||||
restart: on-failure
|
||||
environment:
|
||||
BOOKIE_PORT: 4182
|
||||
BK_zkServers: "zk:2181"
|
||||
BK_advertisedAddress: ${BK_PUBLIC_IP}
|
||||
BK_httpServerPort: 3182
|
||||
ports:
|
||||
- "4182:4182"
|
||||
volumes:
|
||||
- ./data/bk2:/data
|
||||
depends_on:
|
||||
- zk
|
||||
- bookie_init
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?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>apache-bookkeeper</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>apache-bookkeeper</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.bookkeeper</groupId>
|
||||
<artifactId>bookkeeper-server</artifactId>
|
||||
<version>${org.apache.bookkeeper.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>1.14.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<org.apache.bookkeeper.version>4.10.0</org.apache.bookkeeper.version>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
package com.baeldung.tutorials.bookkeeper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.bookkeeper.client.BKException;
|
||||
import org.apache.bookkeeper.client.BookKeeper;
|
||||
import org.apache.bookkeeper.client.BookKeeper.DigestType;
|
||||
import org.apache.bookkeeper.client.LedgerHandle;
|
||||
import org.apache.bookkeeper.client.api.LedgerMetadata;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.zookeeper.AsyncCallback;
|
||||
|
||||
public class BkHelper {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(BkHelper.class);
|
||||
|
||||
public static BookKeeper createBkClient(String zkConnectionString) {
|
||||
try {
|
||||
return new BookKeeper(zkConnectionString);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Ledger with the given name added as custom metadata
|
||||
* @param bk
|
||||
* @param name
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
public static LedgerHandle createLedger(BookKeeper bk, String name, byte[] password) {
|
||||
try {
|
||||
return bk.createLedger(3, 2, 2, DigestType.MAC, password, Collections.singletonMap("name", name.getBytes()));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over all available ledgers and returns the first one that has
|
||||
* a metadata key 'name' equals to the given name
|
||||
* @param bk
|
||||
* @param name
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Optional<Long> findLedgerByName(BookKeeper bk, String name) throws Exception {
|
||||
Map<Long, LedgerMetadata> ledgers = new HashMap<Long, LedgerMetadata>();
|
||||
final AtomicInteger returnCode = new AtomicInteger(BKException.Code.OK);
|
||||
final CountDownLatch processDone = new CountDownLatch(1);
|
||||
|
||||
// There's no standard "list" operation. Instead, BK offers a generalized way to
|
||||
// iterate over all available ledgers using an async visitor callback.
|
||||
// The second callback will be called when there are no more ledgers do process or if an
|
||||
// error occurs.
|
||||
bk.getLedgerManager()
|
||||
.asyncProcessLedgers(
|
||||
(ledgerId, cb) -> collectLedgers(bk, ledgerId, cb, ledgers),
|
||||
(rc, s, obj) -> {
|
||||
returnCode.set(rc);
|
||||
processDone.countDown();
|
||||
},
|
||||
null,
|
||||
BKException.Code.OK, BKException.Code.ReadException);
|
||||
processDone.await(5, TimeUnit.MINUTES);
|
||||
LOG.info("Ledgers collected: total found=" + ledgers.size());
|
||||
|
||||
byte[] nameBytes = name.getBytes();
|
||||
Optional<Entry<Long, LedgerMetadata>> entry = ledgers.entrySet()
|
||||
.stream()
|
||||
.filter((e) -> {
|
||||
Map<String, byte[]> meta = e.getValue()
|
||||
.getCustomMetadata();
|
||||
if (meta != null) {
|
||||
LOG.info("ledger: " + e.getKey() + ", customMeta=" + meta);
|
||||
byte[] data = meta.get("name");
|
||||
if (data != null && Arrays.equals(data, nameBytes)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOG.info("ledger: " + e.getKey() + ", no meta");
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.findFirst();
|
||||
if (entry.isPresent()) {
|
||||
return Optional.of(entry.get()
|
||||
.getKey());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public static void collectLedgers(BookKeeper bk, long ledgerId, AsyncCallback.VoidCallback cb, Map<Long, LedgerMetadata> ledgers) {
|
||||
try {
|
||||
bk.getLedgerManager()
|
||||
.readLedgerMetadata(ledgerId)
|
||||
.thenAccept((v) -> {
|
||||
LOG.debug("Got ledger metadata");
|
||||
ledgers.put(ledgerId, v.getValue());
|
||||
})
|
||||
.thenAccept((v) -> {
|
||||
cb.processResult(BKException.Code.OK, null, null);
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list with all available Ledgers
|
||||
* @param bk
|
||||
* @return
|
||||
*/
|
||||
public static List<Long> listAllLedgers(BookKeeper bk) {
|
||||
final List<Long> ledgers = Collections.synchronizedList(new ArrayList<>());
|
||||
final CountDownLatch processDone = new CountDownLatch(1);
|
||||
|
||||
bk.getLedgerManager()
|
||||
.asyncProcessLedgers((ledgerId, cb) -> {
|
||||
ledgers.add(ledgerId);
|
||||
cb.processResult(BKException.Code.OK, null, null);
|
||||
},
|
||||
(rc, s, obj) -> {
|
||||
processDone.countDown();
|
||||
}, null, BKException.Code.OK, BKException.Code.ReadException);
|
||||
|
||||
try {
|
||||
processDone.await(1, TimeUnit.MINUTES);
|
||||
return ledgers;
|
||||
} catch (InterruptedException ie) {
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
package com.baeldung.tutorials.bookkeeper;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.bookkeeper.client.BookKeeper;
|
||||
import org.apache.bookkeeper.client.LedgerEntry;
|
||||
import org.apache.bookkeeper.client.LedgerHandle;
|
||||
import org.apache.bookkeeper.client.api.DigestType;
|
||||
import org.apache.bookkeeper.client.api.LedgerEntries;
|
||||
import org.apache.bookkeeper.client.api.WriteHandle;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class BkHelperLiveTest extends BkHelper {
|
||||
private static BookKeeper bk;
|
||||
private byte[] ledgerPassword = "SuperS3cR37".getBytes();
|
||||
private static final Log LOG = LogFactory.getLog(BkHelperLiveTest.class);
|
||||
|
||||
@BeforeAll
|
||||
static void initBkClient() {
|
||||
bk = createBkClient("192.168.99.101:2181");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreateLedger_thenSuccess() throws Exception {
|
||||
LedgerHandle lh = bk.createLedger(BookKeeper.DigestType.MAC, ledgerPassword);
|
||||
assertNotNull(lh);
|
||||
assertNotNull(lh.getId());
|
||||
LOG.info("[I33] Ledge created: id=" + lh.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCreateLedgerAsync_thenSuccess() throws Exception {
|
||||
|
||||
CompletableFuture<WriteHandle> cf = bk.newCreateLedgerOp()
|
||||
.withDigestType(org.apache.bookkeeper.client.api.DigestType.MAC)
|
||||
.withPassword("password".getBytes())
|
||||
.execute();
|
||||
|
||||
WriteHandle handle = cf.get(1, TimeUnit.MINUTES);
|
||||
assertNotNull(handle);
|
||||
handle.close();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenAsyncCreateLedger_thenSuccess() throws Exception {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AtomicReference<LedgerHandle> handleRef = new AtomicReference<>();
|
||||
|
||||
bk.asyncCreateLedger(3, 2, 2, BookKeeper.DigestType.MAC, ledgerPassword,
|
||||
(rc, lh, ctx) -> {
|
||||
handleRef.set(lh);
|
||||
latch.countDown();
|
||||
}, null, Collections.emptyMap());
|
||||
latch.await(1, TimeUnit.MINUTES);
|
||||
LedgerHandle lh = handleRef.get();
|
||||
assertNotNull(lh);
|
||||
assertFalse(lh.isClosed(), "Ledger should be writeable");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenListLedgers_thenSuccess() throws Exception {
|
||||
List<Long> ledgers = listAllLedgers(bk);
|
||||
assertNotNull(ledgers);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWriteEntries_thenSuccess() throws Exception {
|
||||
LedgerHandle lh = createLedger(bk, "myledger", ledgerPassword);
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
byte[] data = new String("message-" + i).getBytes();
|
||||
lh.append(data);
|
||||
}
|
||||
lh.close();
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
LOG.info("Entries added to ledgerId " + lh.getId() + ". count=1000, elapsed=" + elapsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWriteEntriesAsync_thenSuccess() throws Exception {
|
||||
CompletableFuture<Object> f = bk.newCreateLedgerOp()
|
||||
.withDigestType(DigestType.MAC)
|
||||
.withPassword(ledgerPassword)
|
||||
.execute()
|
||||
.thenApply((wh) -> {
|
||||
List<CompletableFuture<Long>> ops = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
byte[] data = String.format("message-%04d", i)
|
||||
.getBytes();
|
||||
ops.add(wh.appendAsync(data));
|
||||
}
|
||||
return CompletableFuture.allOf(ops.stream()
|
||||
.toArray(CompletableFuture[]::new))
|
||||
.thenCompose((v) -> wh.closeAsync());
|
||||
});
|
||||
f.get(5, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWriteAndReadEntriesAsync_thenSuccess() throws Exception {
|
||||
CompletableFuture<Long> f = bk.newCreateLedgerOp()
|
||||
.withDigestType(DigestType.MAC)
|
||||
.withPassword(ledgerPassword)
|
||||
.execute()
|
||||
.thenApply((wh) -> {
|
||||
List<CompletableFuture<Long>> ops = new ArrayList<>();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
byte[] data = String.format("message-%04d", i)
|
||||
.getBytes();
|
||||
ops.add(wh.appendAsync(data));
|
||||
}
|
||||
return CompletableFuture.allOf(ops.stream()
|
||||
.toArray(CompletableFuture[]::new))
|
||||
.thenCompose((v) -> wh.closeAsync())
|
||||
.thenApply((v) -> wh.getId());
|
||||
})
|
||||
.thenCompose((lf) -> lf); // flatten the futures
|
||||
Long ledgerId = f.get(5, TimeUnit.MINUTES);
|
||||
LOG.info("Ledger created with 1000 entries: ledgerId=" + ledgerId);
|
||||
|
||||
// Now let's read data back...
|
||||
CompletableFuture<LedgerEntries> ef = bk.newOpenLedgerOp()
|
||||
.withLedgerId(ledgerId)
|
||||
.withPassword(ledgerPassword)
|
||||
.withDigestType(DigestType.MAC)
|
||||
.execute()
|
||||
.thenCompose((rh) -> {
|
||||
return rh.readLastAddConfirmedAsync()
|
||||
.thenCompose((lastId) -> rh.readAsync(0, lastId));
|
||||
});
|
||||
LedgerEntries entries = ef.get(5, TimeUnit.MINUTES);
|
||||
|
||||
// Check all writes where OK
|
||||
long count = 0;
|
||||
Iterator<org.apache.bookkeeper.client.api.LedgerEntry> it = entries.iterator();
|
||||
while (it.hasNext()) {
|
||||
org.apache.bookkeeper.client.api.LedgerEntry e = it.next();
|
||||
String msg = new String(e.getEntryBytes());
|
||||
assertEquals(String.format("message-%04d", count), msg);
|
||||
count++;
|
||||
}
|
||||
assertEquals(1000, count);
|
||||
LOG.info("Got entries: count=" + count);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenWriteAndReadEntries_thenSuccess() throws Exception {
|
||||
LedgerHandle lh = createLedger(bk, "myledger", ledgerPassword);
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
byte[] data = new String("message-" + i).getBytes();
|
||||
lh.append(data);
|
||||
}
|
||||
lh.close();
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
LOG.info("Entries added to ledgerId " + lh.getId() + ", elapsed=" + elapsed);
|
||||
|
||||
Long ledgerId = findLedgerByName(bk, "myledger").orElse(null);
|
||||
assertNotNull(ledgerId);
|
||||
lh = bk.openLedger(ledgerId, BookKeeper.DigestType.MAC, ledgerPassword);
|
||||
long lastId = lh.readLastConfirmed();
|
||||
Enumeration<LedgerEntry> entries = lh.readEntries(0, lastId);
|
||||
while (entries.hasMoreElements()) {
|
||||
LedgerEntry entry = entries.nextElement();
|
||||
String msg = new String(entry.getEntry());
|
||||
LOG.info("Entry: id=" + entry.getEntryId() + ", data=" + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
|
||||
%msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -9,3 +9,4 @@
|
||||
- [A Simple Guide to Connection Pooling in Java](https://www.baeldung.com/java-connection-pooling)
|
||||
- [Guide to the JDBC ResultSet Interface](https://www.baeldung.com/jdbc-resultset)
|
||||
- [Types of SQL Joins](https://www.baeldung.com/sql-joins)
|
||||
- [Returning the Generated Keys in JDBC](https://www.baeldung.com/jdbc-returning-generated-keys)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Hibernate could not initialize proxy – no Session](https://www.baeldung.com/hibernate-initialize-proxy-exception)
|
||||
@@ -0,0 +1,3 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [A Guide to the Hibernate Types Library](https://www.baeldung.com/hibernate-types-library)
|
||||
@@ -4,7 +4,7 @@ This module contains articles about Hibernate 5. Let's not add more articles her
|
||||
|
||||
### Relevant articles:
|
||||
|
||||
- [An Overview of Identifiers in Hibernate](https://www.baeldung.com/hibernate-identifiers)
|
||||
- [An Overview of Identifiers in Hibernate/JPA](https://www.baeldung.com/hibernate-identifiers)
|
||||
- [Hibernate Interceptors](https://www.baeldung.com/hibernate-interceptor)
|
||||
- [Hibernate Entity Lifecycle](https://www.baeldung.com/hibernate-entity-lifecycle)
|
||||
- [Hibernate 5 Naming Strategy Configuration](https://www.baeldung.com/hibernate-naming-strategy)
|
||||
@@ -12,4 +12,4 @@ This module contains articles about Hibernate 5. Let's not add more articles her
|
||||
- [Hibernate 5 Bootstrapping API](https://www.baeldung.com/hibernate-5-bootstrapping-api)
|
||||
- [Guide to the Hibernate EntityManager](https://www.baeldung.com/hibernate-entitymanager)
|
||||
- [Using c3p0 with Hibernate](https://www.baeldung.com/hibernate-c3p0)
|
||||
- [Persist a JSON Object Using Hibernate](https://www.baeldung.com/hibernate-persist-json-object)
|
||||
- [Persist a JSON Object Using Hibernate](https://www.baeldung.com/hibernate-persist-json-object)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>persistence-libraries</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>java-sql2o</name>
|
||||
<name>persistence-libraries</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<modules>
|
||||
<module>activejdbc</module>
|
||||
<module>apache-bookkeeper</module><!-- BAEL-2322 -->
|
||||
<module>apache-cayenne</module>
|
||||
<module>core-java-persistence</module>
|
||||
<module>deltaspike</module>
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
<description>Sample R2DBC Project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.6.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import reactor.core.publisher.Flux;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class R2dbcExampleApplicationTests {
|
||||
public class R2dbcExampleApplicationIntegrationTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
@@ -33,7 +33,7 @@
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>${jedis.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.kstyrc</groupId>
|
||||
@@ -48,12 +48,19 @@
|
||||
<dependency>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${epoll.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<embedded-redis.version>0.6</embedded-redis.version>
|
||||
<redisson.version>3.3.0</redisson.version>
|
||||
<redisson.version>3.13.1</redisson.version>
|
||||
<jedis.version>3.3.0</jedis.version>
|
||||
<epoll.version>4.1.50.Final</epoll.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.baeldung;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Created by johnson on 3/9/17.
|
||||
*/
|
||||
public class CustomMessage {
|
||||
public class CustomMessage implements Serializable {
|
||||
private String message;
|
||||
|
||||
public CustomMessage() {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.baeldung;
|
||||
|
||||
public class Ledger {
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Ledger implements Serializable {
|
||||
|
||||
public Ledger() {
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
{
|
||||
"singleServerConfig": {
|
||||
"idleConnectionTimeout": 10000,
|
||||
"pingTimeout": 1000,
|
||||
"connectTimeout": 10000,
|
||||
"timeout": 3000,
|
||||
"retryAttempts": 3,
|
||||
"retryInterval": 1500,
|
||||
"reconnectionTimeout": 3000,
|
||||
"failedAttempts": 3,
|
||||
"password": null,
|
||||
"subscriptionsPerConnection": 5,
|
||||
"clientName": null,
|
||||
@@ -17,11 +14,9 @@
|
||||
"connectionMinimumIdleSize": 10,
|
||||
"connectionPoolSize": 64,
|
||||
"database": 0,
|
||||
"dnsMonitoring": false,
|
||||
"dnsMonitoringInterval": 5000
|
||||
},
|
||||
"threads": 0,
|
||||
"nettyThreads": 0,
|
||||
"codec": null,
|
||||
"useLinuxNativeEpoll": false
|
||||
"codec": null
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
singleServerConfig:
|
||||
idleConnectionTimeout: 10000
|
||||
pingTimeout: 1000
|
||||
connectTimeout: 10000
|
||||
timeout: 3000
|
||||
retryAttempts: 3
|
||||
retryInterval: 1500
|
||||
reconnectionTimeout: 3000
|
||||
failedAttempts: 3
|
||||
password: null
|
||||
subscriptionsPerConnection: 5
|
||||
clientName: null
|
||||
@@ -16,9 +13,7 @@ singleServerConfig:
|
||||
connectionMinimumIdleSize: 10
|
||||
connectionPoolSize: 64
|
||||
database: 0
|
||||
dnsMonitoring: false
|
||||
dnsMonitoringInterval: 5000
|
||||
threads: 0
|
||||
nettyThreads: 0
|
||||
codec: !<org.redisson.codec.JsonJacksonCodec> {}
|
||||
useLinuxNativeEpoll: false
|
||||
codec: !<org.redisson.codec.JsonJacksonCodec> {}
|
||||
+1
-1
@@ -48,7 +48,7 @@ public class RedissonConfigurationIntegrationTest {
|
||||
public void givenJavaConfig_thenRedissonConnectToRedis() {
|
||||
Config config = new Config();
|
||||
config.useSingleServer()
|
||||
.setAddress(String.format("127.0.0.1:%s", port));
|
||||
.setAddress(String.format("redis://127.0.0.1:%s", port));
|
||||
|
||||
client = Redisson.create(config);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.redisson.Redisson;
|
||||
import org.redisson.RedissonMultiLock;
|
||||
import org.redisson.api.*;
|
||||
import org.redisson.client.RedisClient;
|
||||
import org.redisson.client.RedisClientConfig;
|
||||
import org.redisson.client.RedisConnection;
|
||||
import org.redisson.client.codec.StringCodec;
|
||||
import org.redisson.client.protocol.RedisCommands;
|
||||
@@ -103,10 +104,10 @@ public class RedissonIntegrationTest {
|
||||
public void givenTopicSubscribedToAChannel_thenReceiveMessageFromChannel() throws ExecutionException, InterruptedException {
|
||||
CompletableFuture<String> future = new CompletableFuture<>();
|
||||
|
||||
RTopic<CustomMessage> subscribeTopic = client.getTopic("baeldung");
|
||||
subscribeTopic.addListener((channel, customMessage) -> future.complete(customMessage.getMessage()));
|
||||
RTopic subscribeTopic = client.getTopic("baeldung");
|
||||
subscribeTopic.addListener(CustomMessage.class, (channel, customMessage) -> future.complete(customMessage.getMessage()));
|
||||
|
||||
RTopic<CustomMessage> publishTopic = client.getTopic("baeldung");
|
||||
RTopic publishTopic = client.getTopic("baeldung");
|
||||
long clientsReceivedMessage
|
||||
= publishTopic.publish(new CustomMessage("This is a message"));
|
||||
|
||||
@@ -203,10 +204,10 @@ public class RedissonIntegrationTest {
|
||||
batch.getMap("ledgerMap").fastPutAsync("1", "2");
|
||||
batch.getMap("ledgerMap").putAsync("2", "5");
|
||||
|
||||
List<?> result = batch.execute();
|
||||
BatchResult<?> batchResult = batch.execute();
|
||||
|
||||
RMap<String, String> map = client.getMap("ledgerMap");
|
||||
assertTrue(result.size() > 0 && map.get("1").equals("2"));
|
||||
assertTrue(batchResult.getResponses().size() > 0 && map.get("1").equals("2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -220,7 +221,9 @@ public class RedissonIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void givenLowLevelRedisCommands_thenExecuteLowLevelCommandsOnRedis(){
|
||||
RedisClient client = new RedisClient("localhost", 6379);
|
||||
RedisClientConfig redisClientConfig = new RedisClientConfig();
|
||||
redisClientConfig.setAddress("localhost", 6379);
|
||||
RedisClient client = RedisClient.create(redisClientConfig);
|
||||
RedisConnection conn = client.connect();
|
||||
conn.sync(StringCodec.INSTANCE, RedisCommands.SET, "test", 0);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<groupId>io.sirix</groupId>
|
||||
<artifactId>sirix</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>core-api-tutorial</name>
|
||||
<name>sirix</name>
|
||||
<packaging>jar</packaging>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<groupId>com.baeldung.boot.persistence</groupId>
|
||||
<artifactId>spring-boot-persistence-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-jdbi</name>
|
||||
<name>spring-boot-persistence-2</name>
|
||||
<description>Sample SpringBoot JDBI Project</description>
|
||||
|
||||
<parent>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
- [Guide to Elasticsearch in Java](https://www.baeldung.com/elasticsearch-java)
|
||||
- [Geospatial Support in ElasticSearch](https://www.baeldung.com/elasticsearch-geo-spatial)
|
||||
- [A Simple Tagging Implementation with Elasticsearch](https://www.baeldung.com/elasticsearch-tagging)
|
||||
- [Introduction to Spring Data Elasticsearch (evaluation)](https://www.baeldung.com/spring-data-elasticsearch-test-2)
|
||||
|
||||
### Build the Project with Tests Running
|
||||
```
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
- [Spring JPA @Embedded and @EmbeddedId](https://www.baeldung.com/spring-jpa-embedded-method-parameters)
|
||||
- [Generate Database Schema with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-generate-db-schema)
|
||||
- [Partial Data Update with Spring Data](https://www.baeldung.com/spring-data-partial-update)
|
||||
|
||||
### Eclipse Config
|
||||
After importing the project into Eclipse, you may see the following error:
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
<version>1.3.1.Final</version>
|
||||
<version>${mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -68,4 +68,14 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<spring-boot-version>2.1.9.RELEASE</spring-boot-version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<start-class>com.baeldung.springdatageode.app.ClientCacheApp</start-class>
|
||||
<spring-geode-starter-version>1.1.1.RELEASE</spring-geode-starter-version>
|
||||
<spring.boot.starter.version>2.1.9.RELEASE</spring.boot.starter.version>
|
||||
<mapstruct.version>1.3.1.Final</mapstruct.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-releasetrain</artifactId>
|
||||
<version>Lovelace-SR9</version>
|
||||
<version>${spring-releasetrain}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
<mysema.maven.version>1.1.3</mysema.maven.version>
|
||||
<mongodb-reactivestreams.version>1.9.2</mongodb-reactivestreams.version>
|
||||
<projectreactor.version>3.2.0.RELEASE</projectreactor.version>
|
||||
<spring-releasetrain>Lovelace-SR9</spring-releasetrain>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||
@@ -60,7 +61,7 @@ public class PersistenceConfig {
|
||||
}
|
||||
|
||||
@Bean("auditorProvider")
|
||||
public AuditorAwareImpl auditorAwareImpl() {
|
||||
public AuditorAware<String> auditorProvider() {
|
||||
return new AuditorAwareImpl();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
- [Self-Contained Testing Using an In-Memory Database](https://www.baeldung.com/spring-jpa-test-in-memory-database)
|
||||
- [A Guide to Spring AbstractRoutingDatasource](https://www.baeldung.com/spring-abstract-routing-data-source)
|
||||
- [Obtaining Auto-generated Keys in Spring JDBC](https://www.baeldung.com/spring-jdbc-autogenerated-keys)
|
||||
- [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring)
|
||||
- [Use Criteria Queries in a Spring Data Application](https://www.baeldung.com/spring-data-criteria-queries)
|
||||
- [Many-To-Many Relationship in JPA](https://www.baeldung.com/jpa-many-to-many)
|
||||
- [Spring Persistence (Hibernate and JPA) with a JNDI datasource](https://www.baeldung.com/spring-persistence-hibernate-and-jpa-with-a-jndi-datasource-2)
|
||||
|
||||
|
||||
### Eclipse Config
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
- [Spring JdbcTemplate Unit Testing](https://www.baeldung.com/spring-jdbctemplate-testing)
|
||||
- [Using a List of Values in a JdbcTemplate IN Clause](https://www.baeldung.com/spring-jdbctemplate-in-list)
|
||||
- [Transactional Annotations: Spring vs. JTA](https://www.baeldung.com/spring-vs-jta-transactional)
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
<version>${h2.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- simple-jndi -->
|
||||
<dependency>
|
||||
<groupId>com.github.h-thurow</groupId>
|
||||
<artifactId>simple-jndi</artifactId>
|
||||
<version>${simple-jndi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test scoped -->
|
||||
<dependency>
|
||||
@@ -53,6 +60,8 @@
|
||||
<org.springframework.version>5.2.4.RELEASE</org.springframework.version>
|
||||
<!-- persistence -->
|
||||
<h2.version>1.4.200</h2.version>
|
||||
<!-- simple-jndi -->
|
||||
<simple-jndi.version>0.23.0</simple-jndi.version>
|
||||
<!-- test scoped -->
|
||||
<mockito.version>3.3.3</mockito.version>
|
||||
</properties>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
|
||||
org.osjava.sj.jndi.shared=true
|
||||
org.osjava.sj.delimiter=.
|
||||
jndi.syntax.separator=/
|
||||
org.osjava.sj.space=java:/comp/env
|
||||
org.osjava.sj.root=src/main/resources/jndi
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
ds.type=javax.sql.DataSource
|
||||
ds.driver=org.h2.Driver
|
||||
ds.url=jdbc:jdbc:h2:mem:testdb
|
||||
ds.user=sa
|
||||
ds.password=password
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.jndi.datasource;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class SimpleJNDIUnitTest {
|
||||
|
||||
private InitialContext initContext;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
this.initContext = new InitialContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMockJndiDataSource_thenReturnJndiDataSource() throws Exception {
|
||||
String dsString = "org.h2.Driver::::jdbc:jdbc:h2:mem:testdb::::sa";
|
||||
Context envContext = (Context) this.initContext.lookup("java:/comp/env");
|
||||
DataSource ds = (DataSource) envContext.lookup("datasource/ds");
|
||||
|
||||
assertEquals(dsString, ds.toString());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
if (this.initContext != null) {
|
||||
this.initContext.close();
|
||||
this.initContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.jndi.datasource;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.mock.jndi.SimpleNamingContextBuilder;
|
||||
|
||||
// marked as a manual test as the bindings in this test and
|
||||
// SimpleJNDIUnitTest conflict depending on the order they are run in
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SimpleNamingContextBuilderManualTest {
|
||||
|
||||
private InitialContext initContext;
|
||||
|
||||
@BeforeEach
|
||||
public void init() throws Exception {
|
||||
SimpleNamingContextBuilder.emptyActivatedContextBuilder();
|
||||
this.initContext = new InitialContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMockJndiDataSource_thenReturnJndiDataSource() throws Exception {
|
||||
this.initContext.bind("java:comp/env/jdbc/datasource", new DriverManagerDataSource("jdbc:h2:mem:testdb"));
|
||||
DataSource ds = (DataSource) this.initContext.lookup("java:comp/env/jdbc/datasource");
|
||||
|
||||
assertNotNull(ds.getConnection());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
if (this.initContext != null) {
|
||||
this.initContext.close();
|
||||
this.initContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user