diff --git a/apache-curator/pom.xml b/apache-curator/pom.xml
new file mode 100644
index 0000000000..36c3949b1a
--- /dev/null
+++ b/apache-curator/pom.xml
@@ -0,0 +1,68 @@
+
+ 4.0.0
+ apache-curator
+ 0.0.1-SNAPSHOT
+ jar
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ 4.0.1
+ 3.4.11
+ 2.9.4
+
+
+ 3.6.1
+
+
+
+
+
+
+
+
+ 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-databind.version}
+
+
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+
diff --git a/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java b/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
new file mode 100644
index 0000000000..bab7133742
--- /dev/null
+++ b/apache-curator/src/main/java/com/baeldung/apache/curator/modeled/HostConfig.java
@@ -0,0 +1,31 @@
+package com.baeldung.apache.curator.modeled;
+
+public class HostConfig {
+ private String hostname;
+ private int port;
+
+ public HostConfig() {
+
+ }
+
+ public HostConfig(String hostname, int port) {
+ this.hostname = hostname;
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getHostname() {
+ return hostname;
+ }
+
+ public void setHostname(String hostname) {
+ this.hostname = hostname;
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/BaseTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseTest.java
new file mode 100644
index 0000000000..cfac3ee3f2
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/BaseTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.apache.curator;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryNTimes;
+import org.junit.Before;
+
+public abstract class BaseTest {
+
+ @Before
+ public void setup() {
+ org.apache.log4j.BasicConfigurator.configure();
+ }
+
+ protected CuratorFramework newClient() {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries, sleepMsBetweenRetries);
+ return CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy);
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
new file mode 100644
index 0000000000..0475f9c237
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/configuration/ConfigurationManagementManualTest.java
@@ -0,0 +1,98 @@
+package com.baeldung.apache.curator.configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseTest;
+
+public class ConfigurationManagementManualTest extends BaseTest {
+
+ private static final String KEY_FORMAT = "/%s";
+
+ @Test
+ public void givenPath_whenCreateKey_thenValueIsStored() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ String key = getKey();
+ String expected = "my_value";
+
+ // Create key nodes structure
+ client
+ .create()
+ .forPath(key);
+
+ // Set data value for our key
+ async
+ .setData()
+ .forPath(key, expected.getBytes());
+
+ // Get data value
+ AtomicBoolean isEquals = new AtomicBoolean();
+ async
+ .getData()
+ .forPath(key)
+ .thenAccept(data -> isEquals.set(new String(data).equals(expected)));
+
+ Thread.sleep(1000);
+
+ assertThat(isEquals.get()).isTrue();
+ }
+ }
+
+ @Test
+ public void givenPath_whenWatchAKeyAndStoreAValue_thenWatcherIsTriggered() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ String key = getKey();
+ String expected = "my_value";
+
+ // Create key structure
+ async
+ .create()
+ .forPath(key);
+
+ List changes = new ArrayList<>();
+
+ // Watch data value
+ async
+ .watched()
+ .getData()
+ .forPath(key)
+ .event()
+ .thenAccept(watchedEvent -> {
+ try {
+ changes.add(new String(client
+ .getData()
+ .forPath(watchedEvent.getPath())));
+ } catch (Exception e) {
+ // fail ...
+ }
+ });
+
+ // Set data value for our key
+ async
+ .setData()
+ .forPath(key, expected.getBytes());
+
+ Thread.sleep(1000);
+
+ assertThat(changes.size() > 0).isTrue();
+ }
+ }
+
+ private String getKey() {
+ return String.format(KEY_FORMAT, UUID
+ .randomUUID()
+ .toString());
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
new file mode 100644
index 0000000000..931a977900
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/connection/ConnectionManagementManualTest.java
@@ -0,0 +1,69 @@
+package com.baeldung.apache.curator.connection;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.curator.RetryPolicy;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.RetryNTimes;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.junit.Test;
+
+public class ConnectionManagementManualTest {
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnection_thenClientIsOpened() throws Exception {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries, sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+ assertThat(client
+ .checkExists()
+ .forPath("/")).isNotNull();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnectionUsingAsyncNotBlocking_thenClientIsOpened() throws InterruptedException {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries, sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+
+ AtomicBoolean exists = new AtomicBoolean(false);
+ async
+ .checkExists()
+ .forPath("/")
+ .thenAcceptAsync(s -> exists.set(s != null));
+ Thread.sleep(100);
+ assertThat(exists.get()).isTrue();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenOpenConnectionUsingAsyncBlocking_thenClientIsOpened() throws InterruptedException {
+ int sleepMsBetweenRetries = 100;
+ int maxRetries = 3;
+ RetryPolicy retryPolicy = new RetryNTimes(maxRetries, sleepMsBetweenRetries);
+
+ try (CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", retryPolicy)) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+
+ AtomicBoolean exists = new AtomicBoolean(false);
+ async
+ .checkExists()
+ .forPath("/")
+ .thenAccept(s -> exists.set(s != null));
+ Thread.sleep(100);
+ assertThat(exists.get()).isTrue();
+ }
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
new file mode 100644
index 0000000000..9d00c0a4c2
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/modeled/ModelTypedExamplesManualTest.java
@@ -0,0 +1,47 @@
+package com.baeldung.apache.curator.modeled;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.x.async.AsyncCuratorFramework;
+import org.apache.curator.x.async.modeled.JacksonModelSerializer;
+import org.apache.curator.x.async.modeled.ModelSpec;
+import org.apache.curator.x.async.modeled.ModeledFramework;
+import org.apache.curator.x.async.modeled.ZPath;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseTest;
+
+public class ModelTypedExamplesManualTest extends BaseTest {
+
+ @Test
+ public void givenPath_whenStoreAModel_thenNodesAreCreated() throws InterruptedException {
+
+ ModelSpec mySpec = ModelSpec
+ .builder(ZPath.parseWithIds("/config/dev"), JacksonModelSerializer.build(HostConfig.class))
+ .build();
+
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ AsyncCuratorFramework async = AsyncCuratorFramework.wrap(client);
+ ModeledFramework modeledClient = ModeledFramework.wrap(async, mySpec);
+
+ modeledClient.set(new HostConfig("host-name", 8080));
+
+ modeledClient
+ .read()
+ .whenComplete((value, e) -> {
+ if (e != null) {
+ fail("Cannot read host config", e);
+ } else {
+ assertThat(value).isNotNull();
+ assertThat(value.getHostname()).isEqualTo("host-name");
+ assertThat(value.getPort()).isEqualTo(8080);
+ }
+
+ });
+ }
+
+ }
+}
diff --git a/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java b/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
new file mode 100644
index 0000000000..04f4104e6b
--- /dev/null
+++ b/apache-curator/src/test/java/com/baeldung/apache/curator/recipes/RecipesManualTest.java
@@ -0,0 +1,74 @@
+package com.baeldung.apache.curator.recipes;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.recipes.leader.LeaderSelector;
+import org.apache.curator.framework.recipes.leader.LeaderSelectorListener;
+import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
+import org.apache.curator.framework.recipes.shared.SharedCount;
+import org.apache.curator.framework.state.ConnectionState;
+import org.junit.Test;
+
+import com.baeldung.apache.curator.BaseTest;
+
+public class RecipesManualTest extends BaseTest {
+
+ @Test
+ public void givenRunningZookeeper_whenUsingLeaderElection_thenNoErrors() {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ LeaderSelector leaderSelector = new LeaderSelector(client, "/mutex/select/leader/for/job/A", new LeaderSelectorListener() {
+
+ @Override
+ public void stateChanged(CuratorFramework client, ConnectionState newState) {
+
+ }
+
+ @Override
+ public void takeLeadership(CuratorFramework client) throws Exception {
+ // I'm the leader of the job A !
+ }
+
+ });
+
+ leaderSelector.start();
+
+ // Wait until the job A is done among all the members
+
+ leaderSelector.close();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenUsingSharedLock_thenNoErrors() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+ InterProcessSemaphoreMutex sharedLock = new InterProcessSemaphoreMutex(client, "/mutex/process/A");
+
+ sharedLock.acquire();
+
+ // Do process A
+
+ sharedLock.release();
+ }
+ }
+
+ @Test
+ public void givenRunningZookeeper_whenUsingSharedCounter_thenCounterIsIncrement() throws Exception {
+ try (CuratorFramework client = newClient()) {
+ client.start();
+
+ try (SharedCount counter = new SharedCount(client, "/counters/A", 0)) {
+ counter.start();
+
+ counter.setCount(0);
+ counter.setCount(counter.getCount() + 1);
+
+ assertThat(counter.getCount()).isEqualTo(1);
+ }
+
+ }
+ }
+
+}
diff --git a/apache-zookeeper/pom.xml b/apache-zookeeper/pom.xml
index 6d49d74ade..3a6fc1787b 100644
--- a/apache-zookeeper/pom.xml
+++ b/apache-zookeeper/pom.xml
@@ -6,6 +6,12 @@
0.0.1-SNAPSHOT
jar
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
org.apache.zookeeper
diff --git a/aws/src/main/java/com/baeldung/ec2/EC2Application.java b/aws/src/main/java/com/baeldung/ec2/EC2Application.java
index bb7d8ca1d7..6755188fcd 100644
--- a/aws/src/main/java/com/baeldung/ec2/EC2Application.java
+++ b/aws/src/main/java/com/baeldung/ec2/EC2Application.java
@@ -38,21 +38,19 @@ public class EC2Application {
}
public static void main(String[] args) {
-
- String yourInstanceId = "";
-
- // 0) - Set up the client
+
+ // Set up the client
AmazonEC2 ec2Client = AmazonEC2ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_1)
.build();
- // 1) - Create a security group
+ // Create a security group
CreateSecurityGroupRequest createSecurityGroupRequest = new CreateSecurityGroupRequest().withGroupName("BaeldungSecurityGroup")
.withDescription("Baeldung Security Group");
ec2Client.createSecurityGroup(createSecurityGroupRequest);
- // 2) - Allow HTTP and SSH traffic
+ // Allow HTTP and SSH traffic
IpRange ipRange1 = new IpRange().withCidrIp("0.0.0.0/0");
IpPermission ipPermission1 = new IpPermission().withIpv4Ranges(Arrays.asList(new IpRange[] { ipRange1 }))
@@ -71,7 +69,7 @@ public class EC2Application {
ec2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
- // 3) - Create KeyPair
+ // Create KeyPair
CreateKeyPairRequest createKeyPairRequest = new CreateKeyPairRequest()
.withKeyName("baeldung-key-pair");
CreateKeyPairResult createKeyPairResult = ec2Client.createKeyPair(createKeyPairRequest);
@@ -79,11 +77,11 @@ public class EC2Application {
.getKeyPair()
.getKeyMaterial(); // make sure you keep it, the private key, Amazon doesn't store the private key
- // 4) - See what key-pairs you've got
+ // See what key-pairs you've got
DescribeKeyPairsRequest describeKeyPairsRequest = new DescribeKeyPairsRequest();
DescribeKeyPairsResult describeKeyPairsResult = ec2Client.describeKeyPairs(describeKeyPairsRequest);
- // 5) - Launch an Amazon Instance
+ // Launch an Amazon Instance
RunInstancesRequest runInstancesRequest = new RunInstancesRequest().withImageId("ami-97785bed") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html | https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/usingsharedamis-finding.html
.withInstanceType("t2.micro") // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html
.withMinCount(1)
@@ -91,9 +89,15 @@ public class EC2Application {
.withKeyName("baeldung-key-pair") // optional - if not present, can't connect to instance
.withSecurityGroups("BaeldungSecurityGroup");
- ec2Client.runInstances(runInstancesRequest);
+ String yourInstanceId = ec2Client.runInstances(runInstancesRequest).getReservation().getInstances().get(0).getInstanceId();
- // 6) Monitor Instances
+ // Start an Instance
+ StartInstancesRequest startInstancesRequest = new StartInstancesRequest()
+ .withInstanceIds(yourInstanceId);
+
+ ec2Client.startInstances(startInstancesRequest);
+
+ // Monitor Instances
MonitorInstancesRequest monitorInstancesRequest = new MonitorInstancesRequest()
.withInstanceIds(yourInstanceId);
@@ -104,14 +108,14 @@ public class EC2Application {
ec2Client.unmonitorInstances(unmonitorInstancesRequest);
- // 7) - Reboot an Instance
+ // Reboot an Instance
RebootInstancesRequest rebootInstancesRequest = new RebootInstancesRequest()
.withInstanceIds(yourInstanceId);
ec2Client.rebootInstances(rebootInstancesRequest);
- // 8) - Stop an Instance
+ // Stop an Instance
StopInstancesRequest stopInstancesRequest = new StopInstancesRequest()
.withInstanceIds(yourInstanceId);
@@ -121,13 +125,7 @@ public class EC2Application {
.getPreviousState()
.getName();
- // 9) - Start an Instance
- StartInstancesRequest startInstancesRequest = new StartInstancesRequest()
- .withInstanceIds("instance-id");
-
- ec2Client.startInstances(startInstancesRequest);
-
- // 10) - Describe an Instance
+ // Describe an Instance
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest();
DescribeInstancesResult response = ec2Client.describeInstances(describeInstancesRequest);
System.out.println(response.getReservations()
diff --git a/core-groovy/build.gradle b/core-groovy/build.gradle
index b3f33836da..300827ee7c 100644
--- a/core-groovy/build.gradle
+++ b/core-groovy/build.gradle
@@ -8,6 +8,6 @@ repositories {
}
dependencies {
- compile 'org.codehaus.groovy:groovy-all:2.5.0-alpha-1'
+ compile 'org.codehaus.groovy:groovy-all:2.4.13'
testCompile 'org.spockframework:spock-core:1.1-groovy-2.4'
}
diff --git a/core-groovy/pom.xml b/core-groovy/pom.xml
index 961a4ba125..91cbe66e35 100644
--- a/core-groovy/pom.xml
+++ b/core-groovy/pom.xml
@@ -23,17 +23,17 @@
org.codehaus.groovy
groovy
- 2.5.0-alpha-1
+ 2.4.13
org.codehaus.groovy
groovy-all
- 2.5.0-alpha-1
+ 2.4.13
org.codehaus.groovy
groovy-sql
- 2.5.0-alpha-1
+ 2.4.13
org.junit.jupiter
diff --git a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
index 0d7c451972..6cda7c6fbd 100644
--- a/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
+++ b/core-groovy/src/main/groovy/com/baeldung/json/JsonParser.groovy
@@ -1,6 +1,5 @@
package com.baeldung.json
-import groovy.json.JsonGenerator
import groovy.json.JsonOutput
import groovy.json.JsonParserType
import groovy.json.JsonSlurper
@@ -21,14 +20,6 @@ class JsonParser {
JsonOutput.toJson(account)
}
- String toJson(Account account, String dateFormat, String... fieldsToExclude) {
- JsonGenerator generator = new JsonGenerator.Options()
- .dateFormat(dateFormat)
- .excludeFieldsByName(fieldsToExclude)
- .build()
- generator.toJson(account)
- }
-
String prettyfy(String json) {
JsonOutput.prettyPrint(json)
}
diff --git a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
index fcd51d58bc..c3842340a5 100644
--- a/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
+++ b/core-groovy/src/test/groovy/com/baeldung/json/JsonParserTest.groovy
@@ -52,20 +52,6 @@ class JsonParserTest extends Specification {
json == '{"value":15.6,"createdAt":"2018-01-01T00:00:00+0000","id":"123"}'
}
- def 'Should parse to Json given an Account object, a date format and fields to exclude' () {
- given:
- Account account = new Account(
- id: '123',
- value: 15.6,
- createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
- )
- when:
- def json = jsonParser.toJson(account, 'MM/dd/yyyy', 'value')
- then:
- json
- json == '{"createdAt":"01/01/2018","id":"123"}'
- }
-
def 'Should prettify given a json string' () {
given:
String json = '{"value":15.6,"createdAt":"01/01/2018","id":"123456"}'
diff --git a/jersey/pom.xml b/jersey/pom.xml
new file mode 100644
index 0000000000..0c8b6b9281
--- /dev/null
+++ b/jersey/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ jersey
+ 0.0.1-SNAPSHOT
+ war
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ 2.26
+ 1.7.25
+ 3.2.0
+
+
+
+ jersey
+
+
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+
+
+
+
+
+
+
+ org.glassfish.jersey.core
+ jersey-server
+ ${jersey.version}
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+
+
+ org.glassfish.jersey.bundles
+ jaxrs-ri
+ ${jersey.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+
+
+
+
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java
new file mode 100644
index 0000000000..88ad891411
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java
@@ -0,0 +1,45 @@
+package com.baeldung.jersey.client;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+
+import com.baeldung.jersey.client.filter.RequestClientFilter;
+import com.baeldung.jersey.client.filter.ResponseClientFilter;
+import com.baeldung.jersey.client.interceptor.RequestClientWriterInterceptor;
+
+public class JerseyClient {
+
+ private static final String URI_GREETINGS = "http://localhost:8080/jersey/greetings";
+
+ public static String getHelloGreeting() {
+ return createClient().target(URI_GREETINGS)
+ .request()
+ .get(String.class);
+ }
+
+ public static String getHiGreeting() {
+ return createClient().target(URI_GREETINGS + "/hi")
+ .request()
+ .get(String.class);
+ }
+
+ public static Response getCustomGreeting() {
+ return createClient().target(URI_GREETINGS + "/custom")
+ .request()
+ .post(Entity.text("custom"));
+ }
+
+ private static Client createClient() {
+ ClientConfig config = new ClientConfig();
+ config.register(RequestClientFilter.class);
+ config.register(ResponseClientFilter.class);
+ config.register(RequestClientWriterInterceptor.class);
+
+ return ClientBuilder.newClient(config);
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java b/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java
new file mode 100644
index 0000000000..8c6ac2c5fb
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java
@@ -0,0 +1,24 @@
+package com.baeldung.jersey.client.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestClientFilter implements ClientRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestClientFilter.class);
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ LOG.info("Request client filter");
+
+ requestContext.setProperty("test", "test client request filter");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java b/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java
new file mode 100644
index 0000000000..1676fa2094
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java
@@ -0,0 +1,26 @@
+package com.baeldung.jersey.client.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class ResponseClientFilter implements ClientResponseFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResponseClientFilter.class);
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ LOG.info("Response client filter");
+
+ responseContext.getHeaders()
+ .add("X-Test-Client", "Test response client filter");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java b/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java
new file mode 100644
index 0000000000..7216cf18cc
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java
@@ -0,0 +1,28 @@
+package com.baeldung.jersey.client.interceptor;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.ws.rs.ext.WriterInterceptorContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestClientWriterInterceptor implements WriterInterceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestClientWriterInterceptor.class);
+
+ @Override
+ public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
+ LOG.info("request writer interceptor in the client side");
+
+ context.getOutputStream()
+ .write(("Message added in the writer interceptor in the client side").getBytes());
+
+ context.proceed();
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java b/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
new file mode 100644
index 0000000000..d0ea873db1
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
@@ -0,0 +1,32 @@
+package com.baeldung.jersey.server;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import com.baeldung.jersey.server.config.HelloBinding;
+
+@Path("/greetings")
+public class Greetings {
+
+ @GET
+ @HelloBinding
+ public String getHelloGreeting() {
+ return "hello";
+ }
+
+ @GET
+ @Path("/hi")
+ public String getHiGreeting() {
+ return "hi";
+ }
+
+ @POST
+ @Path("/custom")
+ public Response getCustomGreeting(String name) {
+ return Response.status(Status.OK.getStatusCode())
+ .build();
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java
new file mode 100644
index 0000000000..49b11adeab
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java
@@ -0,0 +1,11 @@
+package com.baeldung.jersey.server.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.ws.rs.NameBinding;
+
+@NameBinding
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HelloBinding {
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java
new file mode 100644
index 0000000000..e56cdec140
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java
@@ -0,0 +1,31 @@
+package com.baeldung.jersey.server.config;
+
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.baeldung.jersey.server.Greetings;
+import com.baeldung.jersey.server.filter.ResponseServerFilter;
+
+@Provider
+public class HelloDynamicBinding implements DynamicFeature {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HelloDynamicBinding.class);
+
+ @Override
+ public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+ LOG.info("Hello dynamic binding");
+
+ if (Greetings.class.equals(resourceInfo.getResourceClass()) && resourceInfo.getResourceMethod()
+ .getName()
+ .contains("HiGreeting")) {
+ context.register(ResponseServerFilter.class);
+ }
+
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java b/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java
new file mode 100644
index 0000000000..4670cc291c
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java
@@ -0,0 +1,14 @@
+package com.baeldung.jersey.server.config;
+
+import javax.ws.rs.ApplicationPath;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+@ApplicationPath("/*")
+public class ServerConfig extends ResourceConfig {
+
+ public ServerConfig() {
+ packages("com.baeldung.jersey.server");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java
new file mode 100644
index 0000000000..181fa7f043
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java
@@ -0,0 +1,27 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+@PreMatching
+public class PrematchingRequestFilter implements ContainerRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PrematchingRequestFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext ctx) throws IOException {
+ LOG.info("prematching filter");
+ if (ctx.getMethod()
+ .equals("DELETE")) {
+ LOG.info("\"Deleting request");
+ }
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java
new file mode 100644
index 0000000000..de0dcbdce7
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java
@@ -0,0 +1,23 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResponseServerFilter implements ContainerResponseFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResponseServerFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ LOG.info("Response server filter");
+
+ responseContext.getHeaders()
+ .add("X-Test", "Filter test");
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java
new file mode 100644
index 0000000000..cb0cd185f7
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java
@@ -0,0 +1,36 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.baeldung.jersey.server.config.HelloBinding;
+
+@Provider
+@Priority(Priorities.AUTHORIZATION)
+@HelloBinding
+public class RestrictedOperationsRequestFilter implements ContainerRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RestrictedOperationsRequestFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext ctx) throws IOException {
+ LOG.info("Restricted operations filter");
+ if (ctx.getLanguage() != null && "EN".equals(ctx.getLanguage()
+ .getLanguage())) {
+ LOG.info("Aborting request");
+ ctx.abortWith(Response.status(Response.Status.FORBIDDEN)
+ .entity("Cannot access")
+ .build());
+ }
+
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java b/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java
new file mode 100644
index 0000000000..e9cc57fc2a
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java
@@ -0,0 +1,36 @@
+package com.baeldung.jersey.server.interceptor;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.ReaderInterceptorContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestServerReaderInterceptor implements ReaderInterceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestServerReaderInterceptor.class);
+
+ @Override
+ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
+ LOG.info("Request reader interceptor in the server side");
+
+ InputStream is = context.getInputStream();
+ String body = new BufferedReader(new InputStreamReader(is)).lines()
+ .collect(Collectors.joining("\n"));
+
+ context.setInputStream(new ByteArrayInputStream((body + " message added in server reader interceptor").getBytes()));
+
+ return context.proceed();
+ }
+
+}
diff --git a/jersey/src/main/resources/logback.xml b/jersey/src/main/resources/logback.xml
new file mode 100644
index 0000000000..d87a87bf53
--- /dev/null
+++ b/jersey/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java b/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java
new file mode 100644
index 0000000000..72ba4cc5b9
--- /dev/null
+++ b/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.jersey.client;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+@Ignore
+public class JerseyClientTest {
+
+ private static int HTTP_OK = 200;
+
+ @Test
+ public void givenGreetingResource_whenCallingHelloGreeting_thenHelloReturned() {
+ String response = JerseyClient.getHelloGreeting();
+
+ Assert.assertEquals("hello", response);
+ }
+
+ @Test
+ public void givenGreetingResource_whenCallingHiGreeting_thenHiReturned() {
+ String response = JerseyClient.getHiGreeting();
+
+ Assert.assertEquals("hi", response);
+ }
+
+ @Test
+ public void givenGreetingResource_whenCallingCustomGreeting_thenCustomGreetingReturned() {
+ Response response = JerseyClient.getCustomGreeting();
+
+ Assert.assertEquals(HTTP_OK, response.getStatus());
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 0c72a82d2f..463f060240 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,8 @@
apache-fop
apache-poi
apache-thrift
+ apache-curator
+ apache-zookeeper
autovalue
axon
bootique
@@ -278,8 +280,9 @@
lucene
vraptor
persistence-modules/java-cockroachdb
+ jersey
java-spi
-
+
@@ -382,4 +385,4 @@
-
+
\ No newline at end of file
diff --git a/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestNumberUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestNumberUnitTest.java
new file mode 100644
index 0000000000..21606afd79
--- /dev/null
+++ b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestNumberUnitTest.java
@@ -0,0 +1,152 @@
+package org.baeldung.hamcrest;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.*;
+import static org.hamcrest.Matchers.closeTo;
+
+public class HamcrestNumberUnitTest {
+
+ @Test
+ public void givenADouble_whenCloseTo_thenCorrect() {
+ double actual = 1.3;
+ double operand = 1;
+ double error = 0.5;
+ assertThat(actual, is(closeTo(operand, error)));
+ }
+
+ @Test
+ public void givenADouble_whenNotCloseTo_thenCorrect() {
+ double actual = 1.6;
+ double operand = 1;
+ double error = 0.5;
+ assertThat(actual, is(not(closeTo(operand, error))));
+ }
+
+ @Test
+ public void givenABigDecimal_whenCloseTo_thenCorrect() {
+ BigDecimal actual = new BigDecimal("1.0003");
+ BigDecimal operand = new BigDecimal("1");
+ BigDecimal error = new BigDecimal("0.0005");
+ assertThat(actual, is(closeTo(operand, error)));
+ }
+
+ @Test
+ public void givenABigDecimal_whenNotCloseTo_thenCorrect() {
+ BigDecimal actual = new BigDecimal("1.0006");
+ BigDecimal operand = new BigDecimal("1");
+ BigDecimal error = new BigDecimal("0.0005");
+ assertThat(actual, is(not(closeTo(operand, error))));
+ }
+
+ @Test
+ public void given7_whenGreaterThan5_thenCorrect() {
+ Integer seven = 7;
+ Integer five = 5;
+ assertThat(seven, is(greaterThan(five)));
+ }
+
+ @Test
+ public void given7_whenGreaterThanOrEqualTo5_thenCorrect() {
+ Integer seven = 7;
+ Integer five = 5;
+ assertThat(seven, is(greaterThanOrEqualTo(five)));
+ }
+
+ @Test
+ public void given5_whenGreaterThanOrEqualTo5_thenCorrect() {
+ Integer five = 5;
+ assertThat(five, is(greaterThanOrEqualTo(five)));
+ }
+
+ @Test
+ public void given3_whenLessThan5_thenCorrect() {
+ Integer three = 3;
+ Integer five = 5;
+ assertThat(three, is(lessThan(five)));
+ }
+
+ @Test
+ public void given3_whenLessThanOrEqualTo5_thenCorrect() {
+ Integer three = 3;
+ Integer five = 5;
+ assertThat(three, is(lessThanOrEqualTo(five)));
+ }
+
+ @Test
+ public void given5_whenLessThanOrEqualTo5_thenCorrect() {
+ Integer five = 5;
+ assertThat(five, is(lessThanOrEqualTo(five)));
+ }
+
+ @Test
+ public void givenBenjamin_whenGreaterThanAmanda_thenCorrect() {
+ String amanda = "Amanda";
+ String benjamin = "Benjamin";
+ assertThat(benjamin, is(greaterThan(amanda)));
+ }
+
+ @Test
+ public void givenAmanda_whenLessThanBenajmin_thenCorrect() {
+ String amanda = "Amanda";
+ String benjamin = "Benjamin";
+ assertThat(amanda, is(lessThan(benjamin)));
+ }
+
+ @Test
+ public void givenToday_whenGreaterThanYesterday_thenCorrect() {
+ LocalDate today = LocalDate.now();
+ LocalDate yesterday = today.minusDays(1);
+ assertThat(today, is(greaterThan(yesterday)));
+ }
+
+ @Test
+ public void givenToday_whenLessThanTomorrow_thenCorrect() {
+ LocalDate today = LocalDate.now();
+ LocalDate tomorrow = today.plusDays(1);
+ assertThat(today, is(lessThan(tomorrow)));
+ }
+
+ @Test
+ public void givenAmanda_whenOlderThanBenjamin_thenCorrect() {
+ Person amanda = new Person("Amanda", 20);
+ Person benjamin = new Person("Benjamin", 18);
+ assertThat(amanda, is(greaterThan(benjamin)));
+ }
+
+ @Test
+ public void givenBenjamin_whenYoungerThanAmanda_thenCorrect() {
+ Person amanda = new Person("Amanda", 20);
+ Person benjamin = new Person("Benjamin", 18);
+ assertThat(benjamin, is(lessThan(amanda)));
+ }
+
+ class Person implements Comparable {
+ String name;
+ int age;
+
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ @Override
+ public int compareTo(Person o) {
+ if (this.age == o.getAge()) return 0;
+ if (this.age > o.age) return 1;
+ else return -1;
+ }
+ }
+}