commit
f7522a1bb9
|
@ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
||||||
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
||||||
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
||||||
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
||||||
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
|
|
||||||
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
||||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
### Relevant Articles:
|
|
||||||
|
|
||||||
- [Intro to OData with Olingo](https://www.baeldung.com/olingo)
|
|
|
@ -1,146 +0,0 @@
|
||||||
CAS Overlay Template [![Build Status](https://travis-ci.org/apereo/cas-overlay-template.svg?branch=master)](https://travis-ci.org/apereo/cas-overlay-template)
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Generic CAS WAR overlay to exercise the latest versions of CAS. This overlay could be freely used as a starting template for local CAS war overlays.
|
|
||||||
|
|
||||||
# Versions
|
|
||||||
|
|
||||||
- CAS `6.1.x`
|
|
||||||
- JDK `11`
|
|
||||||
|
|
||||||
# Overview
|
|
||||||
|
|
||||||
To build the project, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Use --refresh-dependencies to force-update SNAPSHOT versions
|
|
||||||
./gradlew[.bat] clean build
|
|
||||||
```
|
|
||||||
|
|
||||||
To see what commands are available to the build script, run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] tasks
|
|
||||||
```
|
|
||||||
|
|
||||||
To launch into the CAS command-line shell:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] downloadShell runShell
|
|
||||||
```
|
|
||||||
|
|
||||||
To fetch and overlay a CAS resource or view, use:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] getResource -PresourceName=[resource-name]
|
|
||||||
```
|
|
||||||
|
|
||||||
To list all available CAS views and templates:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] listTemplateViews
|
|
||||||
```
|
|
||||||
|
|
||||||
To unzip and explode the CAS web application file and the internal resources jar:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] explodeWar
|
|
||||||
```
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
|
|
||||||
- The `etc` directory contains the configuration files and directories that need to be copied to `/etc/cas/config`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] copyCasConfiguration
|
|
||||||
```
|
|
||||||
|
|
||||||
- The specifics of the build are controlled using the `gradle.properties` file.
|
|
||||||
|
|
||||||
## Adding Modules
|
|
||||||
|
|
||||||
CAS modules may be specified under the `dependencies` block of the [Gradle build script](build.gradle):
|
|
||||||
|
|
||||||
```gradle
|
|
||||||
dependencies {
|
|
||||||
compile "org.apereo.cas:cas-server-some-module:${project.casVersion}"
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To collect the list of all project modules and dependencies:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] allDependencies
|
|
||||||
```
|
|
||||||
|
|
||||||
### Clear Gradle Cache
|
|
||||||
|
|
||||||
If you need to, on Linux/Unix systems, you can delete all the existing artifacts (artifacts and metadata) Gradle has downloaded using:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Only do this when absolutely necessary
|
|
||||||
rm -rf $HOME/.gradle/caches/
|
|
||||||
```
|
|
||||||
|
|
||||||
Same strategy applies to Windows too, provided you switch `$HOME` to its equivalent in the above command.
|
|
||||||
|
|
||||||
# Deployment
|
|
||||||
|
|
||||||
- Create a keystore file `thekeystore` under `/etc/cas`. Use the password `changeit` for both the keystore and the key/certificate entries. This can either be done using the JDK's `keytool` utility or via the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] createKeystore
|
|
||||||
```
|
|
||||||
|
|
||||||
- Ensure the keystore is loaded up with keys and certificates of the server.
|
|
||||||
|
|
||||||
On a successful deployment via the following methods, CAS will be available at:
|
|
||||||
|
|
||||||
* `https://cas.server.name:8443/cas`
|
|
||||||
|
|
||||||
## Executable WAR
|
|
||||||
|
|
||||||
Run the CAS web application as an executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] run
|
|
||||||
```
|
|
||||||
|
|
||||||
Debug the CAS web application as an executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the CAS web application as a *standalone* executable WAR:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew[.bat] clean executable
|
|
||||||
```
|
|
||||||
|
|
||||||
## External
|
|
||||||
|
|
||||||
Deploy the binary web application file `cas.war` after a successful build to a servlet container of choice.
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
The following strategies outline how to build and deploy CAS Docker images.
|
|
||||||
|
|
||||||
### Jib
|
|
||||||
|
|
||||||
The overlay embraces the [Jib Gradle Plugin](https://github.com/GoogleContainerTools/jib) to provide easy-to-use out-of-the-box tooling for building CAS docker images. Jib is an open-source Java containerizer from Google that lets Java developers build containers using the tools they know. It is a container image builder that handles all the steps of packaging your application into a container image. It does not require you to write a Dockerfile or have Docker installed, and it is directly integrated into the overlay.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./gradlew build jibDockerBuild
|
|
||||||
```
|
|
||||||
|
|
||||||
### Dockerfile
|
|
||||||
|
|
||||||
You can also use the native Docker tooling and the provided `Dockerfile` to build and run CAS.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
chmod +x *.sh
|
|
||||||
./docker-build.sh
|
|
||||||
./docker-run.sh
|
|
||||||
```
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.baeldung.java14.helpfulnullpointerexceptions;
|
||||||
|
|
||||||
|
public class HelpfulNullPointerException {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Employee employee = null;
|
||||||
|
employee.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmployeeEmailAddress(Employee employee) {
|
||||||
|
String emailAddress = employee.getPersonalDetails().getEmailAddress().toLowerCase();
|
||||||
|
return emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Employee {
|
||||||
|
String name;
|
||||||
|
PersonalDetails personalDetails;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonalDetails getPersonalDetails() {
|
||||||
|
return personalDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonalDetails(PersonalDetails personalDetails) {
|
||||||
|
this.personalDetails = personalDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class PersonalDetails {
|
||||||
|
String emailAddress;
|
||||||
|
String phone;
|
||||||
|
|
||||||
|
public String getEmailAddress() {
|
||||||
|
return emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailAddress(String emailAddress) {
|
||||||
|
this.emailAddress = emailAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.java14.helpfulnullpointerexceptions;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.Employee;
|
||||||
|
import static com.baeldung.java14.helpfulnullpointerexceptions.HelpfulNullPointerException.PersonalDetails;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class HelpfulNullPointerExceptionUnitTest {
|
||||||
|
|
||||||
|
@Test (expected = NullPointerException.class)
|
||||||
|
public void givenAnEmptyPersonalDetails_whenEmailAddressIsAccessed_thenThrowNPE() {
|
||||||
|
var helpfulNPE = new HelpfulNullPointerException();
|
||||||
|
|
||||||
|
var employee = new Employee();
|
||||||
|
employee.setName("Eduard");
|
||||||
|
employee.setPersonalDetails(new PersonalDetails());
|
||||||
|
helpfulNPE.getEmployeeEmailAddress(employee);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCompletePersonalDetails_whenEmailAddressIsAccessed_thenSuccess() {
|
||||||
|
var helpfulNPE = new HelpfulNullPointerException();
|
||||||
|
var emailAddress = "eduard@gmx.com";
|
||||||
|
|
||||||
|
var employee = new Employee();
|
||||||
|
employee.setName("Eduard");
|
||||||
|
|
||||||
|
var personalDetails = new PersonalDetails();
|
||||||
|
personalDetails.setEmailAddress(emailAddress.toUpperCase());
|
||||||
|
personalDetails.setPhone("1234");
|
||||||
|
employee.setPersonalDetails(personalDetails);
|
||||||
|
|
||||||
|
assertThat(helpfulNPE.getEmployeeEmailAddress(employee)).isEqualTo(emailAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ This module contains articles about Java 8 core features
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)
|
|
||||||
- [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments)
|
- [Run a Java Application from the Command Line](https://www.baeldung.com/java-run-jar-with-arguments)
|
||||||
- [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit)
|
- [Java 8 Stream skip() vs limit()](https://www.baeldung.com/java-stream-skip-vs-limit)
|
||||||
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
- [Guide to Java BiFunction Interface](https://www.baeldung.com/java-bifunction-interface)
|
||||||
|
|
|
@ -12,4 +12,3 @@
|
||||||
- [Sorting in Java](https://www.baeldung.com/java-sorting)
|
- [Sorting in Java](https://www.baeldung.com/java-sorting)
|
||||||
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
- [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size)
|
||||||
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
- [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections)
|
||||||
- [Operating on and Removing an Item from Stream](https://www.baeldung.com/java-use-remove-item-stream)
|
|
||||||
|
|
|
@ -13,5 +13,4 @@ This module contains articles about Map data structures in Java.
|
||||||
- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort)
|
- [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort)
|
||||||
- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max)
|
- [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max)
|
||||||
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
|
||||||
- [Java TreeMap vs HashMap](https://www.baeldung.com/java-treemap-vs-hashmap)
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps) [[next -->]](/core-java-modules/core-java-collections-maps-3)
|
||||||
- More articles: [[<-- prev>]](/../java-collections-maps)
|
|
|
@ -3,16 +3,16 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>java-collections-maps-2</artifactId>
|
<artifactId>core-java-collections-maps-2</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>java-collections-maps-2</name>
|
<name>core-java-collections-maps-2</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>parent-java</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../parent-java</relativePath>
|
<relativePath>../../parent-java</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
|
@ -0,0 +1,8 @@
|
||||||
|
## Java Collections Cookbooks and Examples
|
||||||
|
|
||||||
|
This module contains articles about Map data structures in Java.
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Java TreeMap vs HashMap](https://www.baeldung.com/java-treemap-vs-hashmap)
|
||||||
|
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
||||||
|
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2)
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>core-java-collections-maps-3</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>core-java-collections-maps-3</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-java</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -10,8 +10,7 @@ This module contains articles about Map data structures in Java.
|
||||||
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
- [How to Store Duplicate Keys in a Map in Java?](https://www.baeldung.com/java-map-duplicate-keys)
|
||||||
- [Get the Key for a Value from a Java Map](https://www.baeldung.com/java-map-key-from-value)
|
- [Get the Key for a Value from a Java Map](https://www.baeldung.com/java-map-key-from-value)
|
||||||
- [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists)
|
- [How to Check If a Key Exists in a Map](https://www.baeldung.com/java-map-key-exists)
|
||||||
- [Comparing Two HashMaps in Java](https://www.baeldung.com/java-compare-hashmaps)
|
|
||||||
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
|
- [Immutable Map Implementations in Java](https://www.baeldung.com/java-immutable-maps)
|
||||||
- [Guide to Apache Commons MultiValuedMap](https://www.baeldung.com/apache-commons-multi-valued-map)
|
- [Guide to Apache Commons MultiValuedMap](https://www.baeldung.com/apache-commons-multi-valued-map)
|
||||||
- [The Java HashMap Under the Hood](https://www.baeldung.com/java-hashmap-advanced)
|
- [The Java HashMap Under the Hood](https://www.baeldung.com/java-hashmap-advanced)
|
||||||
- More articles: [[next -->]](/../java-collections-maps-2)
|
- More articles: [[next -->]](/core-java-modules/core-java-collections-maps-2)
|
|
@ -2,16 +2,16 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>java-collections-maps</artifactId>
|
<artifactId>core-java-collections-maps</artifactId>
|
||||||
<version>0.1.0-SNAPSHOT</version>
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
<name>java-collections-maps</name>
|
<name>core-java-collections-maps</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-java</artifactId>
|
<artifactId>parent-java</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../parent-java</relativePath>
|
<relativePath>../../parent-java</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
|
@ -3,7 +3,6 @@
|
||||||
This module contains articles about Java collections
|
This module contains articles about Java collections
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Collect a Java Stream to an Immutable Collection](https://www.baeldung.com/java-stream-immutable-collection)
|
|
||||||
- [Introduction to the Java ArrayDeque](https://www.baeldung.com/java-array-deque)
|
- [Introduction to the Java ArrayDeque](https://www.baeldung.com/java-array-deque)
|
||||||
- [An Introduction to Java.util.Hashtable Class](https://www.baeldung.com/java-hash-table)
|
- [An Introduction to Java.util.Hashtable Class](https://www.baeldung.com/java-hash-table)
|
||||||
- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
|
- [Thread Safe LIFO Data Structure Implementations](https://www.baeldung.com/java-lifo-thread-safe)
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.concurrent.volatilekeyword;
|
||||||
|
|
||||||
|
public class TaskRunner {
|
||||||
|
|
||||||
|
private static int number;
|
||||||
|
private volatile static boolean ready;
|
||||||
|
|
||||||
|
private static class Reader extends Thread {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!ready) {
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new Reader().start();
|
||||||
|
number = 42;
|
||||||
|
ready = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Introduction to Lock Striping](https://www.baeldung.com/java-lock-stripping)
|
|
@ -12,4 +12,5 @@ This module contains articles about core Java input and output (IO)
|
||||||
- [Java – Append Data to a File](https://www.baeldung.com/java-append-to-file)
|
- [Java – Append Data to a File](https://www.baeldung.com/java-append-to-file)
|
||||||
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
|
- [How to Copy a File with Java](https://www.baeldung.com/java-copy-file)
|
||||||
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
- [Create a Directory in Java](https://www.baeldung.com/java-create-directory)
|
||||||
|
- [Java IO vs NIO](https://www.baeldung.com/java-io-vs-nio)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-io)
|
- [[<-- Prev]](/core-java-modules/core-java-io)
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package com.baeldung.comparelong;
|
package com.baeldung.comparelong;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class CompareLongUnitTest {
|
public class CompareLongUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -32,6 +36,33 @@ public class CompareLongUnitTest {
|
||||||
assertThat(l1.equals(l2)).isTrue();
|
assertThat(l1.equals(l2)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLongValuesLessThan128_whenUsingObjectsEquals_thenSuccess() {
|
||||||
|
|
||||||
|
Long l1 = 127L;
|
||||||
|
Long l2 = 127L;
|
||||||
|
|
||||||
|
assertThat(Objects.equals(l1, l2)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLongValuesGreaterOrEqualsThan128_whenUsingObjectsEquals_thenSuccess() {
|
||||||
|
|
||||||
|
Long l1 = 128L;
|
||||||
|
Long l2 = 128L;
|
||||||
|
|
||||||
|
assertThat(Objects.equals(l1, l2)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenNullReference_whenUsingObjectsEquals_thenNoException() {
|
||||||
|
|
||||||
|
Long l1 = null;
|
||||||
|
Long l2 = 128L;
|
||||||
|
|
||||||
|
assertThatCode(() -> Objects.equals(l1, l2)).doesNotThrowAnyException();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenLongValuesGreaterOrEqualsThan128_whenUsingComparisonOperator_andLongValue_thenSuccess() {
|
public void givenLongValuesGreaterOrEqualsThan128_whenUsingComparisonOperator_andLongValue_thenSuccess() {
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
## Core Java Security
|
||||||
|
|
||||||
|
This module contains articles about core Java Security
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Guide To The Java Authentication And Authorization Service (JAAS)](https://www.baeldung.com/java-authentication-authorization-service)
|
- [Guide To The Java Authentication And Authorization Service (JAAS)](https://www.baeldung.com/java-authentication-authorization-service)
|
||||||
|
- [MD5 Hashing in Java](http://www.baeldung.com/java-md5)
|
||||||
|
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
||||||
|
- [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
||||||
|
- More articles: [[<-- prev]](/core-java-modules/core-java-security)
|
||||||
|
|
|
@ -16,4 +16,45 @@
|
||||||
<relativePath>../../parent-java</relativePath>
|
<relativePath>../../parent-java</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-codec</groupId>
|
||||||
|
<artifactId>commons-codec</artifactId>
|
||||||
|
<version>${commons-codec.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
<version>${bouncycastle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${assertj-core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
<version>2.3.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- util -->
|
||||||
|
<bouncycastle.version>1.60</bouncycastle.version>
|
||||||
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
|
|
||||||
|
<!-- testing -->
|
||||||
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.baeldung.checksums;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.zip.CRC32;
|
||||||
|
import java.util.zip.CheckedInputStream;
|
||||||
|
import java.util.zip.Checksum;
|
||||||
|
|
||||||
|
public class ChecksumUtils {
|
||||||
|
|
||||||
|
public static long getChecksumCRC32(byte[] bytes) {
|
||||||
|
Checksum crc32 = new CRC32();
|
||||||
|
crc32.update(bytes, 0, bytes.length);
|
||||||
|
return crc32.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getChecksumCRC32(InputStream stream, int bufferSize) throws IOException {
|
||||||
|
CheckedInputStream checkedInputStream = new CheckedInputStream(stream, new CRC32());
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
while (checkedInputStream.read(buffer, 0, buffer.length) >= 0) {}
|
||||||
|
return checkedInputStream.getChecksum().getValue();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.checksums;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class ChecksumUtilsUnitTest {
|
||||||
|
|
||||||
|
byte[] arr;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
void setUp() {
|
||||||
|
arr = new byte[]{0,10,21,20,35,40,120,56,72,22};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenByteArray_whenChecksumCreated_checkCorrect() {
|
||||||
|
|
||||||
|
long checksum = ChecksumUtils.getChecksumCRC32(arr);
|
||||||
|
|
||||||
|
assertEquals(3915397664L, checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenTwoDifferentStrings_whenChecksumCreated_checkCollision() {
|
||||||
|
|
||||||
|
String plumless = "plumless";
|
||||||
|
String buckeroo = "buckeroo";
|
||||||
|
|
||||||
|
long plumlessChecksum = ChecksumUtils.getChecksumCRC32(plumless.getBytes());
|
||||||
|
long buckerooChecksum = ChecksumUtils.getChecksumCRC32(buckeroo.getBytes());
|
||||||
|
|
||||||
|
assertEquals(plumlessChecksum, buckerooChecksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenInputString_whenChecksumCreated_checkCorrect() throws IOException {
|
||||||
|
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(arr);
|
||||||
|
long checksum = ChecksumUtils.getChecksumCRC32(inputStream, 10);
|
||||||
|
|
||||||
|
assertEquals(3915397664L, checksum);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,17 +3,16 @@
|
||||||
This module contains articles about core Java Security
|
This module contains articles about core Java Security
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [MD5 Hashing in Java](http://www.baeldung.com/java-md5)
|
|
||||||
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
|
- [Guide to the Cipher Class](http://www.baeldung.com/java-cipher-class)
|
||||||
- [Introduction to SSL in Java](http://www.baeldung.com/java-ssl)
|
- [Introduction to SSL in Java](http://www.baeldung.com/java-ssl)
|
||||||
- [Java KeyStore API](http://www.baeldung.com/java-keystore)
|
- [Java KeyStore API](http://www.baeldung.com/java-keystore)
|
||||||
- [Encrypting and Decrypting Files in Java](http://www.baeldung.com/java-cipher-input-output-stream)
|
- [Encrypting and Decrypting Files in Java](http://www.baeldung.com/java-cipher-input-output-stream)
|
||||||
- [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing)
|
|
||||||
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
|
- [SSL Handshake Failures](https://www.baeldung.com/java-ssl-handshake-failures)
|
||||||
- [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java)
|
|
||||||
- [Enabling TLS v1.2 in Java 7](https://www.baeldung.com/java-7-tls-v12)
|
- [Enabling TLS v1.2 in Java 7](https://www.baeldung.com/java-7-tls-v12)
|
||||||
- [The Java SecureRandom Class](https://www.baeldung.com/java-secure-random)
|
- [The Java SecureRandom Class](https://www.baeldung.com/java-secure-random)
|
||||||
- [An Introduction to Java SASL](https://www.baeldung.com/java-sasl)
|
- [An Introduction to Java SASL](https://www.baeldung.com/java-sasl)
|
||||||
- [A Guide to Java GSS API](https://www.baeldung.com/java-gss)
|
- [A Guide to Java GSS API](https://www.baeldung.com/java-gss)
|
||||||
- [Intro to the Java SecurityManager](https://www.baeldung.com/java-security-manager)
|
- [Intro to the Java SecurityManager](https://www.baeldung.com/java-security-manager)
|
||||||
|
- More articles: [[next -->]](/core-java-modules/core-java-security-2)
|
||||||
|
|
||||||
|
|
|
@ -24,24 +24,9 @@
|
||||||
<version>${assertj-core.version}</version>
|
<version>${assertj-core.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-codec</groupId>
|
|
||||||
<artifactId>commons-codec</artifactId>
|
|
||||||
<version>${commons-codec.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
|
||||||
<version>${bouncycastle.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- util -->
|
|
||||||
<bouncycastle.version>1.60</bouncycastle.version>
|
|
||||||
<commons-codec.version>1.11</commons-codec.version>
|
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<assertj-core.version>3.10.0</assertj-core.version>
|
<assertj-core.version>3.10.0</assertj-core.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.streams.bigdecimals;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AddNumbersUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenIntStream_whenSum_thenResultIsCorrect() {
|
||||||
|
IntStream intNumbers = IntStream.range(0, 3);
|
||||||
|
assertEquals(3, intNumbers.sum());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCollectionOfDouble_whenUsingMapToDoubleToSum_thenResultIsCorrect() {
|
||||||
|
List<Double> doubleNumbers = Arrays.asList(23.48, 52.26, 13.5);
|
||||||
|
double result = doubleNumbers.stream()
|
||||||
|
.mapToDouble(Double::doubleValue)
|
||||||
|
.sum();
|
||||||
|
assertEquals(89.24, result, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void givenStreamOfIntegers_whenUsingReduceToSum_thenResultIsCorrect() {
|
||||||
|
Stream<Integer> intNumbers = Stream.of(0, 1, 2);
|
||||||
|
int result = intNumbers.reduce(0, Integer::sum);
|
||||||
|
assertEquals(106, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void givenStreamOfBigDecimals_whenUsingReduceToSum_thenResultIsCorrect() {
|
||||||
|
Stream<BigDecimal> bigDecimalNumber = Stream.of(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN);
|
||||||
|
BigDecimal result = bigDecimalNumber.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
assertEquals(11, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,6 +42,9 @@
|
||||||
<module>core-java-collections-list</module>
|
<module>core-java-collections-list</module>
|
||||||
<module>core-java-collections-list-2</module>
|
<module>core-java-collections-list-2</module>
|
||||||
<module>core-java-collections-list-3</module>
|
<module>core-java-collections-list-3</module>
|
||||||
|
<module>core-java-collections-maps</module>
|
||||||
|
<module>core-java-collections-maps-2</module>
|
||||||
|
<module>core-java-collections-maps-3</module>
|
||||||
<!-- <module>core-java-collections-set</module> --> <!-- We haven't upgraded to java 11. Fixing in BAEL-10841 -->
|
<!-- <module>core-java-collections-set</module> --> <!-- We haven't upgraded to java 11. Fixing in BAEL-10841 -->
|
||||||
|
|
||||||
<module>core-java-concurrency-2</module>
|
<module>core-java-concurrency-2</module>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This module contains articles about Kotlin core features.
|
This module contains articles about Kotlin core features.
|
||||||
|
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
- [Introduction to the Kotlin Language](https://www.baeldung.com/kotlin-intro)
|
- [Introduction to the Kotlin Language](https://www.baeldung.com/kotlin/tutorial)
|
||||||
- [Kotlin Java Interoperability](https://www.baeldung.com/kotlin-java-interoperability)
|
- [Kotlin Java Interoperability](https://www.baeldung.com/kotlin-java-interoperability)
|
||||||
- [Get a Random Number in Kotlin](https://www.baeldung.com/kotlin-random-number)
|
- [Get a Random Number in Kotlin](https://www.baeldung.com/kotlin-random-number)
|
||||||
- [Create a Java and Kotlin Project with Maven](https://www.baeldung.com/kotlin-maven-java-project)
|
- [Create a Java and Kotlin Project with Maven](https://www.baeldung.com/kotlin-maven-java-project)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Pattern Matching in Scala](https://www.baeldung.com/scala/pattern-matching)
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.guava.mapmaker;
|
||||||
|
|
||||||
|
public class Profile {
|
||||||
|
private long id;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
public Profile(long id, String type) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.guava.mapmaker;
|
||||||
|
|
||||||
|
public class Session {
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
public Session(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.guava.mapmaker;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
private long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public User(long id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.guava.mapmaker;
|
||||||
|
|
||||||
|
import com.google.common.collect.MapMaker;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
public class GuavaMapMakerUnitTest {
|
||||||
|
@Test
|
||||||
|
public void whenCreateCaches_thenCreated() {
|
||||||
|
ConcurrentMap<User, Session> sessionCache = new MapMaker().makeMap();
|
||||||
|
assertNotNull(sessionCache);
|
||||||
|
|
||||||
|
ConcurrentMap<User, Profile> profileCache = new MapMaker().makeMap();
|
||||||
|
assertNotNull(profileCache);
|
||||||
|
|
||||||
|
User userA = new User(1, "UserA");
|
||||||
|
|
||||||
|
sessionCache.put(userA, new Session(100));
|
||||||
|
Assert.assertThat(sessionCache.size(), equalTo(1));
|
||||||
|
|
||||||
|
profileCache.put(userA, new Profile(1000, "Personal"));
|
||||||
|
Assert.assertThat(profileCache.size(), equalTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateCacheWithInitialCapacity_thenCreated() {
|
||||||
|
ConcurrentMap<User, Profile> profileCache = new MapMaker().initialCapacity(100).makeMap();
|
||||||
|
assertNotNull(profileCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateCacheWithConcurrencyLevel_thenCreated() {
|
||||||
|
ConcurrentMap<User, Session> sessionCache = new MapMaker().concurrencyLevel(10).makeMap();
|
||||||
|
assertNotNull(sessionCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateCacheWithWeakKeys_thenCreated() {
|
||||||
|
ConcurrentMap<User, Session> sessionCache = new MapMaker().weakKeys().makeMap();
|
||||||
|
assertNotNull(sessionCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenCreateCacheWithWeakValues_thenCreated() {
|
||||||
|
ConcurrentMap<User, Profile> profileCache = new MapMaker().weakValues().makeMap();
|
||||||
|
assertNotNull(profileCache);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.abstractnumber;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AbstractNumberUnitTest {
|
||||||
|
|
||||||
|
private final static double DOUBLE_VALUE = 9999.999;
|
||||||
|
private final static float FLOAT_VALUE = 101.99F;
|
||||||
|
private final static long LONG_VALUE = 1000L;
|
||||||
|
private final static int INTEGER_VALUE = 100;
|
||||||
|
private final static short SHORT_VALUE = 127;
|
||||||
|
private final static byte BYTE_VALUE = 120;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDoubleValue_whenShortValueUsed_thenShortValueReturned() {
|
||||||
|
Double doubleValue = Double.valueOf(DOUBLE_VALUE);
|
||||||
|
assertEquals(9999, doubleValue.shortValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFloatValue_whenByteValueUsed_thenByteValueReturned() {
|
||||||
|
Float floatValue = Float.valueOf(FLOAT_VALUE);
|
||||||
|
assertEquals(101, floatValue.byteValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLongValue_whenInitValueUsed_thenInitValueReturned() {
|
||||||
|
Long longValue = Long.valueOf(LONG_VALUE);
|
||||||
|
assertEquals(1000, longValue.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenIntegerValue_whenLongValueUsed_thenLongValueReturned() {
|
||||||
|
Integer integerValue = Integer.valueOf(INTEGER_VALUE);
|
||||||
|
assertEquals(100, integerValue.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenShortValue_whenFloatValueUsed_thenFloatValueReturned() {
|
||||||
|
Short shortValue = Short.valueOf(SHORT_VALUE);
|
||||||
|
assertEquals(127.0F, shortValue.floatValue(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenByteValue_whenDoubleValueUsed_thenDoubleValueReturned() {
|
||||||
|
Byte byteValue = Byte.valueOf(BYTE_VALUE);
|
||||||
|
assertEquals(120.0, byteValue.doubleValue(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,4 +12,5 @@ This module contains articles about numbers in Java.
|
||||||
- [Calculating the nth Root in Java](https://www.baeldung.com/java-nth-root)
|
- [Calculating the nth Root in Java](https://www.baeldung.com/java-nth-root)
|
||||||
- [Convert Double to String, Removing Decimal Places](https://www.baeldung.com/java-double-to-string)
|
- [Convert Double to String, Removing Decimal Places](https://www.baeldung.com/java-double-to-string)
|
||||||
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
- [Changing the Order in a Sum Operation Can Produce Different Results?](https://www.baeldung.com/java-floating-point-sum-order)
|
||||||
|
- [Using Math.sin with Degrees](https://www.baeldung.com/java-math-sin-degrees)
|
||||||
- More articles: [[next -->]](/../java-numbers-2)
|
- More articles: [[next -->]](/../java-numbers-2)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>OpenNMS Repository</id>
|
<id>OpenNMS Repository</id>
|
||||||
<url>http://repo.opennms.org/maven2/</url>
|
<url>https://repo.opennms.org/maven2/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
|
@ -27,11 +27,6 @@
|
||||||
<artifactId>jnlp-servlet</artifactId>
|
<artifactId>jnlp-servlet</artifactId>
|
||||||
<version>${jnlp-servlet.version}</version>
|
<version>${jnlp-servlet.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.samples.jnlp</groupId>
|
|
||||||
<artifactId>jnlp-jardiff</artifactId>
|
|
||||||
<version>${jnlp-jardiff.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -84,7 +79,6 @@
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
|
||||||
<jnlp-jardiff.version>1.6.0</jnlp-jardiff.version>
|
|
||||||
<jnlp-servlet.version>1.6.0</jnlp-servlet.version>
|
<jnlp-servlet.version>1.6.0</jnlp-servlet.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -15,4 +15,4 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
|
||||||
- [Introduction to the jcabi-aspects AOP Annotations Library](https://www.baeldung.com/java-jcabi-aspects)
|
- [Introduction to the jcabi-aspects AOP Annotations Library](https://www.baeldung.com/java-jcabi-aspects)
|
||||||
- [Introduction to Takes](https://www.baeldung.com/java-takes)
|
- [Introduction to Takes](https://www.baeldung.com/java-takes)
|
||||||
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
|
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
|
||||||
|
- [Introduction to Alibaba Arthas](https://www.baeldung.com/java-alibaba-arthas-intro)
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>coroutines-with-quasar</artifactId>
|
||||||
|
<name>coroutines-with-quasar</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>libraries-concurrency</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>co.paralleluniverse</groupId>
|
||||||
|
<artifactId>quasar-core</artifactId>
|
||||||
|
<version>0.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>co.paralleluniverse</groupId>
|
||||||
|
<artifactId>quasar-actors</artifactId>
|
||||||
|
<version>0.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>co.paralleluniverse</groupId>
|
||||||
|
<artifactId>quasar-reactive-streams</artifactId>
|
||||||
|
<version>0.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>getClasspathFilenames</id>
|
||||||
|
<goals>
|
||||||
|
<goal>properties</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.baeldung.quasar.App</mainClass>
|
||||||
|
<workingDirectory>target/classes</workingDirectory>
|
||||||
|
<executable>java</executable>
|
||||||
|
<arguments>
|
||||||
|
<!-- Turn off before production -->
|
||||||
|
<argument>-Dco.paralleluniverse.fibers.verifyInstrumentation=true</argument>
|
||||||
|
|
||||||
|
<!-- Quasar Agent -->
|
||||||
|
<argument>-javaagent:${co.paralleluniverse:quasar-core:jar}</argument>
|
||||||
|
|
||||||
|
<!-- Classpath -->
|
||||||
|
<argument>-classpath</argument>
|
||||||
|
<classpath />
|
||||||
|
|
||||||
|
<!-- Main class -->
|
||||||
|
<argument>com.baeldung.quasar.App</argument>
|
||||||
|
</arguments>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>12</source>
|
||||||
|
<target>12</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.baeldung.quasar;
|
||||||
|
|
||||||
|
import co.paralleluniverse.fibers.Fiber;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new Fiber<Void>(() -> {
|
||||||
|
System.out.println("Inside fiber coroutine...");
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>libraries-concurrency</artifactId>
|
||||||
|
<name>libraries-concurrency</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<!-- <module>coroutines-with-quasar</module> --><!-- we haven't upgraded to Java 12 -->
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [How to Use Command Line Arguments in a Bash Script](https://www.baeldung.com/linux/use-command-line-arguments-in-bash-script)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles
|
||||||
|
|
||||||
|
- [Bash Functions in Linux](https://www.baeldung.com/linux/bash-functions)
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide to the Linux read Command](https://www.baeldung.com/linux/read-command)
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Linux Commands – Remove All Text After X](https://www.baeldung.com/linux/tr-manipulate-strings)
|
- [Linux Commands – Remove All Text After X](https://www.baeldung.com/linux/tr-manipulate-strings)
|
||||||
|
- [Linux Commands for Appending Multiple Lines to a File](https://www.baeldung.com/linux/appending-multiple-lines-to-file2)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- TBD
|
- TBD
|
||||||
- [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback)
|
- [Improved Java Logging with Mapped Diagnostic Context (MDC)](https://www.baeldung.com/mdc-in-log4j-2-logback)
|
||||||
- [Java Logging with Nested Diagnostic Context (NDC)](https:www.baeldung.com/java-logging-ndc-log4j)
|
- [Java Logging with Nested Diagnostic Context (NDC)](https://www.baeldung.com/java-logging-ndc-log4j)
|
||||||
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)
|
- [Drools Using Rules from Excel Files](https://www.baeldung.com/drools-excel)
|
||||||
|
|
||||||
### References
|
### References
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Guide to the Linux wc Command](https://www.baeldung.com/linux/wc-command)
|
|
@ -0,0 +1,6 @@
|
||||||
|
## Netty
|
||||||
|
|
||||||
|
This module contains articles about Netty.
|
||||||
|
|
||||||
|
### Relevant Articles:
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>netty</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>netty</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-all</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.conscrypt</groupId>
|
||||||
|
<artifactId>conscrypt-openjdk-uber</artifactId>
|
||||||
|
<version>2.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<netty.version>4.1.48.Final</netty.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,135 @@
|
||||||
|
package com.baeldung.netty.http2;
|
||||||
|
|
||||||
|
import static io.netty.handler.logging.LogLevel.INFO;
|
||||||
|
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
|
import com.baeldung.netty.http2.client.Http2ClientResponseHandler;
|
||||||
|
import com.baeldung.netty.http2.client.Http2SettingsHandler;
|
||||||
|
import com.baeldung.netty.http2.server.Http2ServerResponseHandler;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||||
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
import io.netty.handler.codec.http.HttpScheme;
|
||||||
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
import io.netty.handler.codec.http2.DefaultHttp2Connection;
|
||||||
|
import io.netty.handler.codec.http2.DelegatingDecompressorFrameListener;
|
||||||
|
import io.netty.handler.codec.http2.Http2Connection;
|
||||||
|
import io.netty.handler.codec.http2.Http2FrameCodecBuilder;
|
||||||
|
import io.netty.handler.codec.http2.Http2FrameLogger;
|
||||||
|
import io.netty.handler.codec.http2.Http2SecurityUtil;
|
||||||
|
import io.netty.handler.codec.http2.HttpConversionUtil;
|
||||||
|
import io.netty.handler.codec.http2.HttpToHttp2ConnectionHandler;
|
||||||
|
import io.netty.handler.codec.http2.HttpToHttp2ConnectionHandlerBuilder;
|
||||||
|
import io.netty.handler.codec.http2.InboundHttp2ToHttpAdapterBuilder;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolConfig;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolNames;
|
||||||
|
import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
|
||||||
|
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||||
|
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||||
|
|
||||||
|
public class Http2Util {
|
||||||
|
public static SslContext createSSLContext(boolean isServer) throws SSLException, CertificateException {
|
||||||
|
|
||||||
|
SslContext sslCtx;
|
||||||
|
|
||||||
|
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||||
|
|
||||||
|
if (isServer) {
|
||||||
|
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
|
||||||
|
.sslProvider(SslProvider.JDK)
|
||||||
|
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
|
||||||
|
.applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN,
|
||||||
|
SelectorFailureBehavior.NO_ADVERTISE,
|
||||||
|
SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1))
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
sslCtx = SslContextBuilder.forClient()
|
||||||
|
.sslProvider(SslProvider.JDK)
|
||||||
|
.ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
|
||||||
|
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||||
|
.applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN,
|
||||||
|
SelectorFailureBehavior.NO_ADVERTISE,
|
||||||
|
SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return sslCtx;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApplicationProtocolNegotiationHandler getServerAPNHandler() {
|
||||||
|
ApplicationProtocolNegotiationHandler serverAPNHandler = new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_2) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) throws Exception {
|
||||||
|
if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
|
||||||
|
ctx.pipeline()
|
||||||
|
.addLast(Http2FrameCodecBuilder.forServer()
|
||||||
|
.build(), new Http2ServerResponseHandler());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Protocol: " + protocol + " not supported");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return serverAPNHandler;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApplicationProtocolNegotiationHandler getClientAPNHandler(int maxContentLength, Http2SettingsHandler settingsHandler, Http2ClientResponseHandler responseHandler) {
|
||||||
|
final Http2FrameLogger logger = new Http2FrameLogger(INFO, Http2Util.class);
|
||||||
|
final Http2Connection connection = new DefaultHttp2Connection(false);
|
||||||
|
|
||||||
|
HttpToHttp2ConnectionHandler connectionHandler = new HttpToHttp2ConnectionHandlerBuilder()
|
||||||
|
.frameListener(new DelegatingDecompressorFrameListener(connection, new InboundHttp2ToHttpAdapterBuilder(connection).maxContentLength(maxContentLength)
|
||||||
|
.propagateSettings(true)
|
||||||
|
.build()))
|
||||||
|
.frameLogger(logger)
|
||||||
|
.connection(connection)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ApplicationProtocolNegotiationHandler clientAPNHandler = new ApplicationProtocolNegotiationHandler(ApplicationProtocolNames.HTTP_2) {
|
||||||
|
@Override
|
||||||
|
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
|
||||||
|
if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
|
||||||
|
ChannelPipeline p = ctx.pipeline();
|
||||||
|
p.addLast(connectionHandler);
|
||||||
|
p.addLast(settingsHandler, responseHandler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.close();
|
||||||
|
throw new IllegalStateException("Protocol: " + protocol + " not supported");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return clientAPNHandler;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FullHttpRequest createGetRequest(String host, int port) {
|
||||||
|
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.valueOf("HTTP/2.0"), HttpMethod.GET, "/", Unpooled.EMPTY_BUFFER);
|
||||||
|
request.headers()
|
||||||
|
.add(HttpHeaderNames.HOST, new String(host + ":" + port));
|
||||||
|
request.headers()
|
||||||
|
.add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), HttpScheme.HTTPS);
|
||||||
|
request.headers()
|
||||||
|
.add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
|
||||||
|
request.headers()
|
||||||
|
.add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.DEFLATE);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.baeldung.netty.http2.client;
|
||||||
|
|
||||||
|
import com.baeldung.netty.http2.Http2Util;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
||||||
|
public class Http2ClientInitializer extends ChannelInitializer<SocketChannel> {
|
||||||
|
|
||||||
|
private final SslContext sslCtx;
|
||||||
|
private final int maxContentLength;
|
||||||
|
private Http2SettingsHandler settingsHandler;
|
||||||
|
private Http2ClientResponseHandler responseHandler;
|
||||||
|
private String host;
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
public Http2ClientInitializer(SslContext sslCtx, int maxContentLength, String host, int port) {
|
||||||
|
this.sslCtx = sslCtx;
|
||||||
|
this.maxContentLength = maxContentLength;
|
||||||
|
this.host = host;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
|
||||||
|
settingsHandler = new Http2SettingsHandler(ch.newPromise());
|
||||||
|
responseHandler = new Http2ClientResponseHandler();
|
||||||
|
|
||||||
|
if (sslCtx != null) {
|
||||||
|
ChannelPipeline pipeline = ch.pipeline();
|
||||||
|
pipeline.addLast(sslCtx.newHandler(ch.alloc(), host, port));
|
||||||
|
pipeline.addLast(Http2Util.getClientAPNHandler(maxContentLength, settingsHandler, responseHandler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Http2SettingsHandler getSettingsHandler() {
|
||||||
|
return settingsHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Http2ClientResponseHandler getResponseHandler() {
|
||||||
|
return responseHandler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package com.baeldung.netty.http2.client;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http2.HttpConversionUtil;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
|
public class Http2ClientResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(Http2ClientResponseHandler.class);
|
||||||
|
private final Map<Integer, MapValues> streamidMap;
|
||||||
|
|
||||||
|
public Http2ClientResponseHandler() {
|
||||||
|
streamidMap = new HashMap<Integer, MapValues>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapValues put(int streamId, ChannelFuture writeFuture, ChannelPromise promise) {
|
||||||
|
return streamidMap.put(streamId, new MapValues(writeFuture, promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String awaitResponses(long timeout, TimeUnit unit) {
|
||||||
|
|
||||||
|
Iterator<Entry<Integer, MapValues>> itr = streamidMap.entrySet()
|
||||||
|
.iterator();
|
||||||
|
|
||||||
|
String response = null;
|
||||||
|
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
Entry<Integer, MapValues> entry = itr.next();
|
||||||
|
ChannelFuture writeFuture = entry.getValue()
|
||||||
|
.getWriteFuture();
|
||||||
|
|
||||||
|
if (!writeFuture.awaitUninterruptibly(timeout, unit)) {
|
||||||
|
throw new IllegalStateException("Timed out waiting to write for stream id " + entry.getKey());
|
||||||
|
}
|
||||||
|
if (!writeFuture.isSuccess()) {
|
||||||
|
throw new RuntimeException(writeFuture.cause());
|
||||||
|
}
|
||||||
|
ChannelPromise promise = entry.getValue()
|
||||||
|
.getPromise();
|
||||||
|
|
||||||
|
if (!promise.awaitUninterruptibly(timeout, unit)) {
|
||||||
|
throw new IllegalStateException("Timed out waiting for response on stream id " + entry.getKey());
|
||||||
|
}
|
||||||
|
if (!promise.isSuccess()) {
|
||||||
|
throw new RuntimeException(promise.cause());
|
||||||
|
}
|
||||||
|
logger.info("---Stream id: " + entry.getKey() + " received---");
|
||||||
|
response = entry.getValue().getResponse();
|
||||||
|
|
||||||
|
itr.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception {
|
||||||
|
Integer streamId = msg.headers()
|
||||||
|
.getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text());
|
||||||
|
if (streamId == null) {
|
||||||
|
logger.error("HttpResponseHandler unexpected message received: " + msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapValues value = streamidMap.get(streamId);
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
logger.error("Message received for unknown stream id " + streamId);
|
||||||
|
ctx.close();
|
||||||
|
} else {
|
||||||
|
ByteBuf content = msg.content();
|
||||||
|
if (content.isReadable()) {
|
||||||
|
int contentLength = content.readableBytes();
|
||||||
|
byte[] arr = new byte[contentLength];
|
||||||
|
content.readBytes(arr);
|
||||||
|
String response = new String(arr, 0, contentLength, CharsetUtil.UTF_8);
|
||||||
|
logger.info("Response from Server: "+ (response));
|
||||||
|
value.setResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.getPromise()
|
||||||
|
.setSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MapValues {
|
||||||
|
ChannelFuture writeFuture;
|
||||||
|
ChannelPromise promise;
|
||||||
|
String response;
|
||||||
|
|
||||||
|
public String getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponse(String response) {
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapValues(ChannelFuture writeFuture2, ChannelPromise promise2) {
|
||||||
|
this.writeFuture = writeFuture2;
|
||||||
|
this.promise = promise2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelFuture getWriteFuture() {
|
||||||
|
return writeFuture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChannelPromise getPromise() {
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.netty.http2.client;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.handler.codec.http2.Http2Settings;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class Http2SettingsHandler extends SimpleChannelInboundHandler<Http2Settings> {
|
||||||
|
private final ChannelPromise promise;
|
||||||
|
|
||||||
|
public Http2SettingsHandler(ChannelPromise promise) {
|
||||||
|
this.promise = promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void awaitSettings(long timeout, TimeUnit unit) throws Exception {
|
||||||
|
if (!promise.awaitUninterruptibly(timeout, unit)) {
|
||||||
|
throw new IllegalStateException("Timed out waiting for settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, Http2Settings msg) throws Exception {
|
||||||
|
promise.setSuccess();
|
||||||
|
|
||||||
|
ctx.pipeline()
|
||||||
|
.remove(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.baeldung.netty.http2.server;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.baeldung.netty.http2.Http2Util;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
import io.netty.handler.logging.LogLevel;
|
||||||
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
|
||||||
|
public final class Http2Server {
|
||||||
|
|
||||||
|
private static final int PORT = 8443;
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Http2Server.class);
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
SslContext sslCtx = Http2Util.createSSLContext(true);
|
||||||
|
|
||||||
|
EventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
try {
|
||||||
|
ServerBootstrap b = new ServerBootstrap();
|
||||||
|
b.option(ChannelOption.SO_BACKLOG, 1024);
|
||||||
|
b.group(group)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.handler(new LoggingHandler(LogLevel.INFO))
|
||||||
|
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
if (sslCtx != null) {
|
||||||
|
ch.pipeline()
|
||||||
|
.addLast(sslCtx.newHandler(ch.alloc()), Http2Util.getServerAPNHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Channel ch = b.bind(PORT)
|
||||||
|
.sync()
|
||||||
|
.channel();
|
||||||
|
|
||||||
|
logger.info("HTTP/2 Server is listening on https://127.0.0.1:" + PORT + '/');
|
||||||
|
|
||||||
|
ch.closeFuture()
|
||||||
|
.sync();
|
||||||
|
} finally {
|
||||||
|
group.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.baeldung.netty.http2.server;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
|
import io.netty.channel.ChannelHandler.Sharable;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
|
import io.netty.handler.codec.http2.DefaultHttp2DataFrame;
|
||||||
|
import io.netty.handler.codec.http2.DefaultHttp2Headers;
|
||||||
|
import io.netty.handler.codec.http2.DefaultHttp2HeadersFrame;
|
||||||
|
import io.netty.handler.codec.http2.Http2Headers;
|
||||||
|
import io.netty.handler.codec.http2.Http2HeadersFrame;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
|
@Sharable
|
||||||
|
public class Http2ServerResponseHandler extends ChannelDuplexHandler {
|
||||||
|
|
||||||
|
static final ByteBuf RESPONSE_BYTES = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
|
super.exceptionCaught(ctx, cause);
|
||||||
|
cause.printStackTrace();
|
||||||
|
ctx.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||||
|
if (msg instanceof Http2HeadersFrame) {
|
||||||
|
Http2HeadersFrame msgHeader = (Http2HeadersFrame) msg;
|
||||||
|
if (msgHeader.isEndStream()) {
|
||||||
|
ByteBuf content = ctx.alloc()
|
||||||
|
.buffer();
|
||||||
|
content.writeBytes(RESPONSE_BYTES.duplicate());
|
||||||
|
|
||||||
|
Http2Headers headers = new DefaultHttp2Headers().status(HttpResponseStatus.OK.codeAsText());
|
||||||
|
ctx.write(new DefaultHttp2HeadersFrame(headers).stream(msgHeader.stream()));
|
||||||
|
ctx.write(new DefaultHttp2DataFrame(content, true).stream(msgHeader.stream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
super.channelRead(ctx, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
ctx.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue