Merge branch 'eugenp:master' into master

This commit is contained in:
priya-soni 2022-04-14 21:30:38 +05:30 committed by GitHub
commit ce9fa68436
290 changed files with 6617 additions and 2144 deletions

View File

@ -7,5 +7,6 @@ This module contains articles about Project Jigsaw and the Java Platform Module
- [Introduction to Project Jigsaw](http://www.baeldung.com/project-jigsaw-java-modularity)
- [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity)
- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api)
- [Java 9 Illegal Reflective Access Warning](https://www.baeldung.com/java-illegal-reflective-access)

View File

@ -0,0 +1,11 @@
#!/bin/bash
DIR=baeldung-agent
# compile
mkdir -p out/${DIR}
javac -d out/${DIR} $(find ${DIR} -type f -name "*.java")
# package
mkdir -p mods
jar --create --file=mods/${DIR}.jar --manifest=${DIR}/manifest.txt -C out/${DIR} .

View File

@ -0,0 +1,11 @@
#!/bin/bash
DIR=baeldung-reflected
# compile
mkdir -p out/${DIR}
javac -d out/${DIR} $(find ${DIR} -type f -name "*.java")
# package
mkdir -p mods
jar --create --file=mods/${DIR}.jar -C out/${DIR} .

View File

@ -0,0 +1,11 @@
#!/bin/bash
DIR=baeldung-intermedium
# compile
mkdir -p out/${DIR}
javac -d out/${DIR} $(find ${DIR} -type f -name "*.java")
# package
mkdir -p mods
jar --create --file=mods/${DIR}.jar -C out/${DIR} .

View File

@ -0,0 +1,11 @@
#!/bin/bash
DIR=baeldung-reflecting-named
# compile
mkdir -p out/${DIR}
javac -d out/${DIR} --module-path mods $(find ${DIR} -type f -name "*.java")
# package
mkdir -p mods
jar --create --file=mods/${DIR}.jar -C out/${DIR} .

View File

@ -0,0 +1,11 @@
#!/bin/bash
DIR=baeldung-reflecting-unnamed
# compile
mkdir -p out/${DIR}
javac -d out/${DIR} $(find ${DIR} -type f -name "*.java")
# package
mkdir -p mods
jar --create --file=mods/${DIR}.jar -C out/${DIR} .

View File

@ -0,0 +1,4 @@
#!/bin/bash
java --module-path mods \
--add-opens baeldung.reflected/com.baeldung.reflected.internal=baeldung.reflecting.named \
--module baeldung.reflecting.named/com.baeldung.reflecting.named.Main

View File

@ -0,0 +1,4 @@
#!/bin/bash
java --module-path mods \
--add-opens baeldung.reflected/com.baeldung.reflected.internal=baeldung.intermedium \
--module baeldung.reflecting.named/com.baeldung.reflecting.named.MainWithForwardOpen

View File

@ -0,0 +1,4 @@
#!/bin/bash
java --module-path mods \
-javaagent:mods/baeldung-agent.jar=com.baeldung.reflected.internal.InternalNonPublicClass,com.baeldung.reflecting.named.Main \
--module baeldung.reflecting.named/com.baeldung.reflecting.named.Main

View File

@ -0,0 +1,2 @@
#!/bin/bash
java -cp "mods/*" com.baeldung.reflecting.unnamed.Main

View File

@ -0,0 +1,2 @@
#!/bin/bash
java -cp "mods/*" --add-opens java.base/java.lang=ALL-UNNAMED com.baeldung.reflecting.unnamed.Main

View File

@ -0,0 +1,2 @@
#!/bin/bash
java -cp "mods/*" -javaagent:mods/baeldung-agent.jar com.baeldung.reflecting.unnamed.Main

View File

@ -0,0 +1,4 @@
#!/bin/bash
rm -rf out
rm -rf mods

View File

@ -0,0 +1,69 @@
package com.baeldung.agent;
import java.lang.instrument.Instrumentation;
import java.util.*;
public class LoadTimeAgent {
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("agentArgs: " + agentArgs);
if (agentArgs != null) {
addExportsAndOpensByClassName(inst, agentArgs);
}
else {
addExportsAndOpensToUnnamedModule(inst);
}
}
private static void addExportsAndOpensByClassName(Instrumentation inst, String agentArgs) {
String[] array = agentArgs.split(",");
try {
String className1 = array[0];
String className2 = array[1];
Class<?> clazz1 = Class.forName(className1);
Class<?> clazz2 = Class.forName(className2);
Module srcModule = clazz1.getModule();
Module targetModule = clazz2.getModule();
redefineModule(inst, srcModule, targetModule);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static void addExportsAndOpensToUnnamedModule(Instrumentation inst) {
Module unnamedModule = ClassLoader.getSystemClassLoader().getUnnamedModule();
Set<Module> modules = ModuleLayer.boot().modules();
for (Module m : modules) {
redefineModule(inst, m, unnamedModule);
}
}
private static void redefineModule(Instrumentation inst, Module src, Module target) {
// prepare extra reads
Set<Module> extraReads = Collections.singleton(target);
// prepare extra exports
Set<String> packages = src.getPackages();
Map<String, Set<Module>> extraExports = new HashMap<>();
for (String pkg : packages) {
extraExports.put(pkg, extraReads);
}
// prepare extra opens
Map<String, Set<Module>> extraOpens = new HashMap<>();
for (String pkg : packages) {
extraOpens.put(pkg, extraReads);
}
// prepare extra uses
Set<Class<?>> extraUses = Collections.emptySet();
// prepare extra provides
Map<Class<?>, List<Class<?>>> extraProvides = Collections.emptyMap();
// redefine module
inst.redefineModule(src, extraReads, extraExports, extraOpens, extraUses, extraProvides);
}
}

View File

@ -0,0 +1,3 @@
Premain-Class: com.baeldung.agent.LoadTimeAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true

View File

@ -0,0 +1,3 @@
module baeldung.agent {
requires java.instrument;
}

View File

@ -0,0 +1,15 @@
package com.baeldung.intermedium;
public class ForwardOpen {
public static void addOpens(Class<?> clazz1, Class<?> clazz2) {
Module currentModule = ForwardOpen.class.getModule();
Module srcModule = clazz1.getModule();
Module targetModule = clazz2.getModule();
System.out.println("current module: " + currentModule.getName());
System.out.println("source module: " + srcModule.getName());
System.out.println("target module: " + targetModule.getName());
srcModule.addOpens(clazz1.getPackageName(), targetModule);
}
}

View File

@ -0,0 +1,3 @@
module baeldung.intermedium {
exports com.baeldung.intermedium;
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.exported;
class ExportedNonPublicClass {
public static void testPublicStaticMethod() {
System.out.println("ExportedNonPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("ExportedNonPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.exported;
public class ExportedPublicClass {
public static void testPublicStaticMethod() {
System.out.println("ExportedPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("ExportedPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.internal;
class InternalNonPublicClass {
public static void testPublicStaticMethod() {
System.out.println("InternalNonPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("InternalNonPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.internal;
public class InternalPublicClass {
public static void testPublicStaticMethod() {
System.out.println("InternalPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("InternalPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.opened;
class OpenedNonPublicClass {
public static void testPublicStaticMethod() {
System.out.println("OpenedNonPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("OpenedNonPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.reflected.opened;
public class OpenedPublicClass {
public static void testPublicStaticMethod() {
System.out.println("OpenedPublicClass.testPublicStaticMethod()");
}
private static void testPrivateStaticMethod() {
System.out.println("OpenedPublicClass.testPrivateStaticMethod()");
}
}

View File

@ -0,0 +1,4 @@
module baeldung.reflected {
exports com.baeldung.reflected.exported;
opens com.baeldung.reflected.opened;
}

View File

@ -0,0 +1,12 @@
package com.baeldung.reflecting.named;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.baeldung.reflected.internal.InternalNonPublicClass");
Method method = clazz.getDeclaredMethod("testPrivateStaticMethod");
method.setAccessible(true);
method.invoke(null);
}
}

View File

@ -0,0 +1,18 @@
package com.baeldung.reflecting.named;
import com.baeldung.intermedium.ForwardOpen;
import java.lang.reflect.Method;
public class MainWithForwardOpen {
public static void main(String[] args) throws Exception {
Class<?> currentClass = Main.class;
Class<?> clazz = Class.forName("com.baeldung.reflected.internal.InternalNonPublicClass");
ForwardOpen.addOpens(clazz, currentClass);
Method method = clazz.getDeclaredMethod("testPrivateStaticMethod");
method.setAccessible(true);
method.invoke(null);
}
}

View File

@ -0,0 +1,4 @@
module baeldung.reflecting.named {
requires baeldung.intermedium;
requires baeldung.reflected;
}

View File

@ -0,0 +1,13 @@
package com.baeldung.reflecting.unnamed;
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = StringBuilder.class;
Field f = clazz.getDeclaredField("serialVersionUID");
f.setAccessible(true);
Object value = f.get(null);
System.out.println(value);
}
}

View File

@ -0,0 +1,36 @@
package test.java.com.baeldung.list.listOfHashMaps;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.Assert.assertTrue;
public class ListOfHashMapsUnitTest {
List<HashMap<String, List<String>>> booksAuthorsMapsList = new ArrayList<>();
@Test
public void givenMaps_whenAddToList_thenListContainsMaps() {
HashMap<String, List<String>> javaBooksAuthorsMap = new HashMap<>();
HashMap<String, List<String>> phpBooksAuthorsMap = new HashMap<>();
javaBooksAuthorsMap.put("Head First Java", Arrays.asList("Kathy Sierra", "Bert Bates"));
javaBooksAuthorsMap.put("Effective Java", Arrays.asList("Joshua Bloch"));
javaBooksAuthorsMap.put("OCA Java SE 8",
Arrays.asList("Kathy Sierra", "Bert Bates", "Elisabeth Robson"));
phpBooksAuthorsMap.put("The Joy of PHP", Arrays.asList("Alan Forbes"));
phpBooksAuthorsMap.put("Head First PHP &amp; MySQL",
Arrays.asList("Lynn Beighley", "Michael Morrison"));
booksAuthorsMapsList.add(javaBooksAuthorsMap);
booksAuthorsMapsList.add(phpBooksAuthorsMap);
assertTrue(booksAuthorsMapsList.get(0).keySet().containsAll
(javaBooksAuthorsMap.keySet().stream().collect(Collectors.toList())));
assertTrue(booksAuthorsMapsList.get(1).keySet().containsAll
(phpBooksAuthorsMap.keySet().stream().collect(Collectors.toList())));
}
}

View File

@ -12,3 +12,4 @@ This module contains articles about the Java Set collection
- [Set Operations in Java](https://www.baeldung.com/java-set-operations)
- [Copying Sets in Java](https://www.baeldung.com/java-copy-sets)
- [Immutable Set in Java](https://www.baeldung.com/java-immutable-set)
- [Find the Difference Between Two Sets](https://www.baeldung.com/java-difference-between-sets)

View File

@ -11,4 +11,5 @@ This module contains articles about date operations in Java.
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
- [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number)
- [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-date)
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)

View File

@ -12,3 +12,4 @@ This module contains articles about parsing and formatting Java date and time ob
- [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp)
- [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date)
- [Format a Milliseconds Duration to HH:MM:SS](https://www.baeldung.com/java-ms-to-hhmmss)
- [Format Instant to String in Java](https://www.baeldung.com/java-instant-to-string)

View File

@ -0,0 +1,54 @@
package com.baeldung.formatinstant;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.UnsupportedTemporalTypeException;
import org.joda.time.format.DateTimeFormat;
import org.junit.Test;
public class FormatInstantUnitTest {
private static final String PATTERN_FORMAT = "dd.MM.yyyy";
@Test
public void givenInstant_whenUsingDateTimeFormatter_thenFormat() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT)
.withZone(ZoneId.systemDefault());
Instant instant = Instant.parse("2022-02-15T18:35:24.00Z");
String formattedInstant = formatter.format(instant);
assertThat(formattedInstant).isEqualTo("15.02.2022");
}
@Test(expected = UnsupportedTemporalTypeException.class)
public void givenInstant_whenNotSpecifyingTimeZone_thenThrowException() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN_FORMAT);
Instant instant = Instant.now();
formatter.format(instant);
}
@Test
public void givenInstant_whenUsingToString_thenFormat() {
Instant instant = Instant.ofEpochMilli(1641828224000L);
String formattedInstant = instant.toString();
assertThat(formattedInstant).isEqualTo("2022-01-10T15:23:44Z");
}
@Test
public void givenInstant_whenUsingJodaTime_thenFormat() {
org.joda.time.Instant instant = new org.joda.time.Instant("2022-03-20T10:11:12");
String formattedInstant = DateTimeFormat.forPattern(PATTERN_FORMAT)
.print(instant);
assertThat(formattedInstant).isEqualTo("20.03.2022");
}
}

View File

@ -8,4 +8,5 @@ This module contains articles about core Java input and output (IO)
- [Simulate touch Command in Java](https://www.baeldung.com/java-simulate-touch-command)
- [SequenceInputStream Class in Java](https://www.baeldung.com/java-sequenceinputstream)
- [Read a File Into a Map in Java](https://www.baeldung.com/java-read-file-into-map)
- [Read User Input Until a Condition is Met](https://www.baeldung.com/java-read-input-until-condition)
- [[<-- Prev]](/core-java-modules/core-java-io-3)

View File

@ -0,0 +1,60 @@
package com.baeldung.implementsvsextends;
import com.baeldung.implementsvsextends.media.model.AudioMedia;
import com.baeldung.implementsvsextends.media.model.Media;
import com.baeldung.implementsvsextends.media.model.VideoMedia;
import com.baeldung.implementsvsextends.media.player.impl.AudioMediaPlayer;
import com.baeldung.implementsvsextends.media.player.impl.CustomMediaPlayer;
import com.baeldung.implementsvsextends.media.player.impl.MultiMediaPlayer;
import com.baeldung.implementsvsextends.media.player.impl.VideoMediaPlayer;
public class Main {
public static void main(String[] args) {
Media media = new Media();
media.setId(001);
media.setTitle("Media1");
media.setArtist("Artist001");
AudioMedia audioMedia = new AudioMedia();
audioMedia.setId(101);
audioMedia.setTitle("Audio1");
audioMedia.setArtist("Artist101");
audioMedia.setBitrate(3500);
audioMedia.setFrequency("256kbps");
VideoMedia videoMedia = new VideoMedia();
videoMedia.setId(201);
videoMedia.setTitle("Video1");
videoMedia.setArtist("Artist201");
videoMedia.setResolution("1024x768");
videoMedia.setAspectRatio("16:9");
System.out.println(media);
System.out.println(audioMedia);
System.out.println(videoMedia);
AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer();
audioMediaPlayer.play();
audioMediaPlayer.pause();
VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer();
videoMediaPlayer.play();
videoMediaPlayer.pause();
MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer();
multiMediaPlayer.play();
multiMediaPlayer.pause();
multiMediaPlayer.seek();
multiMediaPlayer.fastForward();
CustomMediaPlayer customMediaPlayer = new CustomMediaPlayer();
customMediaPlayer.play();
customMediaPlayer.pause();
customMediaPlayer.setId(301);
customMediaPlayer.setTitle("Custom1");
customMediaPlayer.setArtist("Artist301");
System.out.println(customMediaPlayer);
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.implementsvsextends.media.model;
public class AudioMedia extends Media {
private int bitrate;
private String frequency;
@Override
public void printTitle() {
System.out.println("AudioMedia Title");
}
public int getBitrate() {
return bitrate;
}
public void setBitrate(int bitrate) {
this.bitrate = bitrate;
}
public String getFrequency() {
return frequency;
}
public void setFrequency(String frequency) {
this.frequency = frequency;
}
@Override
public String toString() {
return "AudioMedia{" +
"id=" + this.getId() +
", title='" + this.getTitle() + '\'' +
", artist='" + this.getArtist() + '\'' +
", bitrate=" + bitrate +
", frequency='" + frequency + '\'' +
"} ";
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.implementsvsextends.media.model;
public class Media {
private int id;
private String title;
private String artist;
public void printTitle() {
System.out.println("Media Title");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
@Override
public String toString() {
return "Media{" +
"id=" + id +
", title='" + title + '\'' +
", artist='" + artist + '\'' +
'}';
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.implementsvsextends.media.model;
public class VideoMedia extends Media {
private String resolution;
private String aspectRatio;
public String getResolution() {
return resolution;
}
public void setResolution(String resolution) {
this.resolution = resolution;
}
public String getAspectRatio() {
return aspectRatio;
}
public void setAspectRatio(String aspectRatio) {
this.aspectRatio = aspectRatio;
}
@Override
public String toString() {
return "VideoMedia{" +
"id=" + this.getId() +
", title='" + this.getTitle() + '\'' +
", artist='" + this.getArtist() + '\'' +
"resolution='" + resolution + '\'' +
", aspectRatio='" + aspectRatio + '\'' +
"} ";
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.implementsvsextends.media.player;
public interface AdvancedPlayerOptions {
void seek();
void fastForward();
}

View File

@ -0,0 +1,8 @@
package com.baeldung.implementsvsextends.media.player;
public interface MediaPlayer {
void play();
void pause();
}

View File

@ -0,0 +1,16 @@
package com.baeldung.implementsvsextends.media.player.impl;
import com.baeldung.implementsvsextends.media.player.MediaPlayer;
public class AudioMediaPlayer implements MediaPlayer {
@Override
public void play() {
System.out.println("AudioMediaPlayer is Playing");
}
@Override
public void pause() {
System.out.println("AudioMediaPlayer is Paused");
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.implementsvsextends.media.player.impl;
import com.baeldung.implementsvsextends.media.model.Media;
import com.baeldung.implementsvsextends.media.player.MediaPlayer;
public class CustomMediaPlayer extends Media implements MediaPlayer {
@Override
public void play() {
System.out.println("CustomMediaPlayer is Playing");
}
@Override
public void pause() {
System.out.println("CustomMediaPlayer is Paused");
}
}

View File

@ -0,0 +1,27 @@
package com.baeldung.implementsvsextends.media.player.impl;
import com.baeldung.implementsvsextends.media.player.AdvancedPlayerOptions;
import com.baeldung.implementsvsextends.media.player.MediaPlayer;
public class MultiMediaPlayer implements MediaPlayer, AdvancedPlayerOptions {
@Override
public void play() {
System.out.println("MultiMediaPlayer is Playing");
}
@Override
public void pause() {
System.out.println("MultiMediaPlayer is Paused");
}
@Override
public void seek() {
System.out.println("MultiMediaPlayer is being seeked");
}
@Override
public void fastForward() {
System.out.println("MultiMediaPlayer is being fast forwarded");
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.implementsvsextends.media.player.impl;
import com.baeldung.implementsvsextends.media.player.MediaPlayer;
public class VideoMediaPlayer implements MediaPlayer {
@Override
public void play() {
System.out.println("VideoMediaPlayer is Playing");
}
@Override
public void pause() {
System.out.println("VideoMediaPlayer is Paused");
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.implementsvsextends.media.model;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
public class AudioMediaUnitTest {
@Test
public void givenAudioMediaInstance_whenCheckedType_thenIsInstanceOfMedia() {
AudioMedia audioMedia = new AudioMedia();
Assert.assertThat(audioMedia, CoreMatchers.<AudioMedia>instanceOf(Media.class));
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.implementsvsextends.media.model;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
public class VideoMediaUnitTest {
@Test
public void givenVideoMediaInstance_whenCheckedType_thenIsInstanceOfMedia() {
VideoMedia videoMedia = new VideoMedia();
Assert.assertThat(videoMedia, CoreMatchers.<VideoMedia>instanceOf(Media.class));
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.implementsvsextends.media.player.impl;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class AudioMediaPlayerUnitTest {
private final PrintStream standardOut = System.out;
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
@BeforeEach
public void setUp() {
System.setOut(new PrintStream(outputStreamCaptor));
}
@AfterEach
public void tearDown() {
System.setOut(standardOut);
}
@Test
public void givenAudioMediaPlayer_whenPlay_thenPrintsPlayingString() {
AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer();
audioMediaPlayer.play();
Assert.assertEquals("AudioMediaPlayer is Playing", outputStreamCaptor.toString()
.trim());
}
@Test
public void givenAudioMediaPlayer_whenPause_thenPrintsPausedString() {
AudioMediaPlayer audioMediaPlayer = new AudioMediaPlayer();
audioMediaPlayer.pause();
Assert.assertEquals("AudioMediaPlayer is Paused", outputStreamCaptor.toString()
.trim());
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.implementsvsextends.media.player.impl;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class MultiMediaPlayerUnitTest {
private final PrintStream standardOut = System.out;
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
@BeforeEach
public void setUp() {
System.setOut(new PrintStream(outputStreamCaptor));
}
@AfterEach
public void tearDown() {
System.setOut(standardOut);
}
@Test
public void givenMultiMediaPlayer_whenPlay_thenPrintsPlayingString() {
MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer();
multiMediaPlayer.play();
Assert.assertEquals("MultiMediaPlayer is Playing", outputStreamCaptor.toString()
.trim());
}
@Test
public void givenMultiMediaPlayer_whenPause_thenPrintsPausedString() {
MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer();
multiMediaPlayer.pause();
Assert.assertEquals("MultiMediaPlayer is Paused", outputStreamCaptor.toString()
.trim());
}
@Test
public void givenMultiMediaPlayer_whenSeek_thenPrintsPausedString() {
MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer();
multiMediaPlayer.seek();
Assert.assertEquals("MultiMediaPlayer is being seeked", outputStreamCaptor.toString()
.trim());
}
@Test
public void givenMultiMediaPlayer_whenFastForward_thenPrintsPausedString() {
MultiMediaPlayer multiMediaPlayer = new MultiMediaPlayer();
multiMediaPlayer.fastForward();
Assert.assertEquals("MultiMediaPlayer is being fast forwarded",
outputStreamCaptor.toString()
.trim());
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.implementsvsextends.media.player.impl;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class VideoMediaPlayerUnitTest {
private final PrintStream standardOut = System.out;
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
@BeforeEach
public void setUp() {
System.setOut(new PrintStream(outputStreamCaptor));
}
@AfterEach
public void tearDown() {
System.setOut(standardOut);
}
@Test
public void givenVideoMediaPlayer_whenPlay_thenPrintsPlayingString() {
VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer();
videoMediaPlayer.play();
Assert.assertEquals("VideoMediaPlayer is Playing", outputStreamCaptor.toString()
.trim());
}
@Test
public void givenVideoMediaPlayer_whenPause_thenPrintsPausedString() {
VideoMediaPlayer videoMediaPlayer = new VideoMediaPlayer();
videoMediaPlayer.pause();
Assert.assertEquals("VideoMediaPlayer is Paused", outputStreamCaptor.toString()
.trim());
}
}

View File

@ -13,4 +13,5 @@ This module contains articles about Java syntax
- [Introduction to Basic Syntax in Java](https://www.baeldung.com/java-syntax)
- [Java protected Access Modifier](https://www.baeldung.com/java-protected-access-modifier)
- [Using the Not Operator in If Conditions in Java](https://www.baeldung.com/java-using-not-in-if-conditions)
- [The for-each Loop in Java](https://www.baeldung.com/java-for-each-loop)
- [[<-- Prev]](/core-java-modules/core-java-lang-syntax)

View File

@ -0,0 +1,24 @@
package regex.array;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
class RegexMatches {
String[] regexMatch(String strSearch)
{
List<String> matchesList = new ArrayList<String>();
String stringToSearch = strSearch;
Pattern p1 = Pattern.compile("780{1}\\d{7}");
Matcher m1 = p1.matcher(stringToSearch);
while (m1.find())
{
matchesList.add(m1.group());
}
int sizeOfNewArray = matchesList.size();
String newArrayOfMatches[] = new String[sizeOfNewArray];
matchesList.toArray(newArrayOfMatches);
return newArrayOfMatches;
}
}

View File

@ -0,0 +1,33 @@
package regex.array;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import regex.array.RegexMatches;
class RegexMatchesUnitTest {
@Test
void whenFourNums_thenFourMatches() {
RegexMatches rm = new RegexMatches();
String actual[] = rm.regexMatch("7801111211fsdafasdfa 7802222222 sadfsadfsda7803333333 sadfdasfasd 7804444444");
assertArrayEquals(new String[] {"7801111211", "7802222222", "7803333333", "7804444444"}, actual, "success");
}
@Test
void whenThreeNums_thenThreeMatches() {
RegexMatches rm = new RegexMatches();
String actual[] = rm.regexMatch("7801111211fsdafasdfa 780222222 sadfsadfsda7803333333 sadfdasfasd 7804444444");
assertArrayEquals(new String[] {"7801111211", "7803333333", "7804444444"}, actual, "success");
}
@Test
void whenZeroNums_thenZeroMatches() {
RegexMatches rm = new RegexMatches();
String actual[] = rm.regexMatch("78011111fsdafasdfa 780222222 sadfsadfsda78033333 sadfdasfasd 7804444");
assertArrayEquals(new String[] {}, actual, "success");
}
}

View File

@ -0,0 +1,2 @@
### Relevant Articles:
- [Send a SOAP Object with Feign Client](https://www.baeldung.com/java-feign-send-soap)

View File

@ -12,7 +12,7 @@
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
<relativePath>../../pom.xml</relativePath>
</parent>
<repositories>
@ -36,51 +36,15 @@
<artifactId>graphql-java-annotations</artifactId>
<version>${graphql-java-annotations.version}</version>
</dependency>
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-core</artifactId>
<version>${ratpack-core.version}</version>
</dependency>
<dependency>
<groupId>com.github.americanexpress.nodes</groupId>
<artifactId>nodes</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>9.2</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-tools</artifactId>
<version>5.2.4</version>
<version>${graphql-java-tools.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java-servlet</artifactId>
<version>6.1.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>5.11.2</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>5.11.2</version>
<version>${graphql-java-servlet.version}</version>
</dependency>
<dependency>
<groupId>com.graphql-java-generator</groupId>
@ -88,15 +52,47 @@
<version>${graphql.java.generator.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-core</artifactId>
<version>${ratpack-core.version}</version>
</dependency>
<dependency>
<groupId>com.github.americanexpress.nodes</groupId>
<artifactId>nodes</artifactId>
<version>${nodes.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>${mockserver-netty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.22.0</version>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>${mockserver-client-java.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -115,11 +111,11 @@
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>10.0.7</version>
<version>${jetty-maven-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<version>${maven-war-plugin.version}</version>
</plugin>
<plugin>
<groupId>com.graphql-java-generator</groupId>
@ -143,12 +139,21 @@
</build>
<properties>
<graphql-java-tools.version>5.2.4</graphql-java-tools.version>
<graphql-java-servlet.version>6.1.3</graphql-java-servlet.version>
<graphql-java-annotations.version>3.0.3</graphql-java-annotations.version>
<ratpack-core.version>1.4.6</ratpack-core.version>
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
<graphql.java.generator.version>1.18</graphql.java.generator.version>
<ratpack-core.version>1.9.0</ratpack-core.version>
<nodes.version>0.5.0</nodes.version>
<httpclient.version>4.5.13</httpclient.version>
<mockserver-netty.version>5.13.2</mockserver-netty.version>
<mockserver-client-java.version>5.13.2</mockserver-client-java.version>
<jetty-maven-plugin.version>10.0.7</jetty-maven-plugin.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<graphql.java.generator.version>1.18</graphql.java.generator.version>
</properties>
</project>

View File

@ -19,24 +19,27 @@ import com.baeldung.graphql.utils.SchemaUtils;
import static ratpack.jackson.Jackson.json;
public class UserHandler implements Handler {
private static final Logger LOGGER = Logger.getLogger(UserHandler.class.getSimpleName());
private GraphQL graphql;
private static List<User> users = new ArrayList<>();
private static final List<User> USERS = new ArrayList<>();
private final GraphQL graphql;
public UserHandler() throws Exception {
graphql = new GraphQL(new UserSchema().getSchema());
graphql = GraphQL.newGraphQL(new UserSchema().getSchema()).build();
}
@Override
public void handle(Context context) throws Exception {
public void handle(Context context) {
context.parse(Map.class)
.then(payload -> {
Map<String, Object> parameters = (Map<String, Object>) payload.get("parameters");
ExecutionResult executionResult = graphql.execute(payload.get(SchemaUtils.QUERY)
.toString(), null, this, parameters);
Map<String, Object> result = new LinkedHashMap<>();
if (executionResult.getErrors()
.isEmpty()) {
if (executionResult.getErrors().isEmpty()) {
result.put(SchemaUtils.DATA, executionResult.getData());
} else {
result.put(SchemaUtils.ERRORS, executionResult.getErrors());
@ -46,8 +49,8 @@ public class UserHandler implements Handler {
});
}
public static List<User> getUsers() {
return users;
public List<User> getUsers() {
return USERS;
}
public static List<User> getUsers(DataFetchingEnvironment env) {

View File

@ -0,0 +1,3 @@
### Relevant Articles:
- [Getting Started With GraphQL SPQR and Spring Boot](https://www.baeldung.com/spring-boot-graphql-spqr)

View File

@ -12,4 +12,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Reading an HTTP Response Body as a String in Java](https://www.baeldung.com/java-http-response-body-as-string)
- [How To Get Cookies From the Apache HttpClient Response](https://www.baeldung.com/java-apache-httpclient-cookies)
- [Enabling Logging for Apache HttpClient](https://www.baeldung.com/apache-httpclient-enable-logging)
- [Expand Shortened URLs with Apache HttpClient](https://www.baeldung.com/apache-httpclient-expand-url)
- [Apache HttpClient vs. CloseableHttpClient](https://www.baeldung.com/apache-httpclient-vs-closeablehttpclient)
- More articles: [[<-- prev]](../httpclient)

View File

@ -15,6 +15,11 @@
</parent>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- http client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@ -50,6 +55,22 @@
<artifactId>spring-boot-starter-webflux</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>${mockserver.version}</version>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>${mockserver.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@ -74,8 +95,10 @@
</build>
<properties>
<assertj.version>3.22.0</assertj.version>
<mockserver.version>5.11.2</mockserver.version>
<httpclient.version>4.5.8</httpclient.version>
<httpclient5.version>5.1</httpclient5.version>
<httpclient5.version>5.1.3</httpclient5.version>
<maven.compiler.source.version>11</maven.compiler.source.version>
<maven.compiler.target.version>11</maven.compiler.target.version>
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>

View File

@ -1,4 +1,4 @@
package com.baeldung.httpclient.rare;
package com.baeldung.httpclient.expandurl;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
@ -22,35 +22,29 @@ import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
public class HttpClientUnshortenLiveTest {
public class HttpClientExpandUrlLiveTest {
private CloseableHttpClient client;
// fixtures
@Before
public final void before() {
client = HttpClientBuilder.create().disableRedirectHandling().build();
}
// tests
@Test
public final void givenShortenedOnce_whenUrlIsUnshortened_thenCorrectResult() throws IOException {
final String expectedResult = "http://www.baeldung.com/rest-versioning";
final String actualResult = expandSingleLevel("http://bit.ly/13jEoS1");
public final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expandSingleLevel("http://bit.ly/3LScTri");
assertThat(actualResult, equalTo(expectedResult));
}
@Test
public final void givenShortenedMultiple_whenUrlIsUnshortened_thenCorrectResult() throws IOException {
final String expectedResult = "http://www.baeldung.com/rest-versioning";
public final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException {
final String expectedResult = "https://www.baeldung.com/rest-versioning";
final String actualResult = expand("http://t.co/e4rDDbnzmk");
assertThat(actualResult, equalTo(expectedResult));
}
// API
private String expand(final String urlArg) throws IOException {
String originalUrl = urlArg;
String newUrl = expandSingleLevel(originalUrl);

View File

@ -0,0 +1,78 @@
package com.baeldung.httpclient.httpclient;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
class ApacheHttpClientUnitTest extends GetRequestMockServer {
@Test
void givenDeveloperUsedHttpClient_whenExecutingGetRequest_thenStatusIsOkButSonarReportsAnIssue() throws IOException {
HttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}
@Test
void givenDeveloperUsedCloseableHttpClient_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}
}
@Test
void givenDeveloperUsedHttpClientBuilder_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGet = new HttpGet(serviceOneUrl);
HttpResponse response = httpClient.execute(httpGet);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}
}
@Test
void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGet = new HttpGet(serviceOneUrl);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
assertThat(response.getCode()).isEqualTo(HttpStatus.SC_OK);
}
}
}
@Test
void givenDeveloperUsedSingleClient_whenExecutingTwoGetRequest_thenStatusIsOk() throws IOException {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpGet httpGetOne = new HttpGet(serviceOneUrl);
try (CloseableHttpResponse responseOne = httpClient.execute(httpGetOne)) {
HttpEntity entityOne = responseOne.getEntity();
EntityUtils.consume(entityOne);
assertThat(responseOne.getCode()).isEqualTo(HttpStatus.SC_OK);
}
HttpGet httpGetTwo = new HttpGet(serviceTwoUrl);
try (CloseableHttpResponse responseTwo = httpClient.execute(httpGetTwo)) {
HttpEntity entityTwo = responseTwo.getEntity();
EntityUtils.consume(entityTwo);
assertThat(responseTwo.getCode()).isEqualTo(HttpStatus.SC_OK);
}
}
}
}

View File

@ -0,0 +1,78 @@
package com.baeldung.httpclient.httpclient;
import org.apache.hc.core5.http.HttpStatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockserver.client.MockServerClient;
import org.mockserver.integration.ClientAndServer;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URISyntaxException;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.matchers.Times.exactly;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
public class GetRequestMockServer {
public static ClientAndServer mockServer;
public static String serviceOneUrl;
public static String serviceTwoUrl;
private static int serverPort;
public static final String SERVER_ADDRESS = "127.0.0.1";
public static final String PATH_ONE = "/test1";
public static final String PATH_TWO = "/test2";
public static final String METHOD = "GET";
@BeforeAll
static void startServer() throws IOException, URISyntaxException {
serverPort = getFreePort();
serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE;
serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO;
mockServer = startClientAndServer(serverPort);
mockGetRequest();
}
@AfterAll
static void stopServer() {
mockServer.stop();
}
private static void mockGetRequest() {
new MockServerClient(SERVER_ADDRESS, serverPort)
.when(
request()
.withPath(PATH_ONE)
.withMethod(METHOD),
exactly(5)
)
.respond(
response()
.withStatusCode(HttpStatus.SC_OK)
.withBody("{\"status\":\"ok\"}")
);
new MockServerClient(SERVER_ADDRESS, serverPort)
.when(
request()
.withPath(PATH_TWO)
.withMethod(METHOD),
exactly(1)
)
.respond(
response()
.withStatusCode(HttpStatus.SC_OK)
.withBody("{\"status\":\"ok\"}")
);
}
private static int getFreePort () throws IOException {
try (ServerSocket serverSocket = new ServerSocket(0)) {
return serverSocket.getLocalPort();
}
}
}

View File

@ -4,14 +4,14 @@ This module contains articles about HTTPClient that are part of the HTTPClient E
### Relevant Articles
- [HttpClient 4 Get the Status Code](https://www.baeldung.com/httpclient-status-code)
- [HttpClient with SSL](https://www.baeldung.com/httpclient-ssl)
- [HttpClient Timeout](https://www.baeldung.com/httpclient-timeout)
- [HttpClient 4 Send Custom Cookie](https://www.baeldung.com/httpclient-4-cookies)
- [Custom HTTP Header with the HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
- [HttpClient Basic Authentication](https://www.baeldung.com/httpclient-4-basic-authentication)
- [Posting with HttpClient](https://www.baeldung.com/httpclient-post-http-request)
- [Adding Parameters to HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters)
- [Apache HttpClient Get the Status Code](https://www.baeldung.com/httpclient-status-code)
- [Apache HttpClient with SSL](https://www.baeldung.com/httpclient-ssl)
- [Apache HttpClient Timeout](https://www.baeldung.com/httpclient-timeout)
- [Apache HttpClient Send Custom Cookie](https://www.baeldung.com/httpclient-cookies)
- [Custom HTTP Header with the Apache HttpClient](https://www.baeldung.com/httpclient-custom-http-header)
- [Apache HttpClient Basic Authentication](https://www.baeldung.com/httpclient-basic-authentication)
- [Posting with Apache HttpClient](https://www.baeldung.com/httpclient-post-http-request)
- [Adding Parameters to Apache HttpClient Requests](https://www.baeldung.com/apache-httpclient-parameters)
### Running the Tests

View File

@ -7,16 +7,14 @@ This module contains articles about HttpClient 4.x
The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles:
- [HttpClient 4 Cancel Request](https://www.baeldung.com/httpclient-cancel-request)
- [HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4)
- [Unshorten URLs with HttpClient](https://www.baeldung.com/unshorten-url-httpclient)
- [HttpClient 4 Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post)
- [Multipart Upload with HttpClient 4](https://www.baeldung.com/httpclient-multipart-upload)
- [HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial)
- [HttpClient 4 Tutorial](https://www.baeldung.com/httpclient-guide)
- [Apache HttpClient Cancel Request](https://www.baeldung.com/httpclient-cancel-request)
- [Apache HttpClient 4 Cookbook](https://www.baeldung.com/httpclient4)
- [Apache HttpClient Follow Redirects for POST](https://www.baeldung.com/httpclient-redirect-on-http-post)
- [Multipart Upload with Apache HttpClient](https://www.baeldung.com/httpclient-multipart-upload)
- [Apache HttpAsyncClient Tutorial](https://www.baeldung.com/httpasyncclient-tutorial)
- [Apache HttpClient Tutorial](https://www.baeldung.com/httpclient-guide)
- [Advanced HttpClient Configuration](https://www.baeldung.com/httpclient-advanced-config)
- [HttpClient 4 Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect)
- [Custom User-Agent in HttpClient 4](https://www.baeldung.com/httpclient-user-agent-header)
- [Apache HttpClient Do Not Follow Redirects](https://www.baeldung.com/httpclient-stop-follow-redirect)
- [Custom User-Agent in Apache HttpClient](https://www.baeldung.com/httpclient-user-agent-header)
- [Apache HttpClient Connection Management](https://www.baeldung.com/httpclient-connection-management)
- More articles: [[next -->]](../httpclient-2)

View File

@ -15,12 +15,6 @@
</parent>
<dependencies>
<!-- utils -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<!-- http client -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>

View File

@ -1,6 +0,0 @@
## Immutables
This module contains articles about the Immutables library.
### Relevant Articles:
- [Introduction to Immutables](https://www.baeldung.com/immutables)

View File

@ -1,34 +0,0 @@
<?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>immutables</artifactId>
<name>immutables</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>${immutables.version}</version>
</dependency>
<dependency>
<groupId>org.mutabilitydetector</groupId>
<artifactId>MutabilityDetector</artifactId>
<version>${mutabilitydetector.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<immutables.version>2.5.6</immutables.version>
<mutabilitydetector.version>0.9.6</mutabilitydetector.version>
</properties>
</project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -5,3 +5,4 @@
- [Determine if an Integers Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
- [Guide to Java BigInteger](https://www.baeldung.com/java-biginteger)
- [Automorphic Numbers in Java](https://www.baeldung.com/java-automorphic-numbers)
- [Convert Byte Size Into a Human-Readable Format in Java](https://www.baeldung.com/java-human-readable-byte-size)

View File

@ -0,0 +1,81 @@
package com.baeldung.humanreadablebytes;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class FileSizeFormatUtil {
private static final long BYTE = 1L;
private static final long KB = BYTE << 10;
private static final long MB = KB << 10;
private static final long GB = MB << 10;
private static final long TB = GB << 10;
private static final long PB = TB << 10;
private static final long EB = PB << 10;
private static final DecimalFormat DEC_FORMAT = new DecimalFormat("#.##");
public static String toHumanReadable(long size) {
if (size < 0)
throw new IllegalArgumentException("Invalid file size: " + size);
if (size >= EB) return formatSize(size, EB, "EB");
if (size >= PB) return formatSize(size, PB, "PB");
if (size >= TB) return formatSize(size, TB, "TB");
if (size >= GB) return formatSize(size, GB, "GB");
if (size >= MB) return formatSize(size, MB, "MB");
if (size >= KB) return formatSize(size, KB, "KB");
return formatSize(size, BYTE, "Bytes");
}
private static String formatSize(long size, long divider, String unitName) {
return DEC_FORMAT.format((double) size / divider) + " " + unitName;
}
public static String toHumanReadableWithEnum(long size) {
final List<SizeUnit> units = SizeUnit.unitsInDescending();
if (size < 0)
throw new IllegalArgumentException("Invalid file size: " + size);
String result = null;
for (SizeUnit unit : units) {
if (size >= unit.getUnitBase()) {
result = formatSize(size, unit.getUnitBase(), unit.name());
break;
}
}
return result == null ? formatSize(size, SizeUnit.Bytes.getUnitBase(), SizeUnit.Bytes.name()) : result;
}
public static String toHumanReadableByNumOfLeadingZeros(long size) {
if (size < 0)
throw new IllegalArgumentException("Invalid file size: " + size);
if (size < 1024) return size + " Bytes";
int unitIdx = (63 - Long.numberOfLeadingZeros(size)) / 10;
return formatSize(size, 1L << (unitIdx * 10), " KMGTPE".charAt(unitIdx) + "B");
}
enum SizeUnit {
Bytes(1L),
KB(Bytes.unitBase << 10),
MB(KB.unitBase << 10),
GB(MB.unitBase << 10),
TB(GB.unitBase << 10),
PB(TB.unitBase << 10),
EB(PB.unitBase << 10);
private final Long unitBase;
public static List<SizeUnit> unitsInDescending() {
List<SizeUnit> list = Arrays.asList(values());
Collections.reverse(list);
return list;
}
public Long getUnitBase() {
return unitBase;
}
SizeUnit(long unitBase) {
this.unitBase = unitBase;
}
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.humanreadablebytes;
import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class FileSizeFormatUtilUnitTest {
private final static Map<Long, String> DATA_MAP = new HashMap<Long, String>() {{
put(0L, "0 Bytes");
put(1023L, "1023 Bytes");
put(1024L, "1 KB");
put(12_345L, "12.06 KB");
put(10_123_456L, "9.65 MB");
put(10_123_456_798L, "9.43 GB");
put(1_777_777_777_777_777_777L, "1.54 EB");
}};
@Test
public void givenBytes_whenCalltoHumanReadableMethod_thenGetExpectedResults() {
DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadable(in)));
}
@Test
public void givenBytes_whenCalltoHumanReadableWithEnumMethod_thenGetExpectedResults() {
DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableWithEnum(in)));
}
@Test
public void givenBytes_whenCalltoHumanReadableByLeadingZeros_thenGetExpectedResults() {
DATA_MAP.forEach((in, expected) -> Assert.assertEquals(expected, FileSizeFormatUtil.toHumanReadableByNumOfLeadingZeros(in)));
}
@Test
public void givenBytes_whenCalltoHumanReadableByFileUtils_thenOutputExpectedResults() {
DATA_MAP.forEach((in, expected) -> System.out.println(in + " bytes -> " + FileUtils.byteCountToDisplaySize(in)));
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.jersey.exceptionhandling;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.IllegalArgumentExceptionMapper;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.ServerExceptionMapper;
@ApplicationPath("/exception-handling/*")
public class ExceptionHandlingConfig extends ResourceConfig {
public ExceptionHandlingConfig() {
packages("com.baeldung.jersey.exceptionhandling.rest");
register(IllegalArgumentExceptionMapper.class);
register(ServerExceptionMapper.class);
}
}

View File

@ -0,0 +1,33 @@
package com.baeldung.jersey.exceptionhandling.data;
import com.baeldung.jersey.exceptionhandling.repo.Identifiable;
public class Stock implements Identifiable {
private static final long serialVersionUID = 1L;
private String id;
private Double price;
public Stock() {
}
public Stock(String id, Double price) {
this.id = id;
this.price = price;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.jersey.exceptionhandling.data;
import com.baeldung.jersey.exceptionhandling.repo.Identifiable;
public class Wallet implements Identifiable {
private static final long serialVersionUID = 1L;
public static final Double MIN_CHARGE = 50.0;
public static final String MIN_CHARGE_MSG = "minimum charge is: " + MIN_CHARGE;
private String id;
private Double balance = 0.0;
public Wallet() {
}
public Wallet(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public Double addBalance(Double amount) {
if (balance == null)
balance = 0.0;
return balance += amount;
}
public boolean hasFunds(Double amount) {
if (balance == null || amount == null) {
return false;
}
return (balance - amount) >= 0;
}
}

View File

@ -0,0 +1,32 @@
package com.baeldung.jersey.exceptionhandling.repo;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public class Db<T extends Identifiable> {
private Map<String, T> db = new HashMap<>();
public Optional<T> findById(String id) {
return Optional.ofNullable(db.get(id));
}
public String save(T t) {
String id = t.getId();
if (id == null) {
id = UUID.randomUUID()
.toString();
t.setId(id);
}
db.put(id, t);
return id;
}
public void remove(T t) {
db.entrySet()
.removeIf(entry -> entry.getValue()
.getId()
.equals(t.getId()));
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.jersey.exceptionhandling.repo;
import java.io.Serializable;
public interface Identifiable extends Serializable {
void setId(String id);
String getId();
public static void assertValid(Identifiable i) {
if (i == null)
throw new IllegalArgumentException("object cannot be null");
if (i.getId() == null)
throw new IllegalArgumentException("object id cannot be null");
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.jersey.exceptionhandling.rest;
import java.util.Optional;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.baeldung.jersey.exceptionhandling.data.Stock;
import com.baeldung.jersey.exceptionhandling.repo.Db;
import com.baeldung.jersey.exceptionhandling.service.Repository;
@Path("/stocks")
public class StocksResource {
private static final Db<Stock> stocks = Repository.STOCKS_DB;
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response post(Stock stock) {
stocks.save(stock);
return Response.ok(stock)
.build();
}
@GET
@Path("/{ticker}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("ticker") String id) {
Optional<Stock> stock = stocks.findById(id);
stock.orElseThrow(IllegalArgumentException::new);
return Response.ok(stock.get())
.build();
}
}

View File

@ -0,0 +1,98 @@
package com.baeldung.jersey.exceptionhandling.rest;
import java.util.Optional;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import com.baeldung.jersey.exceptionhandling.data.Stock;
import com.baeldung.jersey.exceptionhandling.data.Wallet;
import com.baeldung.jersey.exceptionhandling.repo.Db;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.InvalidTradeException;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.RestErrorResponse;
import com.baeldung.jersey.exceptionhandling.service.Repository;
@Path("/wallets")
public class WalletsResource {
private static final Db<Stock> stocks = Repository.STOCKS_DB;
private static final Db<Wallet> wallets = Repository.WALLETS_DB;
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response post(Wallet wallet) {
wallets.save(wallet);
return Response.ok(wallet)
.build();
}
@GET
@Path("/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("id") String id) {
Optional<Wallet> wallet = wallets.findById(id);
wallet.orElseThrow(IllegalArgumentException::new);
return Response.ok(wallet.get())
.build();
}
@PUT
@Path("/{id}/{amount}")
@Produces(MediaType.APPLICATION_JSON)
public Response putAmount(@PathParam("id") String id, @PathParam("amount") Double amount) {
Optional<Wallet> wallet = wallets.findById(id);
wallet.orElseThrow(IllegalArgumentException::new);
if (amount < Wallet.MIN_CHARGE) {
throw new InvalidTradeException(Wallet.MIN_CHARGE_MSG);
}
wallet.get()
.addBalance(amount);
wallets.save(wallet.get());
return Response.ok(wallet)
.build();
}
@POST
@Path("/{wallet}/buy/{ticker}")
@Produces(MediaType.APPLICATION_JSON)
public Response postBuyStock(@PathParam("wallet") String walletId, @PathParam("ticker") String id) {
Optional<Stock> stock = stocks.findById(id);
stock.orElseThrow(InvalidTradeException::new);
Optional<Wallet> w = wallets.findById(walletId);
w.orElseThrow(InvalidTradeException::new);
Wallet wallet = w.get();
Double price = stock.get()
.getPrice();
if (!wallet.hasFunds(price)) {
RestErrorResponse response = new RestErrorResponse();
response.setSubject(wallet);
response.setMessage("insufficient balance");
throw new WebApplicationException(Response.status(Status.NOT_ACCEPTABLE)
.entity(response)
.build());
}
wallet.addBalance(-price);
wallets.save(wallet);
return Response.ok(wallet)
.build();
}
}

View File

@ -0,0 +1,23 @@
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {
public static final String DEFAULT_MESSAGE = "an illegal argument was provided";
@Override
public Response toResponse(final IllegalArgumentException exception) {
return Response.status(Response.Status.EXPECTATION_FAILED)
.entity(build(exception.getMessage()))
.type(MediaType.APPLICATION_JSON)
.build();
}
private RestErrorResponse build(String message) {
RestErrorResponse response = new RestErrorResponse();
response.setMessage(DEFAULT_MESSAGE + ": " + message);
return response;
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
public class InvalidTradeException extends WebApplicationException {
private static final long serialVersionUID = 1L;
private static final String MESSAGE = "invalid trade operation";
public InvalidTradeException() {
super(MESSAGE, Response.Status.NOT_ACCEPTABLE);
}
public InvalidTradeException(String detail) {
super(MESSAGE + ": " + detail, Response.Status.NOT_ACCEPTABLE);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
public class RestErrorResponse {
private Object subject;
private String message;
public RestErrorResponse() {
}
public RestErrorResponse(String message) {
this.message = message;
}
public RestErrorResponse(Object subject, String message) {
this.subject = subject;
this.message = message;
}
public Object getSubject() {
return subject;
}
public void setSubject(Object subject) {
this.subject = subject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,35 @@
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
public class ServerExceptionMapper implements ExceptionMapper<WebApplicationException> {
public static final String HTTP_405_MESSAGE = "METHOD_NOT_ALLOWED";
@Override
public Response toResponse(final WebApplicationException exception) {
String message = exception.getMessage();
Response response = exception.getResponse();
Status status = response.getStatusInfo()
.toEnum();
switch (status) {
case METHOD_NOT_ALLOWED:
message = HTTP_405_MESSAGE;
break;
case INTERNAL_SERVER_ERROR:
message = "internal validation - " + exception;
break;
default:
message = "[unhandled response code] " + exception;
}
return Response.status(status)
.entity(status + ": " + message)
.type(MediaType.TEXT_PLAIN)
.build();
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.jersey.exceptionhandling.service;
import com.baeldung.jersey.exceptionhandling.data.Stock;
import com.baeldung.jersey.exceptionhandling.data.Wallet;
import com.baeldung.jersey.exceptionhandling.repo.Db;
public class Repository {
public static Db<Stock> STOCKS_DB = new Db<>();
public static Db<Wallet> WALLETS_DB = new Db<>();
}

View File

@ -0,0 +1,99 @@
package com.baeldung.jersey.exceptionhandling.rest;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import com.baeldung.jersey.exceptionhandling.ExceptionHandlingConfig;
import com.baeldung.jersey.exceptionhandling.data.Stock;
import com.baeldung.jersey.exceptionhandling.data.Wallet;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.IllegalArgumentExceptionMapper;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.RestErrorResponse;
import com.baeldung.jersey.exceptionhandling.rest.exceptions.ServerExceptionMapper;
public class StocksResourceIntegrationTest extends JerseyTest {
private static final Entity<String> EMPTY_BODY = Entity.json("");
private static final Stock STOCK = new Stock("BAEL", 51.57);
private static final String MY_WALLET = "MY-WALLET";
private static final Wallet WALLET = new Wallet(MY_WALLET);
private static final int INSUFFICIENT_AMOUNT = (int) (Wallet.MIN_CHARGE - 1);
@Override
protected Application configure() {
return new ExceptionHandlingConfig();
}
private Invocation.Builder stocks(String path) {
return target("/stocks" + path).request();
}
private Invocation.Builder wallets(String path, Object... args) {
return target("/wallets" + String.format(path, args)).request();
}
private Entity<?> entity(Object object) {
return Entity.entity(object, MediaType.APPLICATION_JSON_TYPE);
}
@Test
public void whenMethodNotAllowed_thenCustomMessage() {
Response response = stocks("").get();
assertEquals(Status.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatus());
String content = response.readEntity(String.class);
assertThat(content, containsString(ServerExceptionMapper.HTTP_405_MESSAGE));
}
@Test
public void whenTickerNotExists_thenRestErrorResponse() {
Response response = stocks("/UNDEFINED").get();
assertEquals(Status.EXPECTATION_FAILED.getStatusCode(), response.getStatus());
RestErrorResponse content = response.readEntity(RestErrorResponse.class);
assertThat(content.getMessage(), startsWith(IllegalArgumentExceptionMapper.DEFAULT_MESSAGE));
}
@Test
public void givenAmountLessThanMinimum_whenAddingToWallet_thenInvalidTradeException() {
wallets("").post(entity(WALLET));
Response response = wallets("/%s/%d", MY_WALLET, INSUFFICIENT_AMOUNT).put(EMPTY_BODY);
assertEquals(Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
String content = response.readEntity(String.class);
assertThat(content, containsString(Wallet.MIN_CHARGE_MSG));
}
@Test
public void givenInsifficientFunds_whenBuyingStock_thenWebApplicationException() {
stocks("").post(entity(STOCK));
wallets("").post(entity(WALLET));
Response response = wallets("/%s/buy/%s", MY_WALLET, STOCK.getId()).post(EMPTY_BODY);
assertEquals(Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
RestErrorResponse content = response.readEntity(RestErrorResponse.class);
assertNotNull(content.getSubject());
HashMap<?, ?> subject = (HashMap<?, ?>) content.getSubject();
assertEquals(subject.get("id"), WALLET.getId());
assertTrue(WALLET.getBalance() < Wallet.MIN_CHARGE);
}
}

View File

@ -53,3 +53,4 @@ Enjoy it :)
- [Intro to Performance Testing using JMeter](https://www.baeldung.com/jmeter)
- [Configure Jenkins to Run and Show JMeter Tests](https://www.baeldung.com/ops/jenkins-and-jmeter)
- [Write Extracted Data to a File Using JMeter](https://www.baeldung.com/jmeter-write-to-file)
- [Basic Authentication in JMeter](https://www.baeldung.com/jmeter-basic-auth)

View File

@ -33,6 +33,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,52 @@
package com.baeldung.configuration;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.inMemoryAuthentication()
.withUser("admin").password(encoder.encode("admin")).roles("USER", "ADMIN")
.and()
.withUser("user1").password(encoder.encode("password1")).roles("USER")
.and()
.withUser("user2").password(encoder.encode("password2")).roles("USER")
.and()
.withUser("user3").password(encoder.encode("password3")).roles("USER")
.and()
.withUser("user4").password(encoder.encode("password4")).roles("USER")
.and()
.withUser("user5").password(encoder.encode("password5")).roles("USER")
.and()
.withUser("user6").password(encoder.encode("password6")).roles("USER")
.and()
.withUser("user7").password(encoder.encode("password7")).roles("USER")
.and()
.withUser("user8").password(encoder.encode("password8")).roles("USER")
.and()
.withUser("user9").password(encoder.encode("password9")).roles("USER")
.and()
.withUser("user10").password(encoder.encode("password10")).roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/secured/**").authenticated()
.anyRequest().permitAll()
.and()
.httpBasic();
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.controller;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baeldung.model.Response;
@RestController
public class SecuredUuidController {
private static final Logger LOGGER = LoggerFactory.getLogger(SecuredUuidController.class);
@GetMapping("/secured/uuid")
public Response uuid() {
LOGGER.info("Returning response");
return new Response(String.format("Secured test message... %s.", UUID.randomUUID()));
}
}

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">localhost</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<stringProp name="Argument.desc">Host of Webservice</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">8080</stringProp>
<stringProp name="Argument.desc">Port of web server</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="username" elementType="Argument">
<stringProp name="Argument.name">username</stringProp>
<stringProp name="Argument.value">user1</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="password" elementType="Argument">
<stringProp name="Argument.name">password</stringProp>
<stringProp name="Argument.value">password1</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Number of Users" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<longProp name="ThreadGroup.start_time">1375525852000</longProp>
<longProp name="ThreadGroup.end_time">1375525852000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Soap Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port">${port}</stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/secured/uuid</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">false</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">false</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<JSR223PreProcessor guiclass="TestBeanGUI" testclass="JSR223PreProcessor" testname="JSR223 PreProcessor" enabled="true">
<stringProp name="cacheKey">false</stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="script">import org.apache.commons.codec.binary.Base64;
String username = vars.get(&quot;username&quot;);
String password = vars.get(&quot;password&quot;);
String credentials = username + &quot;:&quot; + password;
byte[] encodedUsernamePassword = Base64.encodeBase64(credentials.getBytes());
vars.put(&quot;base64Credentials&quot;, new String(encodedUsernamePassword));
</stringProp>
<stringProp name="scriptLanguage">java</stringProp>
</JSR223PreProcessor>
<hashTree/>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">text/xml; charset=utf-8</stringProp>
</elementProp>
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Authorization</stringProp>
<stringProp name="Header.value">basic ${base64Credentials}</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="HTTP 200 Status" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="49586">200</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">8</intProp>
</ResponseAssertion>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response content assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="1645228770">Secured test message...</stringProp>
</collectionProp>
<stringProp name="TestPlan.comments">Verify content in response</stringProp>
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">16</intProp>
<stringProp name="Assertion.custom_message"></stringProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

View File

@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">localhost</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<stringProp name="Argument.desc">Host of Webservice</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">8080</stringProp>
<stringProp name="Argument.desc">Port of web server</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="csvFileLocation" elementType="Argument">
<stringProp name="Argument.name">csvFileLocation</stringProp>
<stringProp name="Argument.value">D:\\work\\credentials.csv</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">text/xml; charset=utf-8</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Number of Users" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">20</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">0</stringProp>
<longProp name="ThreadGroup.start_time">1375525852000</longProp>
<longProp name="ThreadGroup.end_time">1375525852000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
</ThreadGroup>
<hashTree>
<CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV Data Set Config" enabled="true">
<stringProp name="delimiter">,</stringProp>
<stringProp name="fileEncoding"></stringProp>
<stringProp name="filename">${csvFileLocation}</stringProp>
<boolProp name="ignoreFirstLine">false</boolProp>
<boolProp name="quotedData">false</boolProp>
<boolProp name="recycle">true</boolProp>
<stringProp name="shareMode">shareMode.all</stringProp>
<boolProp name="stopThread">false</boolProp>
<stringProp name="variableNames">username,password</stringProp>
</CSVDataSet>
<hashTree/>
<AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true">
<collectionProp name="AuthManager.auth_list">
<elementProp name="" elementType="Authorization">
<stringProp name="Authorization.url">http://${host}:${port}/secured/uuid</stringProp>
<stringProp name="Authorization.username">${username}</stringProp>
<stringProp name="Authorization.password">${password}</stringProp>
<stringProp name="Authorization.domain"></stringProp>
<stringProp name="Authorization.realm"></stringProp>
</elementProp>
</collectionProp>
<boolProp name="AuthManager.controlledByThreadGroup">false</boolProp>
<boolProp name="AuthManager.clearEachIteration">true</boolProp>
</AuthManager>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Soap Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port">${port}</stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/secured/uuid</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">false</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">false</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="HTTP 200 Status" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="49586">200</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">8</intProp>
</ResponseAssertion>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response content assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="1645228770">Secured test message...</stringProp>
</collectionProp>
<stringProp name="TestPlan.comments">Verify content in response</stringProp>
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">16</intProp>
<stringProp name="Assertion.custom_message"></stringProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

View File

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">localhost</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<stringProp name="Argument.desc">Host of Webservice</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">8080</stringProp>
<stringProp name="Argument.desc">Port of web server</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="username" elementType="Argument">
<stringProp name="Argument.name">username</stringProp>
<stringProp name="Argument.value">user1</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
<elementProp name="password" elementType="Argument">
<stringProp name="Argument.name">password</stringProp>
<stringProp name="Argument.value">password1</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">text/xml; charset=utf-8</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Number of Users" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">1</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">0</stringProp>
<longProp name="ThreadGroup.start_time">1375525852000</longProp>
<longProp name="ThreadGroup.end_time">1375525852000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
</ThreadGroup>
<hashTree>
<AuthManager guiclass="AuthPanel" testclass="AuthManager" testname="HTTP Authorization Manager" enabled="true">
<collectionProp name="AuthManager.auth_list">
<elementProp name="" elementType="Authorization">
<stringProp name="Authorization.url">http://${host}:${port}/secured/uuid</stringProp>
<stringProp name="Authorization.username">${username}</stringProp>
<stringProp name="Authorization.password">${password}</stringProp>
<stringProp name="Authorization.domain"></stringProp>
<stringProp name="Authorization.realm"></stringProp>
</elementProp>
</collectionProp>
<boolProp name="AuthManager.controlledByThreadGroup">false</boolProp>
<boolProp name="AuthManager.clearEachIteration">true</boolProp>
</AuthManager>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Soap Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port">${port}</stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/secured/uuid</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">false</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">false</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="HTTP 200 Status" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="49586">200</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">8</intProp>
</ResponseAssertion>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response content assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="1645228770">Secured test message...</stringProp>
</collectionProp>
<stringProp name="TestPlan.comments">Verify content in response</stringProp>
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">16</intProp>
<stringProp name="Assertion.custom_message"></stringProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<Arguments guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="host" elementType="Argument">
<stringProp name="Argument.name">host</stringProp>
<stringProp name="Argument.value">localhost</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<stringProp name="Argument.desc">Host of Webservice</stringProp>
</elementProp>
<elementProp name="port" elementType="Argument">
<stringProp name="Argument.name">port</stringProp>
<stringProp name="Argument.value">8080</stringProp>
<stringProp name="Argument.desc">Port of web server</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</Arguments>
<hashTree/>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Number of Users" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">2</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">5</stringProp>
<stringProp name="ThreadGroup.ramp_time">5</stringProp>
<longProp name="ThreadGroup.start_time">1375525852000</longProp>
<longProp name="ThreadGroup.end_time">1375525852000</longProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
</ThreadGroup>
<hashTree>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Soap Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments"/>
</elementProp>
<stringProp name="HTTPSampler.domain">${host}</stringProp>
<stringProp name="HTTPSampler.port">${port}</stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/secured/uuid</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">false</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">false</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree>
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
<collectionProp name="HeaderManager.headers">
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Content-Type</stringProp>
<stringProp name="Header.value">text/xml; charset=utf-8</stringProp>
</elementProp>
<elementProp name="" elementType="Header">
<stringProp name="Header.name">Authorization</stringProp>
<stringProp name="Header.value">dXNlcjE6cGFzc3dvcmQx</stringProp>
</elementProp>
</collectionProp>
</HeaderManager>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="HTTP 200 Status" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="49586">200</stringProp>
</collectionProp>
<stringProp name="Assertion.custom_message"></stringProp>
<stringProp name="Assertion.test_field">Assertion.response_code</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">8</intProp>
</ResponseAssertion>
<hashTree/>
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response content assertion" enabled="true">
<collectionProp name="Asserion.test_strings">
<stringProp name="1645228770">Secured test message...</stringProp>
</collectionProp>
<stringProp name="TestPlan.comments">Verify content in response</stringProp>
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
<boolProp name="Assertion.assume_success">false</boolProp>
<intProp name="Assertion.test_type">16</intProp>
<stringProp name="Assertion.custom_message"></stringProp>
</ResponseAssertion>
<hashTree/>
</hashTree>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>true</message>
<threadName>true</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>false</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>false</responseHeaders>
<requestHeaders>false</requestHeaders>
<responseDataOnError>true</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>0</assertionsResultsToSave>
<bytes>true</bytes>
<hostname>true</hostname>
<threadCounts>true</threadCounts>
<sampleCount>true</sampleCount>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>

View File

@ -0,0 +1,10 @@
user1,password1
user2,password2
user3,password3
user4,password4
user5,password5
user6,password6
user7,password7
user8,password8
user9,password9
user10,password10
1 user1 password1
2 user2 password2
3 user3 password3
4 user4 password4
5 user5 password5
6 user6 password6
7 user7 password7
8 user8 password8
9 user9 password9
10 user10 password10

View File

@ -1,6 +0,0 @@
## JTA
This module contains articles about the Java Transaction API (JTA).
### Relevant Articles:
- [Guide to Jakarta EE JTA](https://www.baeldung.com/jee-jta)

View File

@ -1,55 +0,0 @@
<?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>jta</artifactId>
<version>1.0-SNAPSHOT</version>
<name>jta</name>
<packaging>jar</packaging>
<description>JEE JTA demo</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>${log4j2.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-bitronix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
</dependencies>
<properties>
<spring-boot.version>2.4.7</spring-boot.version>
<log4j2.version>2.17.1</log4j2.version>
</properties>
</project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="15 seconds" debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{ISO8601}]-[%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@ -16,4 +16,6 @@ Remember, for advanced libraries like [Jackson](/jackson) and [JUnit](/testing-m
- [Introduction to Takes](https://www.baeldung.com/java-takes)
- [Using NullAway to Avoid NullPointerExceptions](https://www.baeldung.com/java-nullaway)
- [Introduction to Alibaba Arthas](https://www.baeldung.com/java-alibaba-arthas-intro)
- More articles [[<-- prev]](/libraries-2) [[next -->]](/libraries-4)
- [Introduction to Structurizr](https://www.baeldung.com/structurizr)
- [Introduction to Immutables](https://www.baeldung.com/immutables)
- More articles [[<-- prev]](../libraries-2) [[next -->]](../libraries-4)

View File

@ -86,6 +86,43 @@
<artifactId>error_prone_core</artifactId>
<version>${errorprone.version}</version>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-core</artifactId>
<version>${structurizr.version}</version>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-spring</artifactId>
<version>${structurizr.version}</version>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-client</artifactId>
<version>${structurizr.version}</version>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-analysis</artifactId>
<version>${structurizr.version}</version>
</dependency>
<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-plantuml</artifactId>
<version>${structurizr.version}</version>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>${immutables.version}</version>
</dependency>
<dependency>
<groupId>org.mutabilitydetector</groupId>
<artifactId>MutabilityDetector</artifactId>
<version>${mutabilitydetector.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
@ -140,7 +177,7 @@
</path>
</annotationProcessorPaths>
<compilerArgs>
<!-- NullAway will warn by default, uncomment the next line to make the build
<!-- NullAway will warn by default, uncomment the next line to make the build
fail -->
<!-- <arg>-Xep:NullAway:ERROR</arg> -->
<arg>-XepExcludedPaths:(.*)/test/.*|(.*)/jcabi/.*</arg>
@ -153,7 +190,7 @@
<artifactId>plexus-compiler-javac-errorprone</artifactId>
<version>2.8</version>
</dependency>
<!-- override plexus-compiler-javac-errorprone's dependency on Error Prone with the
<!-- override plexus-compiler-javac-errorprone's dependency on Error Prone with the
latest version -->
<dependency>
<groupId>com.google.errorprone</groupId>
@ -229,6 +266,9 @@
<nullaway.version>0.3.0</nullaway.version>
<plexus-compiler.version>2.8</plexus-compiler.version>
<errorprone.version>2.1.3</errorprone.version>
<structurizr.version>1.0.0</structurizr.version>
<immutables.version>2.5.6</immutables.version>
<mutabilitydetector.version>0.9.6</mutabilitydetector.version>
</properties>
</project>

Some files were not shown because too many files have changed in this diff Show More