diff --git a/apache-avro/README.md b/apache-avro/README.md
deleted file mode 100644
index b338e8e565..0000000000
--- a/apache-avro/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-## Apache Avro
-
-This module contains articles about Apache Avro
-
-### Relevant Articles:
-- [Guide to Apache Avro](https://www.baeldung.com/java-apache-avro)
diff --git a/apache-avro/pom.xml b/apache-avro/pom.xml
deleted file mode 100644
index ad32ebb702..0000000000
--- a/apache-avro/pom.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
- 4.0.0
- apache-avro
- 0.0.1-SNAPSHOT
- apache-avro
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.slf4j
- slf4j-simple
- ${slf4j.version}
- compile
-
-
- org.apache.avro
- avro
- ${avro.version}
-
-
- org.apache.avro
- avro-compiler
- ${avro.version}
-
-
-
- org.apache.avro
- avro-maven-plugin
- ${avro.version}
-
-
-
-
-
-
- org.apache.avro
- avro-maven-plugin
- ${avro.version}
-
-
- schemas
- generate-sources
-
- schema
- protocol
- idl-protocol
-
-
- ${project.basedir}/src/main/resources/
- ${project.basedir}/src/main/java/
-
-
-
-
-
-
-
-
- 1.8.2
- 1.7.25
-
-
-
diff --git a/apache-beam/README.md b/apache-beam/README.md
deleted file mode 100644
index a71e5256a8..0000000000
--- a/apache-beam/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Relevant Articles:
-
-- [Introduction to Apache Beam](https://www.baeldung.com/apache-beam)
diff --git a/apache-beam/pom.xml b/apache-beam/pom.xml
deleted file mode 100644
index 7a714ac480..0000000000
--- a/apache-beam/pom.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
- 4.0.0
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
- com.baeldung.apache
- apache-beam
- 0.0.1-SNAPSHOT
-
-
-
- org.apache.beam
- beam-sdks-java-core
- ${beam.version}
-
-
-
- org.apache.beam
- beam-runners-direct-java
- ${beam.version}
- runtime
-
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
-
-
- 2.19.0
- 3.6.1
-
-
-
diff --git a/apache-bval/README.md b/apache-bval/README.md
deleted file mode 100644
index e856810378..0000000000
--- a/apache-bval/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache BVal
-
-This module contains articles about Apache BVal
-
-### Relevant Articles:
-
-- [Intro to Apache BVal](https://www.baeldung.com/apache-bval)
diff --git a/apache-bval/pom.xml b/apache-bval/pom.xml
deleted file mode 100644
index 49484f4959..0000000000
--- a/apache-bval/pom.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
- 4.0.0
- apache-bval
- 0.0.1-SNAPSHOT
- apache-bval
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.bval
- bval-jsr
- ${bval.version}
-
-
- javax.validation
- validation-api
- ${javax.validation.validation-api.version}
-
-
- org.apache.bval
- bval-extras
- ${bval.version}
-
-
-
-
- 1.1.2
- 1.1.0.Final
-
-
-
\ No newline at end of file
diff --git a/apache-curator/README.md b/apache-curator/README.md
deleted file mode 100644
index 4fef6a138e..0000000000
--- a/apache-curator/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Curator
-
-This module contains articles about Apache Curator
-
-### Relevant Articles:
-
-- [Introduction to Apache Curator](https://www.baeldung.com/apache-curator)
diff --git a/apache-curator/pom.xml b/apache-curator/pom.xml
deleted file mode 100644
index 5b249127d9..0000000000
--- a/apache-curator/pom.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
- 4.0.0
- apache-curator
- 0.0.1-SNAPSHOT
- apache-curator
- jar
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
-
- org.apache.curator
- curator-x-async
- ${curator.version}
-
-
- org.apache.zookeeper
- zookeeper
-
-
-
-
- org.apache.curator
- curator-recipes
- ${curator.version}
-
-
- org.apache.zookeeper
- zookeeper
- ${zookeeper.version}
-
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson.version}
-
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
- com.jayway.awaitility
- awaitility
- ${avaitility.version}
- test
-
-
-
-
- 4.0.1
- 3.4.11
-
- 3.6.1
- 1.7.0
-
-
-
\ No newline at end of file
diff --git a/apache-curator/src/main/resources/logback.xml b/apache-curator/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/apache-curator/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apache-geode/README.md b/apache-geode/README.md
deleted file mode 100644
index 86629f7a82..0000000000
--- a/apache-geode/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Geode
-
-This module contains articles about Apache Geode
-
-### Relevant Articles:
-
-- [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode)
diff --git a/apache-geode/pom.xml b/apache-geode/pom.xml
deleted file mode 100644
index fc5b253c01..0000000000
--- a/apache-geode/pom.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- 4.0.0
- apache-geode
- 1.0-SNAPSHOT
- apache-geode
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.geode
- geode-core
- ${geode.core}
-
-
-
-
- 1.6.0
-
-
-
\ No newline at end of file
diff --git a/apache-libraries/README.md b/apache-libraries/README.md
new file mode 100644
index 0000000000..1fc0dd0842
--- /dev/null
+++ b/apache-libraries/README.md
@@ -0,0 +1,15 @@
+## Apache Libraries
+
+This module contains articles about various Apache libraries and utilities
+
+### Relevant Articles:
+- [Guide to Apache Avro](https://www.baeldung.com/java-apache-avro)
+- [Introduction to Apache Beam](https://www.baeldung.com/apache-beam)
+- [Intro to Apache BVal](https://www.baeldung.com/apache-bval)
+- [Building a Microservice with Apache Meecrowave](https://www.baeldung.com/apache-meecrowave)
+- [Intro to Apache OpenNLP](https://www.baeldung.com/apache-open-nlp)
+- [Introduction to Apache Pulsar](https://www.baeldung.com/apache-pulsar)
+- [Getting Started with Java and Zookeeper](https://www.baeldung.com/java-zookeeper)
+- [Introduction to Apache Curator](https://www.baeldung.com/apache-curator)
+- [A Quick Guide to Apache Geode](https://www.baeldung.com/apache-geode)
+- [Guide to Solr in Java with Apache Solrj](https://www.baeldung.com/apache-solrj)
diff --git a/apache-libraries/pom.xml b/apache-libraries/pom.xml
new file mode 100644
index 0000000000..fc655967ed
--- /dev/null
+++ b/apache-libraries/pom.xml
@@ -0,0 +1,223 @@
+
+
+ 4.0.0
+ apache-miscellaneous-1
+ 0.0.1-SNAPSHOT
+ apache-libraries
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+
+ org.apache.avro
+ avro
+ ${avro.version}
+
+
+ org.apache.avro
+ avro-compiler
+ ${avro.version}
+
+
+ org.apache.avro
+ avro-maven-plugin
+ ${avro.version}
+
+
+
+
+ org.apache.beam
+ beam-sdks-java-core
+ ${beam.version}
+
+
+
+ org.apache.beam
+ beam-runners-direct-java
+ ${beam.version}
+ runtime
+
+
+
+
+ org.apache.bval
+ bval-jsr
+ ${bval.version}
+
+
+ javax.validation
+ validation-api
+ ${javax.validation.validation-api.version}
+
+
+ org.apache.bval
+ bval-extras
+ ${bval.version}
+
+
+
+
+ org.apache.meecrowave
+ meecrowave-core
+ ${meecrowave-core.version}
+
+
+
+ org.apache.meecrowave
+ meecrowave-jpa
+ ${meecrowave-jpa.version}
+
+
+ com.squareup.okhttp3
+ okhttp
+ ${okhttp.version}
+
+
+ org.apache.meecrowave
+ meecrowave-junit
+ ${meecrowave-junit.version}
+ test
+
+
+
+
+ org.apache.opennlp
+ opennlp-tools
+ ${opennlp.opennlp-tools.version}
+
+
+
+
+ org.apache.pulsar
+ pulsar-client
+ ${pulsar-client.version}
+ compile
+
+
+
+
+ org.apache.zookeeper
+ zookeeper
+ ${zookeeper.version}
+
+
+
+
+ org.apache.curator
+ curator-x-async
+ ${curator.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+
+
+
+
+ org.apache.curator
+ curator-recipes
+ ${curator.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+ ${zookeeper.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ com.jayway.awaitility
+ awaitility
+ ${avaitility.version}
+ test
+
+
+
+
+ org.apache.geode
+ geode-core
+ ${geode.core}
+
+
+
+
+ org.apache.solr
+ solr-solrj
+ ${solr.solr-solrj.version}
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
+
+
+
+
+ org.apache.avro
+ avro-maven-plugin
+ ${avro.version}
+
+
+ schemas
+ generate-sources
+
+ schema
+ protocol
+ idl-protocol
+
+
+ ${project.basedir}/src/main/resources/
+ ${project.basedir}/src/main/java/
+
+
+
+
+
+
+
+ org.apache.meecrowave
+ meecrowave-maven-plugin
+ ${meecrowave-maven-plugin.version}
+
+
+
+
+
+ 1.8
+ 1.8
+ 1.8.2
+ 1.7.25
+ 2.19.0
+ 3.9.0
+ 1.1.2
+ 1.1.0.Final
+ 1.2.0
+ 3.10.0
+ 1.2.1
+ 1.2.1
+ 1.2.1
+ 1.8.4
+ 2.1.1-incubating
+ 3.4.11
+ 4.0.1
+ 1.7.0
+ 1.6.0
+ 6.4.0
+
+
+
diff --git a/apache-beam/src/main/java/com/baeldung/apache/beam/intro/WordCount.java b/apache-libraries/src/main/java/com/baeldung/apache/beam/intro/WordCount.java
similarity index 100%
rename from apache-beam/src/main/java/com/baeldung/apache/beam/intro/WordCount.java
rename to apache-libraries/src/main/java/com/baeldung/apache/beam/intro/WordCount.java
diff --git a/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java b/apache-libraries/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
similarity index 100%
rename from apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
rename to apache-libraries/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
diff --git a/apache-libraries/src/main/java/com/baeldung/avro/model/Active.java b/apache-libraries/src/main/java/com/baeldung/avro/model/Active.java
new file mode 100644
index 0000000000..06624df246
--- /dev/null
+++ b/apache-libraries/src/main/java/com/baeldung/avro/model/Active.java
@@ -0,0 +1,13 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.model;
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public enum Active {
+ YES, NO ;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"enum\",\"name\":\"Active\",\"namespace\":\"com.baeldung.avro.model\",\"symbols\":[\"YES\",\"NO\"]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+}
diff --git a/apache-libraries/src/main/java/com/baeldung/avro/model/AvroHttpRequest.java b/apache-libraries/src/main/java/com/baeldung/avro/model/AvroHttpRequest.java
new file mode 100644
index 0000000000..584ccfc21c
--- /dev/null
+++ b/apache-libraries/src/main/java/com/baeldung/avro/model/AvroHttpRequest.java
@@ -0,0 +1,491 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.model;
+
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class AvroHttpRequest extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+ private static final long serialVersionUID = -8649010116827875312L;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroHttpRequest\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"requestTime\",\"type\":\"long\"},{\"name\":\"clientIdentifier\",\"type\":{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}},{\"name\":\"employeeNames\",\"type\":{\"type\":\"array\",\"items\":\"string\"},\"default\":null},{\"name\":\"active\",\"type\":{\"type\":\"enum\",\"name\":\"Active\",\"symbols\":[\"YES\",\"NO\"]}}]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+ private static SpecificData MODEL$ = new SpecificData();
+
+ private static final BinaryMessageEncoder ENCODER =
+ new BinaryMessageEncoder(MODEL$, SCHEMA$);
+
+ private static final BinaryMessageDecoder DECODER =
+ new BinaryMessageDecoder(MODEL$, SCHEMA$);
+
+ /**
+ * Return the BinaryMessageDecoder instance used by this class.
+ */
+ public static BinaryMessageDecoder getDecoder() {
+ return DECODER;
+ }
+
+ /**
+ * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+ * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+ */
+ public static BinaryMessageDecoder createDecoder(SchemaStore resolver) {
+ return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver);
+ }
+
+ /** Serializes this AvroHttpRequest to a ByteBuffer. */
+ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+ return ENCODER.encode(this);
+ }
+
+ /** Deserializes a AvroHttpRequest from a ByteBuffer. */
+ public static AvroHttpRequest fromByteBuffer(
+ java.nio.ByteBuffer b) throws java.io.IOException {
+ return DECODER.decode(b);
+ }
+
+ @Deprecated public long requestTime;
+ @Deprecated public com.baeldung.avro.model.ClientIdentifier clientIdentifier;
+ @Deprecated public java.util.List employeeNames;
+ @Deprecated public com.baeldung.avro.model.Active active;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use newBuilder()
.
+ */
+ public AvroHttpRequest() {}
+
+ /**
+ * All-args constructor.
+ * @param requestTime The new value for requestTime
+ * @param clientIdentifier The new value for clientIdentifier
+ * @param employeeNames The new value for employeeNames
+ * @param active The new value for active
+ */
+ public AvroHttpRequest(java.lang.Long requestTime, com.baeldung.avro.model.ClientIdentifier clientIdentifier, java.util.List employeeNames, com.baeldung.avro.model.Active active) {
+ this.requestTime = requestTime;
+ this.clientIdentifier = clientIdentifier;
+ this.employeeNames = employeeNames;
+ this.active = active;
+ }
+
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return requestTime;
+ case 1: return clientIdentifier;
+ case 2: return employeeNames;
+ case 3: return active;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: requestTime = (java.lang.Long)value$; break;
+ case 1: clientIdentifier = (com.baeldung.avro.model.ClientIdentifier)value$; break;
+ case 2: employeeNames = (java.util.List)value$; break;
+ case 3: active = (com.baeldung.avro.model.Active)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'requestTime' field.
+ * @return The value of the 'requestTime' field.
+ */
+ public java.lang.Long getRequestTime() {
+ return requestTime;
+ }
+
+ /**
+ * Sets the value of the 'requestTime' field.
+ * @param value the value to set.
+ */
+ public void setRequestTime(java.lang.Long value) {
+ this.requestTime = value;
+ }
+
+ /**
+ * Gets the value of the 'clientIdentifier' field.
+ * @return The value of the 'clientIdentifier' field.
+ */
+ public com.baeldung.avro.model.ClientIdentifier getClientIdentifier() {
+ return clientIdentifier;
+ }
+
+ /**
+ * Sets the value of the 'clientIdentifier' field.
+ * @param value the value to set.
+ */
+ public void setClientIdentifier(com.baeldung.avro.model.ClientIdentifier value) {
+ this.clientIdentifier = value;
+ }
+
+ /**
+ * Gets the value of the 'employeeNames' field.
+ * @return The value of the 'employeeNames' field.
+ */
+ public java.util.List getEmployeeNames() {
+ return employeeNames;
+ }
+
+ /**
+ * Sets the value of the 'employeeNames' field.
+ * @param value the value to set.
+ */
+ public void setEmployeeNames(java.util.List value) {
+ this.employeeNames = value;
+ }
+
+ /**
+ * Gets the value of the 'active' field.
+ * @return The value of the 'active' field.
+ */
+ public com.baeldung.avro.model.Active getActive() {
+ return active;
+ }
+
+ /**
+ * Sets the value of the 'active' field.
+ * @param value the value to set.
+ */
+ public void setActive(com.baeldung.avro.model.Active value) {
+ this.active = value;
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static com.baeldung.avro.model.AvroHttpRequest.Builder newBuilder() {
+ return new com.baeldung.avro.model.AvroHttpRequest.Builder();
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder by copying an existing Builder.
+ * @param other The existing builder to copy.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static com.baeldung.avro.model.AvroHttpRequest.Builder newBuilder(com.baeldung.avro.model.AvroHttpRequest.Builder other) {
+ return new com.baeldung.avro.model.AvroHttpRequest.Builder(other);
+ }
+
+ /**
+ * Creates a new AvroHttpRequest RecordBuilder by copying an existing AvroHttpRequest instance.
+ * @param other The existing instance to copy.
+ * @return A new AvroHttpRequest RecordBuilder
+ */
+ public static com.baeldung.avro.model.AvroHttpRequest.Builder newBuilder(com.baeldung.avro.model.AvroHttpRequest other) {
+ return new com.baeldung.avro.model.AvroHttpRequest.Builder(other);
+ }
+
+ /**
+ * RecordBuilder for AvroHttpRequest instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase
+ implements org.apache.avro.data.RecordBuilder {
+
+ private long requestTime;
+ private com.baeldung.avro.model.ClientIdentifier clientIdentifier;
+ private com.baeldung.avro.model.ClientIdentifier.Builder clientIdentifierBuilder;
+ private java.util.List employeeNames;
+ private com.baeldung.avro.model.Active active;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(SCHEMA$);
+ }
+
+ /**
+ * Creates a Builder by copying an existing Builder.
+ * @param other The existing Builder to copy.
+ */
+ private Builder(com.baeldung.avro.model.AvroHttpRequest.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.requestTime)) {
+ this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.clientIdentifier)) {
+ this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier);
+ fieldSetFlags()[1] = true;
+ }
+ if (other.hasClientIdentifierBuilder()) {
+ this.clientIdentifierBuilder = com.baeldung.avro.model.ClientIdentifier.newBuilder(other.getClientIdentifierBuilder());
+ }
+ if (isValidValue(fields()[2], other.employeeNames)) {
+ this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.active)) {
+ this.active = data().deepCopy(fields()[3].schema(), other.active);
+ fieldSetFlags()[3] = true;
+ }
+ }
+
+ /**
+ * Creates a Builder by copying an existing AvroHttpRequest instance
+ * @param other The existing instance to copy.
+ */
+ private Builder(com.baeldung.avro.model.AvroHttpRequest other) {
+ super(SCHEMA$);
+ if (isValidValue(fields()[0], other.requestTime)) {
+ this.requestTime = data().deepCopy(fields()[0].schema(), other.requestTime);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.clientIdentifier)) {
+ this.clientIdentifier = data().deepCopy(fields()[1].schema(), other.clientIdentifier);
+ fieldSetFlags()[1] = true;
+ }
+ this.clientIdentifierBuilder = null;
+ if (isValidValue(fields()[2], other.employeeNames)) {
+ this.employeeNames = data().deepCopy(fields()[2].schema(), other.employeeNames);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.active)) {
+ this.active = data().deepCopy(fields()[3].schema(), other.active);
+ fieldSetFlags()[3] = true;
+ }
+ }
+
+ /**
+ * Gets the value of the 'requestTime' field.
+ * @return The value.
+ */
+ public java.lang.Long getRequestTime() {
+ return requestTime;
+ }
+
+ /**
+ * Sets the value of the 'requestTime' field.
+ * @param value The value of 'requestTime'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder setRequestTime(long value) {
+ validate(fields()[0], value);
+ this.requestTime = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'requestTime' field has been set.
+ * @return True if the 'requestTime' field has been set, false otherwise.
+ */
+ public boolean hasRequestTime() {
+ return fieldSetFlags()[0];
+ }
+
+
+ /**
+ * Clears the value of the 'requestTime' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder clearRequestTime() {
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'clientIdentifier' field.
+ * @return The value.
+ */
+ public com.baeldung.avro.model.ClientIdentifier getClientIdentifier() {
+ return clientIdentifier;
+ }
+
+ /**
+ * Sets the value of the 'clientIdentifier' field.
+ * @param value The value of 'clientIdentifier'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder setClientIdentifier(com.baeldung.avro.model.ClientIdentifier value) {
+ validate(fields()[1], value);
+ this.clientIdentifierBuilder = null;
+ this.clientIdentifier = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'clientIdentifier' field has been set.
+ * @return True if the 'clientIdentifier' field has been set, false otherwise.
+ */
+ public boolean hasClientIdentifier() {
+ return fieldSetFlags()[1];
+ }
+
+ /**
+ * Gets the Builder instance for the 'clientIdentifier' field and creates one if it doesn't exist yet.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.ClientIdentifier.Builder getClientIdentifierBuilder() {
+ if (clientIdentifierBuilder == null) {
+ if (hasClientIdentifier()) {
+ setClientIdentifierBuilder(com.baeldung.avro.model.ClientIdentifier.newBuilder(clientIdentifier));
+ } else {
+ setClientIdentifierBuilder(com.baeldung.avro.model.ClientIdentifier.newBuilder());
+ }
+ }
+ return clientIdentifierBuilder;
+ }
+
+ /**
+ * Sets the Builder instance for the 'clientIdentifier' field
+ * @param value The builder instance that must be set.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder setClientIdentifierBuilder(com.baeldung.avro.model.ClientIdentifier.Builder value) {
+ clearClientIdentifier();
+ clientIdentifierBuilder = value;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'clientIdentifier' field has an active Builder instance
+ * @return True if the 'clientIdentifier' field has an active Builder instance
+ */
+ public boolean hasClientIdentifierBuilder() {
+ return clientIdentifierBuilder != null;
+ }
+
+ /**
+ * Clears the value of the 'clientIdentifier' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder clearClientIdentifier() {
+ clientIdentifier = null;
+ clientIdentifierBuilder = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'employeeNames' field.
+ * @return The value.
+ */
+ public java.util.List getEmployeeNames() {
+ return employeeNames;
+ }
+
+ /**
+ * Sets the value of the 'employeeNames' field.
+ * @param value The value of 'employeeNames'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder setEmployeeNames(java.util.List value) {
+ validate(fields()[2], value);
+ this.employeeNames = value;
+ fieldSetFlags()[2] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'employeeNames' field has been set.
+ * @return True if the 'employeeNames' field has been set, false otherwise.
+ */
+ public boolean hasEmployeeNames() {
+ return fieldSetFlags()[2];
+ }
+
+
+ /**
+ * Clears the value of the 'employeeNames' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder clearEmployeeNames() {
+ employeeNames = null;
+ fieldSetFlags()[2] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'active' field.
+ * @return The value.
+ */
+ public com.baeldung.avro.model.Active getActive() {
+ return active;
+ }
+
+ /**
+ * Sets the value of the 'active' field.
+ * @param value The value of 'active'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder setActive(com.baeldung.avro.model.Active value) {
+ validate(fields()[3], value);
+ this.active = value;
+ fieldSetFlags()[3] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'active' field has been set.
+ * @return True if the 'active' field has been set, false otherwise.
+ */
+ public boolean hasActive() {
+ return fieldSetFlags()[3];
+ }
+
+
+ /**
+ * Clears the value of the 'active' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.AvroHttpRequest.Builder clearActive() {
+ active = null;
+ fieldSetFlags()[3] = false;
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public AvroHttpRequest build() {
+ try {
+ AvroHttpRequest record = new AvroHttpRequest();
+ record.requestTime = fieldSetFlags()[0] ? this.requestTime : (java.lang.Long) defaultValue(fields()[0]);
+ if (clientIdentifierBuilder != null) {
+ record.clientIdentifier = this.clientIdentifierBuilder.build();
+ } else {
+ record.clientIdentifier = fieldSetFlags()[1] ? this.clientIdentifier : (com.baeldung.avro.model.ClientIdentifier) defaultValue(fields()[1]);
+ }
+ record.employeeNames = fieldSetFlags()[2] ? this.employeeNames : (java.util.List) defaultValue(fields()[2]);
+ record.active = fieldSetFlags()[3] ? this.active : (com.baeldung.avro.model.Active) defaultValue(fields()[3]);
+ return record;
+ } catch (java.lang.Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumWriter
+ WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$);
+
+ @Override public void writeExternal(java.io.ObjectOutput out)
+ throws java.io.IOException {
+ WRITER$.write(this, SpecificData.getEncoder(out));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumReader
+ READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$);
+
+ @Override public void readExternal(java.io.ObjectInput in)
+ throws java.io.IOException {
+ READER$.read(this, SpecificData.getDecoder(in));
+ }
+
+}
diff --git a/apache-libraries/src/main/java/com/baeldung/avro/model/ClientIdentifier.java b/apache-libraries/src/main/java/com/baeldung/avro/model/ClientIdentifier.java
new file mode 100644
index 0000000000..6d1f9a7e75
--- /dev/null
+++ b/apache-libraries/src/main/java/com/baeldung/avro/model/ClientIdentifier.java
@@ -0,0 +1,308 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package com.baeldung.avro.model;
+
+import org.apache.avro.specific.SpecificData;
+import org.apache.avro.message.BinaryMessageEncoder;
+import org.apache.avro.message.BinaryMessageDecoder;
+import org.apache.avro.message.SchemaStore;
+
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class ClientIdentifier extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+ private static final long serialVersionUID = 8754570983127295424L;
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"ClientIdentifier\",\"namespace\":\"com.baeldung.avro.model\",\"fields\":[{\"name\":\"hostName\",\"type\":\"string\"},{\"name\":\"ipAddress\",\"type\":\"string\"}]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+
+ private static SpecificData MODEL$ = new SpecificData();
+
+ private static final BinaryMessageEncoder ENCODER =
+ new BinaryMessageEncoder(MODEL$, SCHEMA$);
+
+ private static final BinaryMessageDecoder DECODER =
+ new BinaryMessageDecoder(MODEL$, SCHEMA$);
+
+ /**
+ * Return the BinaryMessageDecoder instance used by this class.
+ */
+ public static BinaryMessageDecoder getDecoder() {
+ return DECODER;
+ }
+
+ /**
+ * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
+ * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
+ */
+ public static BinaryMessageDecoder createDecoder(SchemaStore resolver) {
+ return new BinaryMessageDecoder(MODEL$, SCHEMA$, resolver);
+ }
+
+ /** Serializes this ClientIdentifier to a ByteBuffer. */
+ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
+ return ENCODER.encode(this);
+ }
+
+ /** Deserializes a ClientIdentifier from a ByteBuffer. */
+ public static ClientIdentifier fromByteBuffer(
+ java.nio.ByteBuffer b) throws java.io.IOException {
+ return DECODER.decode(b);
+ }
+
+ @Deprecated public java.lang.CharSequence hostName;
+ @Deprecated public java.lang.CharSequence ipAddress;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use newBuilder()
.
+ */
+ public ClientIdentifier() {}
+
+ /**
+ * All-args constructor.
+ * @param hostName The new value for hostName
+ * @param ipAddress The new value for ipAddress
+ */
+ public ClientIdentifier(java.lang.CharSequence hostName, java.lang.CharSequence ipAddress) {
+ this.hostName = hostName;
+ this.ipAddress = ipAddress;
+ }
+
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return hostName;
+ case 1: return ipAddress;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: hostName = (java.lang.CharSequence)value$; break;
+ case 1: ipAddress = (java.lang.CharSequence)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'hostName' field.
+ * @return The value of the 'hostName' field.
+ */
+ public java.lang.CharSequence getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Sets the value of the 'hostName' field.
+ * @param value the value to set.
+ */
+ public void setHostName(java.lang.CharSequence value) {
+ this.hostName = value;
+ }
+
+ /**
+ * Gets the value of the 'ipAddress' field.
+ * @return The value of the 'ipAddress' field.
+ */
+ public java.lang.CharSequence getIpAddress() {
+ return ipAddress;
+ }
+
+ /**
+ * Sets the value of the 'ipAddress' field.
+ * @param value the value to set.
+ */
+ public void setIpAddress(java.lang.CharSequence value) {
+ this.ipAddress = value;
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static com.baeldung.avro.model.ClientIdentifier.Builder newBuilder() {
+ return new com.baeldung.avro.model.ClientIdentifier.Builder();
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder by copying an existing Builder.
+ * @param other The existing builder to copy.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static com.baeldung.avro.model.ClientIdentifier.Builder newBuilder(com.baeldung.avro.model.ClientIdentifier.Builder other) {
+ return new com.baeldung.avro.model.ClientIdentifier.Builder(other);
+ }
+
+ /**
+ * Creates a new ClientIdentifier RecordBuilder by copying an existing ClientIdentifier instance.
+ * @param other The existing instance to copy.
+ * @return A new ClientIdentifier RecordBuilder
+ */
+ public static com.baeldung.avro.model.ClientIdentifier.Builder newBuilder(com.baeldung.avro.model.ClientIdentifier other) {
+ return new com.baeldung.avro.model.ClientIdentifier.Builder(other);
+ }
+
+ /**
+ * RecordBuilder for ClientIdentifier instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase
+ implements org.apache.avro.data.RecordBuilder {
+
+ private java.lang.CharSequence hostName;
+ private java.lang.CharSequence ipAddress;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(SCHEMA$);
+ }
+
+ /**
+ * Creates a Builder by copying an existing Builder.
+ * @param other The existing Builder to copy.
+ */
+ private Builder(com.baeldung.avro.model.ClientIdentifier.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.hostName)) {
+ this.hostName = data().deepCopy(fields()[0].schema(), other.hostName);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.ipAddress)) {
+ this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress);
+ fieldSetFlags()[1] = true;
+ }
+ }
+
+ /**
+ * Creates a Builder by copying an existing ClientIdentifier instance
+ * @param other The existing instance to copy.
+ */
+ private Builder(com.baeldung.avro.model.ClientIdentifier other) {
+ super(SCHEMA$);
+ if (isValidValue(fields()[0], other.hostName)) {
+ this.hostName = data().deepCopy(fields()[0].schema(), other.hostName);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.ipAddress)) {
+ this.ipAddress = data().deepCopy(fields()[1].schema(), other.ipAddress);
+ fieldSetFlags()[1] = true;
+ }
+ }
+
+ /**
+ * Gets the value of the 'hostName' field.
+ * @return The value.
+ */
+ public java.lang.CharSequence getHostName() {
+ return hostName;
+ }
+
+ /**
+ * Sets the value of the 'hostName' field.
+ * @param value The value of 'hostName'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.ClientIdentifier.Builder setHostName(java.lang.CharSequence value) {
+ validate(fields()[0], value);
+ this.hostName = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'hostName' field has been set.
+ * @return True if the 'hostName' field has been set, false otherwise.
+ */
+ public boolean hasHostName() {
+ return fieldSetFlags()[0];
+ }
+
+
+ /**
+ * Clears the value of the 'hostName' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.ClientIdentifier.Builder clearHostName() {
+ hostName = null;
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /**
+ * Gets the value of the 'ipAddress' field.
+ * @return The value.
+ */
+ public java.lang.CharSequence getIpAddress() {
+ return ipAddress;
+ }
+
+ /**
+ * Sets the value of the 'ipAddress' field.
+ * @param value The value of 'ipAddress'.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.ClientIdentifier.Builder setIpAddress(java.lang.CharSequence value) {
+ validate(fields()[1], value);
+ this.ipAddress = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /**
+ * Checks whether the 'ipAddress' field has been set.
+ * @return True if the 'ipAddress' field has been set, false otherwise.
+ */
+ public boolean hasIpAddress() {
+ return fieldSetFlags()[1];
+ }
+
+
+ /**
+ * Clears the value of the 'ipAddress' field.
+ * @return This builder.
+ */
+ public com.baeldung.avro.model.ClientIdentifier.Builder clearIpAddress() {
+ ipAddress = null;
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ClientIdentifier build() {
+ try {
+ ClientIdentifier record = new ClientIdentifier();
+ record.hostName = fieldSetFlags()[0] ? this.hostName : (java.lang.CharSequence) defaultValue(fields()[0]);
+ record.ipAddress = fieldSetFlags()[1] ? this.ipAddress : (java.lang.CharSequence) defaultValue(fields()[1]);
+ return record;
+ } catch (java.lang.Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumWriter
+ WRITER$ = (org.apache.avro.io.DatumWriter)MODEL$.createDatumWriter(SCHEMA$);
+
+ @Override public void writeExternal(java.io.ObjectOutput out)
+ throws java.io.IOException {
+ WRITER$.write(this, SpecificData.getEncoder(out));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static final org.apache.avro.io.DatumReader
+ READER$ = (org.apache.avro.io.DatumReader)MODEL$.createDatumReader(SCHEMA$);
+
+ @Override public void readExternal(java.io.ObjectInput in)
+ throws java.io.IOException {
+ READER$.read(this, SpecificData.getDecoder(in));
+ }
+
+}
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java b/apache-libraries/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/AvroClassGenerator.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java b/apache-libraries/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/AvroSchemaBuilder.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java b/apache-libraries/src/main/java/com/baeldung/avro/util/model/Active.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/model/Active.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/model/Active.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java b/apache-libraries/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/model/AvroHttpRequest.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java b/apache-libraries/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/model/ClientIdentifier.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java b/apache-libraries/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/serealization/AvroDeSerealizer.java
diff --git a/apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java b/apache-libraries/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java
similarity index 100%
rename from apache-avro/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java
rename to apache-libraries/src/main/java/com/baeldung/avro/util/serealization/AvroSerealizer.java
diff --git a/apache-bval/src/main/java/com/baeldung/model/User.java b/apache-libraries/src/main/java/com/baeldung/bval/model/User.java
similarity index 96%
rename from apache-bval/src/main/java/com/baeldung/model/User.java
rename to apache-libraries/src/main/java/com/baeldung/bval/model/User.java
index 477136ddb4..95f09a4e0a 100644
--- a/apache-bval/src/main/java/com/baeldung/model/User.java
+++ b/apache-libraries/src/main/java/com/baeldung/bval/model/User.java
@@ -1,4 +1,4 @@
-package com.baeldung.model;
+package com.baeldung.bval.model;
import java.io.File;
@@ -13,7 +13,7 @@ import org.apache.bval.extras.constraints.creditcard.Visa;
import org.apache.bval.extras.constraints.file.Directory;
import org.apache.bval.extras.constraints.net.InetAddress;
-import com.baeldung.validation.Password;
+import com.baeldung.bval.validation.Password;
public class User {
@NotNull
diff --git a/apache-bval/src/main/java/com/baeldung/validation/Password.java b/apache-libraries/src/main/java/com/baeldung/bval/validation/Password.java
similarity index 94%
rename from apache-bval/src/main/java/com/baeldung/validation/Password.java
rename to apache-libraries/src/main/java/com/baeldung/bval/validation/Password.java
index 4ae06b2fb0..b278612261 100644
--- a/apache-bval/src/main/java/com/baeldung/validation/Password.java
+++ b/apache-libraries/src/main/java/com/baeldung/bval/validation/Password.java
@@ -1,4 +1,4 @@
-package com.baeldung.validation;
+package com.baeldung.bval.validation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
diff --git a/apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java b/apache-libraries/src/main/java/com/baeldung/bval/validation/PasswordValidator.java
similarity index 95%
rename from apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java
rename to apache-libraries/src/main/java/com/baeldung/bval/validation/PasswordValidator.java
index 19038d04d5..46d7ff8d9e 100644
--- a/apache-bval/src/main/java/com/baeldung/validation/PasswordValidator.java
+++ b/apache-libraries/src/main/java/com/baeldung/bval/validation/PasswordValidator.java
@@ -1,4 +1,4 @@
-package com.baeldung.validation;
+package com.baeldung.bval.validation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
diff --git a/apache-geode/src/main/java/com/baeldung/geode/Customer.java b/apache-libraries/src/main/java/com/baeldung/geode/Customer.java
similarity index 100%
rename from apache-geode/src/main/java/com/baeldung/geode/Customer.java
rename to apache-libraries/src/main/java/com/baeldung/geode/Customer.java
diff --git a/apache-geode/src/main/java/com/baeldung/geode/CustomerKey.java b/apache-libraries/src/main/java/com/baeldung/geode/CustomerKey.java
similarity index 100%
rename from apache-geode/src/main/java/com/baeldung/geode/CustomerKey.java
rename to apache-libraries/src/main/java/com/baeldung/geode/CustomerKey.java
diff --git a/apache-geode/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java b/apache-libraries/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java
similarity index 100%
rename from apache-geode/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java
rename to apache-libraries/src/main/java/com/baeldung/geode/functions/UpperCaseNames.java
diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java b/apache-libraries/src/main/java/com/baeldung/meecrowave/Article.java
similarity index 100%
rename from apache-meecrowave/src/main/java/com/baeldung/meecrowave/Article.java
rename to apache-libraries/src/main/java/com/baeldung/meecrowave/Article.java
diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java b/apache-libraries/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java
similarity index 100%
rename from apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java
rename to apache-libraries/src/main/java/com/baeldung/meecrowave/ArticleEndpoints.java
diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java b/apache-libraries/src/main/java/com/baeldung/meecrowave/ArticleService.java
similarity index 100%
rename from apache-meecrowave/src/main/java/com/baeldung/meecrowave/ArticleService.java
rename to apache-libraries/src/main/java/com/baeldung/meecrowave/ArticleService.java
diff --git a/apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java b/apache-libraries/src/main/java/com/baeldung/meecrowave/Server.java
similarity index 100%
rename from apache-meecrowave/src/main/java/com/baeldung/meecrowave/Server.java
rename to apache-libraries/src/main/java/com/baeldung/meecrowave/Server.java
diff --git a/apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java b/apache-libraries/src/main/java/com/baeldung/pulsar/ConsumerUnitTest.java
similarity index 98%
rename from apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java
rename to apache-libraries/src/main/java/com/baeldung/pulsar/ConsumerUnitTest.java
index 82a0028837..be94f1a975 100644
--- a/apache-pulsar/src/main/java/com/baeldung/ConsumerUnitTest.java
+++ b/apache-libraries/src/main/java/com/baeldung/pulsar/ConsumerUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.pulsar;
import java.io.IOException;
diff --git a/apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java b/apache-libraries/src/main/java/com/baeldung/pulsar/ProducerUnitTest.java
similarity index 98%
rename from apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java
rename to apache-libraries/src/main/java/com/baeldung/pulsar/ProducerUnitTest.java
index 10a4b46c4d..45c4def559 100644
--- a/apache-pulsar/src/main/java/com/baeldung/ProducerUnitTest.java
+++ b/apache-libraries/src/main/java/com/baeldung/pulsar/ProducerUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung;
+package com.baeldung.pulsar;
import org.apache.pulsar.client.api.CompressionType;
import org.apache.pulsar.client.api.Message;
diff --git a/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java b/apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/ExclusiveSubscriptionUnitTest.java
similarity index 98%
rename from apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java
rename to apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/ExclusiveSubscriptionUnitTest.java
index 79121347e7..57d4ed5d00 100644
--- a/apache-pulsar/src/main/java/com/baeldung/subscriptions/ExclusiveSubscriptionUnitTest.java
+++ b/apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/ExclusiveSubscriptionUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.subscriptions;
+package com.baeldung.pulsar.subscriptions;
import org.apache.pulsar.client.api.ConsumerBuilder;
import org.apache.pulsar.client.api.Message;
diff --git a/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java b/apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/FailoverSubscriptionUnitTest.java
similarity index 98%
rename from apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java
rename to apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/FailoverSubscriptionUnitTest.java
index 1d13b4b83a..c5395da606 100644
--- a/apache-pulsar/src/main/java/com/baeldung/subscriptions/FailoverSubscriptionUnitTest.java
+++ b/apache-libraries/src/main/java/com/baeldung/pulsar/subscriptions/FailoverSubscriptionUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.subscriptions;
+package com.baeldung.pulsar.subscriptions;
import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.ConsumerBuilder;
diff --git a/apache-solrj/src/main/java/com/baeldung/solrjava/ProductBean.java b/apache-libraries/src/main/java/com/baeldung/solrjava/ProductBean.java
similarity index 100%
rename from apache-solrj/src/main/java/com/baeldung/solrjava/ProductBean.java
rename to apache-libraries/src/main/java/com/baeldung/solrjava/ProductBean.java
diff --git a/apache-solrj/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java b/apache-libraries/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java
similarity index 100%
rename from apache-solrj/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java
rename to apache-libraries/src/main/java/com/baeldung/solrjava/SolrJavaIntegration.java
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java b/apache-libraries/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
similarity index 100%
rename from apache-zookeeper/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
rename to apache-libraries/src/main/java/com/baeldung/zookeeper/connection/ZKConnection.java
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java b/apache-libraries/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
similarity index 100%
rename from apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
rename to apache-libraries/src/main/java/com/baeldung/zookeeper/manager/ZKManager.java
diff --git a/apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java b/apache-libraries/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
similarity index 100%
rename from apache-zookeeper/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
rename to apache-libraries/src/main/java/com/baeldung/zookeeper/manager/ZKManagerImpl.java
diff --git a/apache-avro/src/main/resources/avroHttpRequest-schema.avsc b/apache-libraries/src/main/resources/avroHttpRequest-schema.avsc
similarity index 100%
rename from apache-avro/src/main/resources/avroHttpRequest-schema.avsc
rename to apache-libraries/src/main/resources/avroHttpRequest-schema.avsc
diff --git a/apache-avro/src/main/resources/logback.xml b/apache-libraries/src/main/resources/logback.xml
similarity index 100%
rename from apache-avro/src/main/resources/logback.xml
rename to apache-libraries/src/main/resources/logback.xml
diff --git a/apache-opennlp/src/main/resources/models/DoccatSample.txt b/apache-libraries/src/main/resources/models/DoccatSample.txt
similarity index 100%
rename from apache-opennlp/src/main/resources/models/DoccatSample.txt
rename to apache-libraries/src/main/resources/models/DoccatSample.txt
diff --git a/apache-opennlp/src/main/resources/models/en-sent.bin b/apache-libraries/src/main/resources/models/en-sent.bin
similarity index 100%
rename from apache-opennlp/src/main/resources/models/en-sent.bin
rename to apache-libraries/src/main/resources/models/en-sent.bin
diff --git a/apache-opennlp/src/main/resources/models/en-token.bin b/apache-libraries/src/main/resources/models/en-token.bin
similarity index 100%
rename from apache-opennlp/src/main/resources/models/en-token.bin
rename to apache-libraries/src/main/resources/models/en-token.bin
diff --git a/apache-beam/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java
similarity index 100%
rename from apache-beam/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/beam/intro/WordCountUnitTest.java
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/BaseManualTest.java b/apache-libraries/src/test/java/com/baeldung/apache/curator/BaseManualTest.java
similarity index 100%
rename from apache-curator/src/test/java/com/baeldung/apache/curator/BaseManualTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/curator/BaseManualTest.java
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java b/apache-libraries/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
similarity index 100%
rename from apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java b/apache-libraries/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
similarity index 100%
rename from apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java b/apache-libraries/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
similarity index 100%
rename from apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java b/apache-libraries/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
similarity index 100%
rename from apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/ChunkerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/ChunkerUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/ChunkerUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/ChunkerUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/LanguageDetectorAndTrainingDataUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/LanguageDetectorAndTrainingDataUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/LanguageDetectorAndTrainingDataUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/LanguageDetectorAndTrainingDataUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/LemmetizerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/LemmetizerUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/LemmetizerUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/LemmetizerUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/NamedEntityRecognitionUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/NamedEntityRecognitionUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/NamedEntityRecognitionUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/NamedEntityRecognitionUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/POSTaggerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/POSTaggerUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/POSTaggerUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/POSTaggerUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/SentenceDetectionUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/SentenceDetectionUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/SentenceDetectionUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/SentenceDetectionUnitTest.java
diff --git a/apache-opennlp/src/test/java/com/baeldung/apache/opennlp/TokenizerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/apache/opennlp/TokenizerUnitTest.java
similarity index 100%
rename from apache-opennlp/src/test/java/com/baeldung/apache/opennlp/TokenizerUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/apache/opennlp/TokenizerUnitTest.java
diff --git a/apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java b/apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java
similarity index 100%
rename from apache-avro/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/avro/util/serealization/AvroSerealizerDeSerealizerUnitTest.java
diff --git a/apache-bval/src/test/java/com/baeldung/validation/ValidationIntegrationTest.java b/apache-libraries/src/test/java/com/baeldung/bval/validation/ValidationIntegrationTest.java
similarity index 97%
rename from apache-bval/src/test/java/com/baeldung/validation/ValidationIntegrationTest.java
rename to apache-libraries/src/test/java/com/baeldung/bval/validation/ValidationIntegrationTest.java
index ecbcd100da..344aec06d0 100644
--- a/apache-bval/src/test/java/com/baeldung/validation/ValidationIntegrationTest.java
+++ b/apache-libraries/src/test/java/com/baeldung/bval/validation/ValidationIntegrationTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.validation;
+package com.baeldung.bval.validation;
import java.io.File;
import java.util.Set;
@@ -13,9 +13,9 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.junit.Assert.*;
+import com.baeldung.bval.model.User;
-import com.baeldung.model.User;
+import static org.junit.Assert.*;
public class ValidationIntegrationTest {
private static ValidatorFactory validatorFactory;
diff --git a/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java b/apache-libraries/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java
similarity index 100%
rename from apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java
rename to apache-libraries/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java
diff --git a/apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java b/apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java
similarity index 100%
rename from apache-meecrowave/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java
rename to apache-libraries/src/test/java/com/baeldung/meecrowave/ArticleEndpointsUnitTest.java
diff --git a/apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java b/apache-libraries/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java
similarity index 100%
rename from apache-solrj/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java
rename to apache-libraries/src/test/java/com/baeldung/solrjava/SolrJavaLiveTest.java
diff --git a/apache-beam/src/test/resources/wordcount.txt b/apache-libraries/src/test/resources/wordcount.txt
similarity index 100%
rename from apache-beam/src/test/resources/wordcount.txt
rename to apache-libraries/src/test/resources/wordcount.txt
diff --git a/apache-meecrowave/README.md b/apache-meecrowave/README.md
deleted file mode 100644
index d360af13af..0000000000
--- a/apache-meecrowave/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Meecrowave
-
-This module contains articles about Apache Meecrowave
-
-### Relevant Articles:
-
-- [Building a Microservice with Apache Meecrowave](https://www.baeldung.com/apache-meecrowave)
\ No newline at end of file
diff --git a/apache-meecrowave/pom.xml b/apache-meecrowave/pom.xml
deleted file mode 100644
index e046599be3..0000000000
--- a/apache-meecrowave/pom.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
- 4.0.0
- apache-meecrowave
- 0.0.1
- apache-meecrowave
- A sample REST API application with Meecrowave
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
-
- org.apache.meecrowave
- meecrowave-core
- ${meecrowave-core.version}
-
-
-
- org.apache.meecrowave
- meecrowave-jpa
- ${meecrowave-jpa.version}
-
-
-
- com.squareup.okhttp3
- okhttp
- ${okhttp.version}
-
-
- org.apache.meecrowave
- meecrowave-junit
- ${meecrowave-junit.version}
- test
-
-
-
-
-
-
- org.apache.meecrowave
- meecrowave-maven-plugin
- ${meecrowave-maven-plugin.version}
-
-
-
-
-
- 1.8
- 1.8
- 1.2.0
- 3.10.0
- 1.2.1
- 1.2.1
- 1.2.1
-
-
-
\ No newline at end of file
diff --git a/apache-meecrowave/src/main/resources/logback.xml b/apache-meecrowave/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/apache-meecrowave/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apache-opennlp/README.md b/apache-opennlp/README.md
deleted file mode 100644
index 4b1fa36540..0000000000
--- a/apache-opennlp/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache OpenNLP
-
-This module contains articles about Apache OpenNLP
-
-### Relevant Articles
-
-- [Intro to Apache OpenNLP](https://www.baeldung.com/apache-open-nlp)
diff --git a/apache-opennlp/pom.xml b/apache-opennlp/pom.xml
deleted file mode 100644
index 07ce14b4fd..0000000000
--- a/apache-opennlp/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
- 4.0.0
- apache-opennlp
- 1.0-SNAPSHOT
- apache-opennlp
- jar
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.opennlp
- opennlp-tools
- ${org.apache.opennlp.opennlp-tools.version}
-
-
- org.assertj
- assertj-core
- ${org.assertj.version}
- test
-
-
-
-
- 3.9.0
- 1.8.4
-
-
-
\ No newline at end of file
diff --git a/apache-opennlp/src/main/resources/logback.xml b/apache-opennlp/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/apache-opennlp/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apache-pulsar/.gitignore b/apache-pulsar/.gitignore
deleted file mode 100755
index 1c53e03007..0000000000
--- a/apache-pulsar/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.classpath
-.project
-.settings
-target
-.idea
-*.iml
-.gradle/
-build/
diff --git a/apache-pulsar/README.md b/apache-pulsar/README.md
deleted file mode 100644
index c44849a490..0000000000
--- a/apache-pulsar/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Pulsar
-
-This module contains articles about Apache Pulsar
-
-### Relevant Articles:
-
-- [Introduction to Apache Pulsar](https://www.baeldung.com/apache-pulsar)
diff --git a/apache-pulsar/pom.xml b/apache-pulsar/pom.xml
deleted file mode 100644
index 568389f9f5..0000000000
--- a/apache-pulsar/pom.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
- 4.0.0
- com.baeldung.pulsar
- apache-pulsar
- 0.0.1
- apache-pulsar
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
- ..
-
-
-
-
- org.apache.pulsar
- pulsar-client
- ${pulsar-client.version}
- compile
-
-
-
-
- 2.1.1-incubating
-
-
-
diff --git a/apache-solrj/README.md b/apache-solrj/README.md
deleted file mode 100644
index 803db393e9..0000000000
--- a/apache-solrj/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Solrj
-
-This module contains articles about Apache Solrj
-
-### Relevant Articles:
-
-- [Guide to Solr in Java with Apache Solrj](https://www.baeldung.com/apache-solrj)
\ No newline at end of file
diff --git a/apache-solrj/pom.xml b/apache-solrj/pom.xml
deleted file mode 100644
index 165cd9571b..0000000000
--- a/apache-solrj/pom.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
- 4.0.0
- apache-solrj
- 0.0.1-SNAPSHOT
- apache-solrj
- jar
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.solr
- solr-solrj
- ${org.apache.solr.solr-solrj.version}
-
-
-
-
- 6.4.0
-
-
-
\ No newline at end of file
diff --git a/apache-solrj/src/main/resources/logback.xml b/apache-solrj/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/apache-solrj/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/apache-zookeeper/README.md b/apache-zookeeper/README.md
deleted file mode 100644
index cda1cd6d73..0000000000
--- a/apache-zookeeper/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-## Apache Zookeeper
-
-This module contains articles about Apache Zookeeper
-
-### Relevant articles:
-
-- [Getting Started with Java and Zookeeper](https://www.baeldung.com/java-zookeeper)
diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml
deleted file mode 100644
index f441848f70..0000000000
--- a/apache-zookeeper/pom.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
- 4.0.0
- apache-zookeeper
- 0.0.1-SNAPSHOT
- apache-zookeeper
- jar
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- org.apache.zookeeper
- zookeeper
- ${org.apache.zookeeper.version}
-
-
-
-
- 3.4.11
-
-
-
-
diff --git a/apache-zookeeper/src/main/resources/logback.xml b/apache-zookeeper/src/main/resources/logback.xml
deleted file mode 100644
index 7d900d8ea8..0000000000
--- a/apache-zookeeper/src/main/resources/logback.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/atomikos/pom.xml b/atomikos/pom.xml
index 881adae074..d680a3ca77 100644
--- a/atomikos/pom.xml
+++ b/atomikos/pom.xml
@@ -41,7 +41,7 @@
org.springframework.data
spring-data-jpa
- 1.11.23.RELEASE
+ ${spring-data-jpa.version}
org.springframework
@@ -64,49 +64,49 @@
org.apache.activemq
activemq-core
- 5.7.0
+ ${activemq-core.version}
org.apache.derby
derby
- 10.8.1.2
+ ${derby.version}
junit
junit
- 4.12
+ ${junit.version}
test
javax.transaction
jta
- 1.1
+ ${jta.version}
org.apache.geronimo.specs
geronimo-jta_1.0.1B_spec
- 1.0
+ ${geronimo.version}
javax.validation
validation-api
- 2.0.1.Final
+ ${validation-api.version}
org.hibernate.validator
hibernate-validator
- 6.1.2.Final
+ ${hibernate-validator.version}
javax.el
javax.el-api
- 3.0.0
+ ${javax.el-api.version}
org.glassfish.web
javax.el
- 2.2.4
+ ${javax.el.version}
@@ -114,6 +114,15 @@
5.0.6
5.1.6.RELEASE
5.4.3.Final
+ 1.11.23.RELEASE
+ 5.7.0
+ 10.8.1.2
+ 1.1
+ 1.0
+ 2.0.1.Final
+ 6.1.2.Final
+ 3.0.0
+ 2.2.4
\ No newline at end of file
diff --git a/core-groovy-2/determine-datatype/pom.xml b/core-groovy-2/determine-datatype/pom.xml
index 0bcef4e5d8..e03cb58ead 100644
--- a/core-groovy-2/determine-datatype/pom.xml
+++ b/core-groovy-2/determine-datatype/pom.xml
@@ -34,7 +34,11 @@
org.junit
junit5-engine
- 5.0.0-ALPHA
+ ${junit5.version}
+
+
+ 5.0.0-ALPHA
+
\ No newline at end of file
diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml
index 69833ff74d..82a68f0ff8 100644
--- a/core-groovy/pom.xml
+++ b/core-groovy/pom.xml
@@ -105,7 +105,7 @@
central
- http://jcenter.bintray.com
+ https://jcenter.bintray.com
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy b/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy
new file mode 100644
index 0000000000..f17b946b1a
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/scopes/Scopes.groovy
@@ -0,0 +1,26 @@
+package com.baeldung.scopes
+
+import java.util.logging.Logger
+
+x = 200
+logger = Logger.getLogger("Scopes.groovy")
+
+def getGlobalResult() {
+ logger.info(x.toString())
+ return 1 + x
+}
+
+def defineGlobalVariable() {
+ z = 234
+ logger = Logger.getLogger("Scopes.groovy")
+ logger.info(z.toString())
+}
+
+logger.info("- Global variable")
+logger.info(x.toString())
+logger.info("- Access global variable from inside function")
+logger.info(getGlobalResult().toString())
+logger.info("- function called to create variable")
+defineGlobalVariable()
+logger.info("- Variable created inside a function")
+logger.info(z.toString())
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy b/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy
new file mode 100644
index 0000000000..d32abfc7ea
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFail.groovy
@@ -0,0 +1,21 @@
+package com.baeldung.scopes
+
+import java.util.logging.Logger
+
+logger = Logger.getLogger("ScopesFail.groovy")
+
+y = 2
+
+def fLocal() {
+ def q = 333
+ println(q)
+ q
+}
+
+fLocal()
+
+logger.info("- Value of the created variable")
+logger.info(fLocal())
+logger.info("- Local variable doesn't exist outside")
+logger.info(q.toString())
+
diff --git a/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy b/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy
new file mode 100644
index 0000000000..3f1fdb45a2
--- /dev/null
+++ b/core-groovy/src/main/groovy/com/baeldung/scopes/ScopesFailNoPrint.groovy
@@ -0,0 +1,15 @@
+package com.baeldung.scopes
+
+import java.util.logging.Logger
+
+logger = Logger.getLogger("ScopesFailNoPrint.groovy")
+
+y = 2
+
+def fLocal() {
+ def q = 333
+ println(q)
+ q
+}
+
+logger.info(y.toString())
diff --git a/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/inputstream/outputstream/InputStreamToOutputStreamUnitTest.java b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/inputstream/outputstream/InputStreamToOutputStreamUnitTest.java
new file mode 100644
index 0000000000..814824e580
--- /dev/null
+++ b/core-java-modules/core-java-9/src/test/java/com/baeldung/java9/inputstream/outputstream/InputStreamToOutputStreamUnitTest.java
@@ -0,0 +1,87 @@
+package com.baeldung.java9.inputstream.outputstream;
+
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+import static org.junit.Assert.assertEquals;
+
+import java.io.*;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+
+import com.google.common.io.ByteStreams;
+
+public class InputStreamToOutputStreamUnitTest {
+
+ /**
+ * Reads all bytes from an input stream and writes them to an output stream.
+ * @param source - input stream to copy data from
+ * @param target - output stream to copy data too
+ */
+ void copy(InputStream source, OutputStream target) throws IOException {
+ byte[] buf = new byte[8192];
+ int length;
+ while ((length = source.read(buf)) > 0) {
+ target.write(buf, 0, length);
+ }
+ }
+
+ @Test
+ public void givenUsingJavaEight_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
+ String initialString = "Hello World!";
+
+ try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
+ ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
+ copy(inputStream, targetStream);
+
+ assertEquals(initialString, new String(targetStream.toByteArray()));
+ }
+ }
+
+ @Test
+ public void givenUsingJavaEight_whenCopyingLongInputStreamToOutputStream_thenCorrect() throws IOException {
+ String initialString = randomAlphabetic(20480);
+
+ try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
+ ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
+ copy(inputStream, targetStream);
+
+ assertEquals(initialString, new String(targetStream.toByteArray()));
+ }
+ }
+
+ @Test
+ public void givenUsingJavaNine_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
+ String initialString = "Hello World!";
+
+ try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
+ ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
+ inputStream.transferTo(targetStream);
+
+ assertEquals(initialString, new String(targetStream.toByteArray()));
+ }
+ }
+
+ @Test
+ public void givenUsingGuava_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
+ String initialString = "Hello World!";
+
+ try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
+ ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
+ ByteStreams.copy(inputStream, targetStream);
+
+ assertEquals(initialString, new String(targetStream.toByteArray()));
+ }
+ }
+
+ @Test
+ public void givenUsingCommonsIO_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
+ String initialString = "Hello World!";
+
+ try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
+ ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
+ IOUtils.copy(inputStream, targetStream);
+
+ assertEquals(initialString, new String(targetStream.toByteArray()));
+ }
+ }
+}
diff --git a/core-java-modules/core-java-concurrency-2/pom.xml b/core-java-modules/core-java-concurrency-2/pom.xml
index 75fd3890b3..253537bc2b 100644
--- a/core-java-modules/core-java-concurrency-2/pom.xml
+++ b/core-java-modules/core-java-concurrency-2/pom.xml
@@ -19,31 +19,31 @@
junit
junit
- 4.13
+ ${junit.version}
test
com.googlecode.thread-weaver
threadweaver
- 0.2
+ ${threadweaver.version}
test
com.google.code.tempus-fugit
tempus-fugit
- 1.1
+ ${tempus-fugit.version}
test
com.googlecode.multithreadedtc
multithreadedtc
- 1.01
+ ${multithreadedtc.version}
test
org.openjdk.jcstress
jcstress-core
- 0.5
+ ${jcstress-core.version}
@@ -63,8 +63,8 @@
3.1
${javac.target}
-
- ${javac.target}
+
+ ${java.version}
@@ -99,7 +99,11 @@
- 1.8
+ 4.13
+ 0.2
+ 1.1
+ 1.01
+ 0.5
diff --git a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockUnitTest.java b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockUnitTest.java
index 553b8c9906..427531a446 100644
--- a/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockUnitTest.java
+++ b/core-java-modules/core-java-concurrency-basic-2/src/test/java/com/baeldung/concurrent/synchronize/BaeldungSychronizedBlockUnitTest.java
@@ -34,4 +34,20 @@ public class BaeldungSychronizedBlockUnitTest {
assertEquals(1000, BaeldungSynchronizedBlocks.getStaticCount());
}
+ @Test
+ public void givenHoldingTheLock_whenReentrant_thenCanAcquireItAgain() {
+ Object lock = new Object();
+ synchronized (lock) {
+ System.out.println("First time acquiring it");
+
+ synchronized (lock) {
+ System.out.println("Entering again");
+
+ synchronized (lock) {
+ System.out.println("And again");
+ }
+ }
+ }
+ }
+
}
diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml
index bdc2ee37f5..c0aae2b1ce 100644
--- a/core-java-modules/core-java-io-2/pom.xml
+++ b/core-java-modules/core-java-io-2/pom.xml
@@ -50,7 +50,7 @@
com.github.tomakehurst
wiremock
- 2.26.3
+ ${wiremock.version}
test
@@ -80,6 +80,7 @@
3.6.1
3.0.0-M1
+ 2.26.3
\ No newline at end of file
diff --git a/core-java-modules/core-java-io-conversions-2/pom.xml b/core-java-modules/core-java-io-conversions-2/pom.xml
index 46bce7988b..e9cf3f55d1 100644
--- a/core-java-modules/core-java-io-conversions-2/pom.xml
+++ b/core-java-modules/core-java-io-conversions-2/pom.xml
@@ -24,7 +24,7 @@
org.json
json
- 20200518
+ ${json.version}
@@ -38,4 +38,8 @@
+
+ 20200518
+
+
\ No newline at end of file
diff --git a/core-java-modules/core-java-jvm/src/test/java/com/baeldung/arraylength/ArrayLengthUnitTest.java b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/arraylength/ArrayLengthUnitTest.java
new file mode 100644
index 0000000000..1b85ea7ebe
--- /dev/null
+++ b/core-java-modules/core-java-jvm/src/test/java/com/baeldung/arraylength/ArrayLengthUnitTest.java
@@ -0,0 +1,13 @@
+package com.baeldung.arraylength;
+
+import org.junit.Test;
+import org.openjdk.jol.info.ClassLayout;
+
+public class ArrayLengthUnitTest {
+
+ @Test
+ public void printingTheArrayLength() {
+ int[] ints = new int[42];
+ System.out.println(ClassLayout.parseInstance(ints).toPrintable());
+ }
+}
diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/IntegerProducer.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/IntegerProducer.java
new file mode 100644
index 0000000000..6a631d45b0
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/IntegerProducer.java
@@ -0,0 +1,8 @@
+package com.baeldung.covariance;
+
+public class IntegerProducer extends Producer {
+ @Override
+ public Integer produce(String input) {
+ return Integer.parseInt(input);
+ }
+}
diff --git a/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/Producer.java b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/Producer.java
new file mode 100644
index 0000000000..94f79ae525
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-methods/src/main/java/com/baeldung/covariance/Producer.java
@@ -0,0 +1,8 @@
+package com.baeldung.covariance;
+
+public class Producer {
+ public Object produce(String input) {
+ Object result = input.toLowerCase();
+ return result;
+ }
+}
diff --git a/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/covariance/CovariantProducersUnitTest.java b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/covariance/CovariantProducersUnitTest.java
new file mode 100644
index 0000000000..2645889ac8
--- /dev/null
+++ b/core-java-modules/core-java-lang-oop-methods/src/test/java/com/baeldung/covariance/CovariantProducersUnitTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.covariance;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class CovariantProducersUnitTest {
+
+ @Test
+ public void whenInputIsArbitrary_thenProducerProducesString() {
+ String arbitraryInput = "just a random text";
+ Producer producer = new Producer();
+
+ Object objectOutput = producer.produce(arbitraryInput);
+
+ assertEquals(arbitraryInput, objectOutput);
+ assertEquals(String.class, objectOutput.getClass());
+ }
+
+ @Test
+ public void whenInputIsArbitrary_thenIntegerProducerFails() {
+ String arbitraryInput = "just a random text";
+ Producer producer = new IntegerProducer();
+
+ assertThrows(NumberFormatException.class, () -> producer.produce(arbitraryInput));
+ }
+
+ @Test
+ public void whenInputIsSupported_thenProducerCreatesInteger() {
+ String integerAsString = "42";
+ Producer producer = new IntegerProducer();
+
+ Object result = producer.produce(integerAsString);
+
+ assertEquals(Integer.class, result.getClass());
+ assertEquals(Integer.parseInt(integerAsString), result);
+ }
+
+ @Test
+ public void whenInputIsSupported_thenIntegerProducerCreatesIntegerWithoutCasting() {
+ String integerAsString = "42";
+ IntegerProducer producer = new IntegerProducer();
+
+ Integer result = producer.produce(integerAsString);
+
+ assertEquals(Integer.parseInt(integerAsString), result);
+ }
+}
diff --git a/core-java-modules/core-java-regex/pom.xml b/core-java-modules/core-java-regex/pom.xml
index 9e2d91d5d9..f26218877c 100644
--- a/core-java-modules/core-java-regex/pom.xml
+++ b/core-java-modules/core-java-regex/pom.xml
@@ -29,7 +29,7 @@
org.assertj
assertj-core
- 3.15.0
+ ${assertj-core.version}
test
@@ -44,4 +44,8 @@
+
+ 3.15.0
+
+
diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml
index 85aa3869b3..890b4147ca 100644
--- a/core-java-modules/core-java-security-2/pom.xml
+++ b/core-java-modules/core-java-security-2/pom.xml
@@ -41,7 +41,7 @@
javax.xml.bind
jaxb-api
- 2.3.1
+ ${jaxb-api.version}
@@ -54,6 +54,7 @@
3.10.0
+ 2.3.1
diff --git a/core-java-modules/core-java-streams/README.md b/core-java-modules/core-java-streams/README.md
index e556c231fe..135e136fee 100644
--- a/core-java-modules/core-java-streams/README.md
+++ b/core-java-modules/core-java-streams/README.md
@@ -13,4 +13,5 @@ This module contains articles about the Stream API in Java.
- [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda)
- [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count)
- [Summing Numbers with Java Streams](https://www.baeldung.com/java-stream-sum)
-- More articles: [[next -->]](/../core-java-streams-2)
\ No newline at end of file
+- [How to Find all Getters Returning Null](https://www.baeldung.com/java-getters-returning-null)
+- More articles: [[next -->]](/../core-java-streams-2)
diff --git a/core-kotlin-modules/core-kotlin-collections/README.md b/core-kotlin-modules/core-kotlin-collections/README.md
index 997680c2bc..dcf2743577 100644
--- a/core-kotlin-modules/core-kotlin-collections/README.md
+++ b/core-kotlin-modules/core-kotlin-collections/README.md
@@ -11,3 +11,4 @@ This module contains articles about core Kotlin collections.
- [Collection Transformations in Kotlin](https://www.baeldung.com/kotlin-collection-transformations)
- [Difference between fold and reduce in Kotlin](https://www.baeldung.com/kotlin/fold-vs-reduce)
- [Guide to Sorting in Kotlin](https://www.baeldung.com/kotlin-sort)
+- [Working With Lists in Kotlin](https://www.baeldung.com/kotlin/lists)
diff --git a/core-kotlin-modules/core-kotlin/README.md b/core-kotlin-modules/core-kotlin/README.md
index 48d19c987a..359c5a4787 100644
--- a/core-kotlin-modules/core-kotlin/README.md
+++ b/core-kotlin-modules/core-kotlin/README.md
@@ -9,3 +9,4 @@ This module contains articles about Kotlin core features.
- [Create a Java and Kotlin Project with Maven](https://www.baeldung.com/kotlin-maven-java-project)
- [Kotlin Ternary Conditional Operator](https://www.baeldung.com/kotlin-ternary-operator)
- [Sequences in Kotlin](https://www.baeldung.com/kotlin/sequences)
+- [Converting Kotlin Data Class from JSON using GSON](https://www.baeldung.com/kotlin-json-convert-data-class)
diff --git a/image-processing/pom.xml b/image-processing/pom.xml
index 806cccf351..8fe161337c 100644
--- a/image-processing/pom.xml
+++ b/image-processing/pom.xml
@@ -38,7 +38,7 @@
org.openpnp
opencv
- 3.4.2-0
+ ${opencv.version}
com.twelvemonkeys.imageio
@@ -68,6 +68,7 @@
3.3.2
4.5.1
4.1.0-1.5.2
+ 3.4.2-0
\ No newline at end of file
diff --git a/intelliJ/intelliJ-formatter.xml b/intelliJ/intelliJ-formatter.xml
index 9b1d12a3be..6e4c927da8 100644
--- a/intelliJ/intelliJ-formatter.xml
+++ b/intelliJ/intelliJ-formatter.xml
@@ -30,12 +30,9 @@
-
-
-
+
-
-
+
diff --git a/jackson-modules/jackson-conversions-2/pom.xml b/jackson-modules/jackson-conversions-2/pom.xml
index 43c9d1478b..992cff30b2 100644
--- a/jackson-modules/jackson-conversions-2/pom.xml
+++ b/jackson-modules/jackson-conversions-2/pom.xml
@@ -23,7 +23,7 @@
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
- 2.9.8
+ ${jackson-datatype.version}
@@ -51,6 +51,7 @@
3.11.0
+ 2.9.8
diff --git a/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/date/EventWithLocalDate.java b/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/date/EventWithLocalDate.java
new file mode 100644
index 0000000000..c67943f418
--- /dev/null
+++ b/jackson-modules/jackson-conversions/src/main/java/com/baeldung/jackson/date/EventWithLocalDate.java
@@ -0,0 +1,33 @@
+package com.baeldung.jackson.date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+
+import java.time.LocalDate;
+
+public class EventWithLocalDate {
+ public String name;
+
+ @JsonDeserialize(using = LocalDateDeserializer.class)
+ @JsonSerialize(using = LocalDateSerializer.class)
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
+ public LocalDate eventDate;
+
+ public EventWithLocalDate() {}
+
+ public EventWithLocalDate(final String name, final LocalDate eventDate) {
+ this.name = name;
+ this.eventDate = eventDate;
+ }
+
+ public LocalDate getEventDate() {
+ return eventDate;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java
index 924ec1162f..047d53ab62 100644
--- a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java
+++ b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertThat;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
@@ -18,11 +19,6 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Test;
-import com.baeldung.jackson.date.Event;
-import com.baeldung.jackson.date.EventWithFormat;
-import com.baeldung.jackson.date.EventWithJodaTime;
-import com.baeldung.jackson.date.EventWithLocalDateTime;
-import com.baeldung.jackson.date.EventWithSerializer;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@@ -57,7 +53,7 @@ public class JacksonDateUnitTest {
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
-
+
// StdDateFormat is ISO8601 since jackson 2.9
mapper.setDateFormat(new StdDateFormat().withColonInTimeZone(true));
@@ -143,7 +139,7 @@ public class JacksonDateUnitTest {
}
@Test
- public void whenDeserializingDateWithJackson_thenCorrect() throws JsonProcessingException, IOException {
+ public void whenDeserializingDateWithJackson_thenCorrect() throws IOException {
final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";
final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
@@ -156,7 +152,7 @@ public class JacksonDateUnitTest {
}
@Test
- public void whenDeserializingDateUsingCustomDeserializer_thenCorrect() throws JsonProcessingException, IOException {
+ public void whenDeserializingDateUsingCustomDeserializer_thenCorrect() throws IOException {
final String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014 02:30:00\"}";
final SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
@@ -179,6 +175,28 @@ public class JacksonDateUnitTest {
assertThat(result, containsString("2014-12-20T02:30"));
}
+ @Test
+ public void whenSerializingJava8DateAndReadingValue_thenCorrect() throws IOException {
+ String stringDate = "\"2014-12-20\"";
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.registerModule(new JavaTimeModule());
+ mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+ LocalDate result = mapper.readValue(stringDate, LocalDate.class);
+ assertThat(result.toString(), containsString("2014-12-20"));
+ }
+
+ @Test
+ public void whenSerializingJava8DateAndReadingFromEntity_thenCorrect() throws IOException {
+ String json = "{\"name\":\"party\",\"eventDate\":\"20-12-2014\"}";
+
+ ObjectMapper mapper = new ObjectMapper();
+
+ EventWithLocalDate result = mapper.readValue(json, EventWithLocalDate.class);
+ assertThat(result.getEventDate().toString(), containsString("2014-12-20"));
+ }
+
@Test
public void whenSerializingJodaTime_thenCorrect() throws JsonProcessingException {
final DateTime date = new DateTime(2014, 12, 20, 2, 30, DateTimeZone.forID("Europe/London"));
diff --git a/java-numbers-3/src/main/java/com/baeldung/formatNumber/FormatNumber.java b/java-numbers-3/src/main/java/com/baeldung/formatNumber/FormatNumber.java
new file mode 100644
index 0000000000..1fdcdd4247
--- /dev/null
+++ b/java-numbers-3/src/main/java/com/baeldung/formatNumber/FormatNumber.java
@@ -0,0 +1,73 @@
+package com.baeldung.formatNumber;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+public class FormatNumber {
+ public static double withBigDecimal(double value, int places) {
+ if (places < 0)
+ throw new IllegalArgumentException();
+
+ BigDecimal bigDecimal = new BigDecimal(value);
+ bigDecimal = bigDecimal.setScale(places, RoundingMode.HALF_UP);
+ return bigDecimal.doubleValue();
+ }
+
+ public static double withMathRound(double value, int places) {
+ double scale = Math.pow(10, places);
+ return Math.round(value * scale) / scale;
+ }
+
+ public static double withDecimalFormatPattern(double value, int places) {
+ DecimalFormat df2 = new DecimalFormat("#,###,###,##0.00");
+ DecimalFormat df3 = new DecimalFormat("#,###,###,##0.000");
+ if (places == 2)
+ return new Double(df2.format(value));
+ else if (places == 3)
+ return new Double(df3.format(value));
+ else
+ throw new IllegalArgumentException();
+ }
+
+ public static double withDecimalFormatLocal(double value) {
+ DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.getDefault());
+ return new Double(df.format(value));
+ }
+
+ public static String withStringFormat(double value, int places) {
+ return String.format("%." + places + "f", value);
+ }
+
+ public static String byPaddingZeros(int value, int paddingLength) {
+ return String.format("%0" + paddingLength + "d", value);
+ }
+
+ public static double withTwoDecimalPlaces(double value) {
+ DecimalFormat df = new DecimalFormat("#.00");
+ return new Double(df.format(value));
+ }
+
+ public static String withLargeIntegers(double value) {
+ DecimalFormat df = new DecimalFormat("###,###,###");
+ return df.format(value);
+ }
+
+ public static String forPercentages(double value, Locale localisation) {
+ NumberFormat nf = NumberFormat.getPercentInstance(localisation);
+ return nf.format(value);
+ }
+
+ public static String currencyWithChosenLocalisation(double value, Locale localisation) {
+ NumberFormat nf = NumberFormat.getCurrencyInstance(localisation);
+ return nf.format(value);
+ }
+
+ public static String currencyWithDefaultLocalisation(double value) {
+ NumberFormat nf = NumberFormat.getCurrencyInstance();
+ return nf.format(value);
+ }
+}
+
diff --git a/java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java b/java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java
new file mode 100644
index 0000000000..4f0358c6a2
--- /dev/null
+++ b/java-numbers-3/src/test/java/com/baeldung/formatNumber/FormatNumberUnitTest.java
@@ -0,0 +1,82 @@
+package com.baeldung.formatNumber;
+
+import org.junit.Test;
+
+import java.util.Locale;
+
+import static com.baeldung.formatNumber.FormatNumber.*;
+import static org.assertj.core.api.Assertions.*;
+
+public class FormatNumberUnitTest {
+ private static final double D = 4.2352989244d;
+ private static final double F = 8.6994540927d;
+
+ @Test
+ public void givenDecimalNumber_whenFormatNumberWithBigDecimal_thenGetExpectedResult() {
+ assertThat(withBigDecimal(D, 2)).isEqualTo(4.24);
+ assertThat(withBigDecimal(D, 3)).isEqualTo(4.235);
+ assertThat(withBigDecimal(F, 2)).isEqualTo(8.7);
+ assertThat(withBigDecimal(F, 3)).isEqualTo(8.699);
+ }
+
+ @Test
+ public void givenDecimalNumber_whenFormatNumberWithDecimalFormat_thenGetExpectedResult() {
+ assertThat(withDecimalFormatLocal(D)).isEqualTo(4.235);
+ assertThat(withDecimalFormatLocal(F)).isEqualTo(8.699);
+
+ assertThat(withDecimalFormatPattern(D, 2)).isEqualTo(4.24);
+ assertThat(withDecimalFormatPattern(D, 3)).isEqualTo(4.235);
+ assertThat(withDecimalFormatPattern(F, 2)).isEqualTo(8.7);
+ assertThat(withDecimalFormatPattern(F, 3)).isEqualTo(8.699);
+ }
+
+ @Test
+ public void givenDecimalNumber_whenFormatNumberWithStringFormat_thenGetExpectedResult() {
+ assertThat(withStringFormat(D, 2)).isEqualTo("4.24");
+ assertThat(withStringFormat(D, 3)).isEqualTo("4.235");
+ assertThat(withStringFormat(F, 2)).isEqualTo("8.70");
+ assertThat(withStringFormat(F, 3)).isEqualTo("8.699");
+ }
+
+ @Test
+ public void givenDecimalNumber_whenFormatNumberWithMathRound_thenGetExpectedResult() {
+ assertThat(withMathRound(D, 2)).isEqualTo(4.24);
+ assertThat(withMathRound(D, 3)).isEqualTo(4.235);
+ assertThat(withMathRound(F, 2)).isEqualTo(8.7);
+ assertThat(withMathRound(F, 3)).isEqualTo(8.699);
+ }
+
+ @Test
+ public void givenIntegerNumber_whenFormatNumberByPaddingOutZeros_thenGetExpectedResult() {
+ int value = 1;
+ assertThat(byPaddingZeros(value, 3)).isEqualTo("001");
+ }
+
+ @Test
+ public void givenIntegerNumber_whenFormatNumberWithTwoDecimalPlaces_thenGetExpectedResult() {
+ int value = 12;
+ assertThat(withTwoDecimalPlaces(value)).isEqualTo(12.00);
+ }
+
+ @Test
+ public void givenIntegerNumber_whenFormatNumberWithLargeIntegers_thenGetExpectedResult() {
+ int value = 123456789;
+ assertThat(withLargeIntegers(value)).isEqualTo("123,456,789");
+ }
+
+ @Test
+ public void givenDecimalNumber_whenFormatNumberForPercentages_thenGetExpectedResult() {
+ double value = 25f / 100f;
+ assertThat(forPercentages(value, new Locale("en", "US"))).isEqualTo("25%");
+ assertThat(forPercentages(value, new Locale("pl", "PL"))).isEqualTo("25%");
+ }
+
+ @Test
+ public void givenCurrency_whenFormatNumberCurrencyWithChosenLocalisation_thenGetExpectedResult() {
+ double value = 23_500;
+ assertThat(currencyWithChosenLocalisation(value, new Locale("en", "US"))).isEqualTo("$23,500.00");
+ assertThat(currencyWithChosenLocalisation(value, new Locale("zh", "CN"))).isEqualTo("¥23,500.00");
+ assertThat(currencyWithChosenLocalisation(value, new Locale("pl", "PL"))).isEqualTo("23 500 zł");
+ }
+
+}
diff --git a/json-2/pom.xml b/json-2/pom.xml
index e0295af59b..d674d6f86d 100644
--- a/json-2/pom.xml
+++ b/json-2/pom.xml
@@ -47,12 +47,13 @@
org.apache.commons
commons-lang3
- 3.9
+ ${commons-lang3.version}
0.9.23
3.11.1
1.9.2
+ 3.9
diff --git a/kotlin-libraries/pom.xml b/kotlin-libraries/pom.xml
index 0d6e589377..908a545ae3 100644
--- a/kotlin-libraries/pom.xml
+++ b/kotlin-libraries/pom.xml
@@ -151,7 +151,6 @@
- 4.12
1.5.0
4.1.0
3.0.4
diff --git a/kotlin-quasar/pom.xml b/kotlin-quasar/pom.xml
index ec37fa8059..59553f422e 100644
--- a/kotlin-quasar/pom.xml
+++ b/kotlin-quasar/pom.xml
@@ -148,7 +148,6 @@
3.1.1
2.22.1
1.3.2
- 4.12
diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml
index 5334bfba70..2f6e9fa747 100644
--- a/libraries-3/pom.xml
+++ b/libraries-3/pom.xml
@@ -73,19 +73,19 @@
com.uber.nullaway
nullaway
- 0.3.0
+ ${nullaway.version}
org.codehaus.plexus
plexus-compiler-javac-errorprone
- 2.8
+ ${plexus-compiler.version}
com.google.errorprone
error_prone_core
- 2.1.3
+ ${errorprone.version}
@@ -230,5 +230,8 @@
4.5.12
2.2
1.6.0
+ 0.3.0
+ 2.8
+ 2.1.3
diff --git a/libraries-4/pom.xml b/libraries-4/pom.xml
index f26e7fc055..d7f6a44985 100644
--- a/libraries-4/pom.xml
+++ b/libraries-4/pom.xml
@@ -91,7 +91,7 @@
org.glassfish.web
javax.el
- 2.2.4
+ ${glassfish.web.version}
@@ -111,6 +111,7 @@
3.0.0
0.6.5
3.0.0
+ 2.2.4
\ No newline at end of file
diff --git a/libraries-concurrency/pom.xml b/libraries-concurrency/pom.xml
index e1307408b0..b7dc5187b1 100644
--- a/libraries-concurrency/pom.xml
+++ b/libraries-concurrency/pom.xml
@@ -16,17 +16,17 @@
co.paralleluniverse
quasar-core
- 0.8.0
+ ${quasar.version}
co.paralleluniverse
quasar-actors
- 0.8.0
+ ${quasar.version}
co.paralleluniverse
quasar-reactive-streams
- 0.8.0
+ ${quasar.version}
@@ -78,4 +78,8 @@
+
+
+ 0.8.0
+
\ No newline at end of file
diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml
index ac23747caa..be776282e9 100644
--- a/libraries-data-2/pom.xml
+++ b/libraries-data-2/pom.xml
@@ -222,5 +222,4 @@
-
\ No newline at end of file
diff --git a/micronaut/pom.xml b/micronaut/pom.xml
index 2cb05cc1b9..d6df6a0347 100644
--- a/micronaut/pom.xml
+++ b/micronaut/pom.xml
@@ -144,7 +144,6 @@
1.8
1.3.2
1.2.3
- 4.12
3.1.6.RELEASE
3.7.0
1.6.0
diff --git a/netflix-modules/README.md b/netflix-modules/README.md
index 7f7a9656fb..c126bbdf5b 100644
--- a/netflix-modules/README.md
+++ b/netflix-modules/README.md
@@ -2,6 +2,3 @@
This module contains articles about Netflix.
-### Relevant articles
-
-- [Introduction to Netflix Genie](https://www.baeldung.com/netflix-genie-intro)
diff --git a/netflix-modules/genie/README.md b/netflix-modules/genie/README.md
new file mode 100644
index 0000000000..f6e15ba403
--- /dev/null
+++ b/netflix-modules/genie/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Introduction to Netflix Genie](https://www.baeldung.com/netflix-genie-intro)
diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml
index c7bb11b1d5..ab5424bfaf 100644
--- a/parent-boot-2/pom.xml
+++ b/parent-boot-2/pom.xml
@@ -82,6 +82,7 @@
1.0.22.RELEASE
2.2.6.RELEASE
+ 1.9.1
diff --git a/parent-java/pom.xml b/parent-java/pom.xml
index baad9fecf4..f56ffbd7f7 100644
--- a/parent-java/pom.xml
+++ b/parent-java/pom.xml
@@ -46,7 +46,6 @@
2.6
1.19
2.3.7
- 4.12
2.2
diff --git a/parent-spring-5/pom.xml b/parent-spring-5/pom.xml
index c75655ebc8..949e40b021 100644
--- a/parent-spring-5/pom.xml
+++ b/parent-spring-5/pom.xml
@@ -33,6 +33,7 @@
5.2.5.RELEASE
5.2.3.RELEASE
+ 1.5.10.RELEASE
\ No newline at end of file
diff --git a/patterns/cqrs-es/pom.xml b/patterns/cqrs-es/pom.xml
index 3c54038837..67665a2d32 100644
--- a/patterns/cqrs-es/pom.xml
+++ b/patterns/cqrs-es/pom.xml
@@ -13,17 +13,19 @@
1.8
1.8
+ 4.13
+ 1.18.12
org.projectlombok
lombok
- 1.18.12
+ ${lombok.version}
junit
junit
- 4.13
+ ${junit.version}
test
diff --git a/pdf/pom.xml b/pdf/pom.xml
index 463c88948d..7d7754ee73 100644
--- a/pdf/pom.xml
+++ b/pdf/pom.xml
@@ -63,12 +63,12 @@
org.thymeleaf
thymeleaf
- 3.0.11.RELEASE
+ ${thymeleaf.version}
org.xhtmlrenderer
flying-saucer-pdf
- 9.1.20
+ ${flying-saucer-pdf.version}
@@ -90,6 +90,8 @@
3.15
1.8
3.15
+ 3.0.11.RELEASE
+ 9.1.20
diff --git a/persistence-modules/apache-bookkeeper/data/.gitignore b/persistence-modules/apache-bookkeeper/data/.gitignore
new file mode 100644
index 0000000000..43a3e42263
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/data/.gitignore
@@ -0,0 +1,5 @@
+bk/bookkeeper/*
+bk1/bookkeeper/*
+bk2/bookkeeper/*
+zk/*
+
diff --git a/persistence-modules/apache-bookkeeper/data/bk1/.gitignore b/persistence-modules/apache-bookkeeper/data/bk1/.gitignore
new file mode 100644
index 0000000000..32c9297ccd
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/data/bk1/.gitignore
@@ -0,0 +1 @@
+/bookkeeper/
diff --git a/persistence-modules/apache-bookkeeper/data/bk2/.gitignore b/persistence-modules/apache-bookkeeper/data/bk2/.gitignore
new file mode 100644
index 0000000000..32c9297ccd
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/data/bk2/.gitignore
@@ -0,0 +1 @@
+/bookkeeper/
diff --git a/persistence-modules/apache-bookkeeper/docker-compose.yml b/persistence-modules/apache-bookkeeper/docker-compose.yml
new file mode 100644
index 0000000000..0ef4c41a4a
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/docker-compose.yml
@@ -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
+
+
+
+
diff --git a/persistence-modules/apache-bookkeeper/pom.xml b/persistence-modules/apache-bookkeeper/pom.xml
new file mode 100644
index 0000000000..0beea7f1fc
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+ 4.0.0
+ apache-bookkeeper
+ 0.0.1-SNAPSHOT
+ apache-bookkeeper
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+ ../../
+
+
+
+
+ org.apache.bookkeeper
+ bookkeeper-server
+ ${org.apache.bookkeeper.version}
+
+
+ org.slf4j
+ slf4j-log4j12
+
+
+
+
+
+ org.testcontainers
+ testcontainers
+ 1.14.3
+ test
+
+
+
+
+
+ 4.10.0
+
+
+
+
+
diff --git a/persistence-modules/apache-bookkeeper/src/main/java/com/baeldung/tutorials/bookkeeper/BkHelper.java b/persistence-modules/apache-bookkeeper/src/main/java/com/baeldung/tutorials/bookkeeper/BkHelper.java
new file mode 100644
index 0000000000..55f5d7b09f
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/src/main/java/com/baeldung/tutorials/bookkeeper/BkHelper.java
@@ -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 findLedgerByName(BookKeeper bk, String name) throws Exception {
+ Map ledgers = new HashMap();
+ 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 = ledgers.entrySet()
+ .stream()
+ .filter((e) -> {
+ Map 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 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 listAllLedgers(BookKeeper bk) {
+ final List 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);
+ }
+ }
+}
diff --git a/persistence-modules/apache-bookkeeper/src/test/java/com/baeldung/tutorials/bookkeeper/BkHelperLiveTest.java b/persistence-modules/apache-bookkeeper/src/test/java/com/baeldung/tutorials/bookkeeper/BkHelperLiveTest.java
new file mode 100644
index 0000000000..84a8ce3db8
--- /dev/null
+++ b/persistence-modules/apache-bookkeeper/src/test/java/com/baeldung/tutorials/bookkeeper/BkHelperLiveTest.java
@@ -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 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 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 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