Merge remote-tracking branch 'refs/remotes/eugenp/master'
This commit is contained in:
commit
e65b813aa7
1
algorithms/.gitignore
vendored
Normal file
1
algorithms/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target/
|
@ -4,3 +4,4 @@
|
|||||||
- [Introduction to Cobertura](http://www.baeldung.com/cobertura)
|
- [Introduction to Cobertura](http://www.baeldung.com/cobertura)
|
||||||
- [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization)
|
- [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization)
|
||||||
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java)
|
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/finite-automata-java)
|
||||||
|
- [Introduction to Jenetics Library](http://www.baeldung.com/jenetics)
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jenetics</groupId>
|
||||||
|
<artifactId>jenetics</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import static org.jenetics.engine.EvolutionResult.toBestPhenotype;
|
||||||
|
import static org.jenetics.engine.limit.bySteadyFitness;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.jenetics.BitChromosome;
|
||||||
|
import org.jenetics.BitGene;
|
||||||
|
import org.jenetics.Mutator;
|
||||||
|
import org.jenetics.Phenotype;
|
||||||
|
import org.jenetics.RouletteWheelSelector;
|
||||||
|
import org.jenetics.SinglePointCrossover;
|
||||||
|
import org.jenetics.TournamentSelector;
|
||||||
|
import org.jenetics.engine.Engine;
|
||||||
|
import org.jenetics.engine.EvolutionStatistics;
|
||||||
|
|
||||||
|
//The main class.
|
||||||
|
public class Knapsack {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int nItems = 15;
|
||||||
|
double ksSize = nItems * 100.0 / 3.0;
|
||||||
|
|
||||||
|
KnapsackFF ff = new KnapsackFF(Stream.generate(KnapsackItem::random)
|
||||||
|
.limit(nItems)
|
||||||
|
.toArray(KnapsackItem[]::new), ksSize);
|
||||||
|
|
||||||
|
Engine<BitGene, Double> engine = Engine.builder(ff, BitChromosome.of(nItems, 0.5))
|
||||||
|
.populationSize(500)
|
||||||
|
.survivorsSelector(new TournamentSelector<>(5))
|
||||||
|
.offspringSelector(new RouletteWheelSelector<>())
|
||||||
|
.alterers(new Mutator<>(0.115), new SinglePointCrossover<>(0.16))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
|
||||||
|
|
||||||
|
Phenotype<BitGene, Double> best = engine.stream()
|
||||||
|
.limit(bySteadyFitness(7))
|
||||||
|
.limit(100)
|
||||||
|
.peek(statistics)
|
||||||
|
.collect(toBestPhenotype());
|
||||||
|
|
||||||
|
System.out.println(statistics);
|
||||||
|
System.out.println(best);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.jenetics.BitChromosome;
|
||||||
|
import org.jenetics.BitGene;
|
||||||
|
import org.jenetics.Genotype;
|
||||||
|
|
||||||
|
public class KnapsackFF implements Function<Genotype<BitGene>, Double> {
|
||||||
|
private KnapsackItem[] items;
|
||||||
|
private double size;
|
||||||
|
|
||||||
|
public KnapsackFF(KnapsackItem[] items, double size) {
|
||||||
|
this.items = items;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double apply(Genotype<BitGene> gt) {
|
||||||
|
KnapsackItem sum = ((BitChromosome) gt.getChromosome()).ones()
|
||||||
|
.mapToObj(i -> items[i])
|
||||||
|
.collect(KnapsackItem.toSum());
|
||||||
|
return sum.size <= this.size ? sum.value : 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collector;
|
||||||
|
|
||||||
|
import org.jenetics.util.RandomRegistry;
|
||||||
|
|
||||||
|
public class KnapsackItem {
|
||||||
|
|
||||||
|
public double size;
|
||||||
|
public double value;
|
||||||
|
|
||||||
|
public KnapsackItem(double size, double value) {
|
||||||
|
this.size = size;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static KnapsackItem random() {
|
||||||
|
Random r = RandomRegistry.getRandom();
|
||||||
|
return new KnapsackItem(r.nextDouble() * 100, r.nextDouble() * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Collector<KnapsackItem, ?, KnapsackItem> toSum() {
|
||||||
|
return Collector.of(() -> new double[2], (a, b) -> {
|
||||||
|
a[0] += b.size;
|
||||||
|
a[1] += b.value;
|
||||||
|
} , (a, b) -> {
|
||||||
|
a[0] += b[0];
|
||||||
|
a[1] += b[1];
|
||||||
|
return a;
|
||||||
|
} , r -> new KnapsackItem(r[0], r[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import org.jenetics.BitChromosome;
|
||||||
|
import org.jenetics.BitGene;
|
||||||
|
import org.jenetics.Genotype;
|
||||||
|
import org.jenetics.engine.Engine;
|
||||||
|
import org.jenetics.engine.EvolutionResult;
|
||||||
|
import org.jenetics.util.Factory;
|
||||||
|
|
||||||
|
public class SimpleGeneticAlgorithm {
|
||||||
|
|
||||||
|
private static Integer eval(Genotype<BitGene> gt) {
|
||||||
|
return gt.getChromosome()
|
||||||
|
.as(BitChromosome.class)
|
||||||
|
.bitCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Factory<Genotype<BitGene>> gtf = Genotype.of(BitChromosome.of(10, 0.5));
|
||||||
|
System.out.println("Before the evolution:\n" + gtf);
|
||||||
|
|
||||||
|
Engine<BitGene, Integer> engine = Engine.builder(SimpleGeneticAlgorithm::eval, gtf)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Genotype<BitGene> result = engine.stream()
|
||||||
|
.limit(500)
|
||||||
|
.collect(EvolutionResult.toBestGenotype());
|
||||||
|
|
||||||
|
System.out.println("After the evolution:\n" + result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.jenetics.BitGene;
|
||||||
|
import org.jenetics.engine.Codec;
|
||||||
|
import org.jenetics.engine.Engine;
|
||||||
|
import org.jenetics.engine.EvolutionResult;
|
||||||
|
import org.jenetics.engine.Problem;
|
||||||
|
import org.jenetics.engine.codecs;
|
||||||
|
import org.jenetics.util.ISeq;
|
||||||
|
|
||||||
|
public class SpringsteenProblem implements Problem<ISeq<SpringsteenRecord>, BitGene, Double> {
|
||||||
|
|
||||||
|
private ISeq<SpringsteenRecord> records;
|
||||||
|
private double maxPricePerUniqueSong;
|
||||||
|
|
||||||
|
public SpringsteenProblem(ISeq<SpringsteenRecord> records, double maxPricePerUniqueSong) {
|
||||||
|
this.records = requireNonNull(records);
|
||||||
|
this.maxPricePerUniqueSong = maxPricePerUniqueSong;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<ISeq<SpringsteenRecord>, Double> fitness() {
|
||||||
|
return SpringsteenRecords -> {
|
||||||
|
double cost = SpringsteenRecords.stream()
|
||||||
|
.mapToDouble(r -> r.price)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
int uniqueSongCount = SpringsteenRecords.stream()
|
||||||
|
.flatMap(r -> r.songs.stream())
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
.size();
|
||||||
|
|
||||||
|
double pricePerUniqueSong = cost / uniqueSongCount;
|
||||||
|
|
||||||
|
return pricePerUniqueSong <= maxPricePerUniqueSong ? uniqueSongCount : 0.0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec<ISeq<SpringsteenRecord>, BitGene> codec() {
|
||||||
|
return codecs.ofSubSet(records);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
double maxPricePerUniqueSong = 2.5;
|
||||||
|
|
||||||
|
SpringsteenProblem springsteen = new SpringsteenProblem(
|
||||||
|
ISeq.of(new SpringsteenRecord("SpringsteenRecord1", 25, ISeq.of("Song1", "Song2", "Song3", "Song4", "Song5", "Song6")), new SpringsteenRecord("SpringsteenRecord2", 15, ISeq.of("Song2", "Song3", "Song4", "Song5", "Song6", "Song7")),
|
||||||
|
new SpringsteenRecord("SpringsteenRecord3", 35, ISeq.of("Song5", "Song6", "Song7", "Song8", "Song9", "Song10")), new SpringsteenRecord("SpringsteenRecord4", 17, ISeq.of("Song9", "Song10", "Song12", "Song4", "Song13", "Song14")),
|
||||||
|
new SpringsteenRecord("SpringsteenRecord5", 29, ISeq.of("Song1", "Song2", "Song13", "Song14", "Song15", "Song16")), new SpringsteenRecord("SpringsteenRecord6", 5, ISeq.of("Song18", "Song20", "Song30", "Song40"))),
|
||||||
|
maxPricePerUniqueSong);
|
||||||
|
|
||||||
|
Engine<BitGene, Double> engine = Engine.builder(springsteen)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ISeq<SpringsteenRecord> result = springsteen.codec()
|
||||||
|
.decoder()
|
||||||
|
.apply(engine.stream()
|
||||||
|
.limit(10)
|
||||||
|
.collect(EvolutionResult.toBestGenotype()));
|
||||||
|
|
||||||
|
double cost = result.stream()
|
||||||
|
.mapToDouble(r -> r.price)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
int uniqueSongCount = result.stream()
|
||||||
|
.flatMap(r -> r.songs.stream())
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
.size();
|
||||||
|
|
||||||
|
double pricePerUniqueSong = cost / uniqueSongCount;
|
||||||
|
|
||||||
|
System.out.println("Overall cost: " + cost);
|
||||||
|
System.out.println("Unique songs: " + uniqueSongCount);
|
||||||
|
System.out.println("Cost per song: " + pricePerUniqueSong);
|
||||||
|
System.out.println("Records: " + result.map(r -> r.name)
|
||||||
|
.toString(", "));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import org.jenetics.util.ISeq;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpringsteenRecord {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
double price;
|
||||||
|
ISeq<String> songs;
|
||||||
|
|
||||||
|
public SpringsteenRecord(String name, double price, ISeq<String> songs) {
|
||||||
|
this.name = requireNonNull(name);
|
||||||
|
this.price = price;
|
||||||
|
this.songs = requireNonNull(songs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.jenetics.EnumGene;
|
||||||
|
import org.jenetics.Mutator;
|
||||||
|
import org.jenetics.PartiallyMatchedCrossover;
|
||||||
|
import org.jenetics.Phenotype;
|
||||||
|
import org.jenetics.engine.Codec;
|
||||||
|
import org.jenetics.engine.Engine;
|
||||||
|
import org.jenetics.engine.EvolutionResult;
|
||||||
|
import org.jenetics.engine.Problem;
|
||||||
|
import org.jenetics.engine.codecs;
|
||||||
|
import org.jenetics.engine.limit;
|
||||||
|
import org.jenetics.util.ISeq;
|
||||||
|
import org.jenetics.util.LCG64ShiftRandom;
|
||||||
|
|
||||||
|
public class SubsetSum implements Problem<ISeq<Integer>, EnumGene<Integer>, Integer> {
|
||||||
|
|
||||||
|
private ISeq<Integer> basicSet;
|
||||||
|
private int size;
|
||||||
|
|
||||||
|
public SubsetSum(ISeq<Integer> basicSet, int size) {
|
||||||
|
this.basicSet = requireNonNull(basicSet);
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<ISeq<Integer>, Integer> fitness() {
|
||||||
|
return subset -> Math.abs(subset.stream()
|
||||||
|
.mapToInt(Integer::intValue)
|
||||||
|
.sum());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec<ISeq<Integer>, EnumGene<Integer>> codec() {
|
||||||
|
return codecs.ofSubSet(basicSet, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SubsetSum of(int n, int k, Random random) {
|
||||||
|
return new SubsetSum(random.doubles()
|
||||||
|
.limit(n)
|
||||||
|
.mapToObj(d -> (int) ((d - 0.5) * n))
|
||||||
|
.collect(ISeq.toISeq()), k);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SubsetSum problem = of(500, 15, new LCG64ShiftRandom(101010));
|
||||||
|
|
||||||
|
Engine<EnumGene<Integer>, Integer> engine = Engine.builder(problem)
|
||||||
|
.minimizing()
|
||||||
|
.maximalPhenotypeAge(5)
|
||||||
|
.alterers(new PartiallyMatchedCrossover<>(0.4), new Mutator<>(0.3))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Phenotype<EnumGene<Integer>, Integer> result = engine.stream()
|
||||||
|
.limit(limit.bySteadyFitness(55))
|
||||||
|
.collect(EvolutionResult.toBestPhenotype());
|
||||||
|
|
||||||
|
System.out.print(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.baeldung.algorithms.ga.jenetics;
|
||||||
|
|
||||||
|
import static java.lang.Math.PI;
|
||||||
|
import static java.lang.Math.abs;
|
||||||
|
import static java.lang.Math.sin;
|
||||||
|
import static org.jenetics.engine.EvolutionResult.toBestPhenotype;
|
||||||
|
import static org.jenetics.engine.limit.bySteadyFitness;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.jenetics.EnumGene;
|
||||||
|
import org.jenetics.Optimize;
|
||||||
|
import org.jenetics.PartiallyMatchedCrossover;
|
||||||
|
import org.jenetics.Phenotype;
|
||||||
|
import org.jenetics.SwapMutator;
|
||||||
|
import org.jenetics.engine.Engine;
|
||||||
|
import org.jenetics.engine.EvolutionStatistics;
|
||||||
|
import org.jenetics.engine.codecs;
|
||||||
|
|
||||||
|
public class TravelingSalesman {
|
||||||
|
|
||||||
|
private static final int STOPS = 50;
|
||||||
|
private static final double[][] ADJACENCE = matrix(STOPS);
|
||||||
|
|
||||||
|
private static double[][] matrix(int stops) {
|
||||||
|
final double radius = 100.0;
|
||||||
|
double[][] matrix = new double[stops][stops];
|
||||||
|
|
||||||
|
for (int i = 0; i < stops; ++i) {
|
||||||
|
for (int j = 0; j < stops; ++j) {
|
||||||
|
matrix[i][j] = chord(stops, abs(i - j), radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double chord(int stops, int i, double r) {
|
||||||
|
return 2.0 * r * abs(sin(PI * i / stops));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double dist(final int[] path) {
|
||||||
|
return IntStream.range(0, STOPS)
|
||||||
|
.mapToDouble(i -> ADJACENCE[path[i]][path[(i + 1) % STOPS]])
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Engine<EnumGene<Integer>, Double> engine = Engine.builder(TravelingSalesman::dist, codecs.ofPermutation(STOPS))
|
||||||
|
.optimize(Optimize.MINIMUM)
|
||||||
|
.maximalPhenotypeAge(11)
|
||||||
|
.populationSize(500)
|
||||||
|
.alterers(new SwapMutator<>(0.2), new PartiallyMatchedCrossover<>(0.35))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final EvolutionStatistics<Double, ?> statistics = EvolutionStatistics.ofNumber();
|
||||||
|
|
||||||
|
final Phenotype<EnumGene<Integer>, Double> best = engine.stream()
|
||||||
|
.limit(bySteadyFitness(15))
|
||||||
|
.limit(250)
|
||||||
|
.peek(statistics)
|
||||||
|
.collect(toBestPhenotype());
|
||||||
|
|
||||||
|
System.out.println(statistics);
|
||||||
|
System.out.println(best);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,10 +2,10 @@ package com.baeldung.algorithms.primechecker;
|
|||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
public class BigIntegerPrimeChecker implements PrimeChecker{
|
public class BigIntegerPrimeChecker implements PrimeChecker<Long>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrime(int number) {
|
public boolean isPrime(Long number) {
|
||||||
BigInteger bigInt = BigInteger.valueOf(number);
|
BigInteger bigInt = BigInteger.valueOf(number);
|
||||||
return bigInt.isProbablePrime(100);
|
return bigInt.isProbablePrime(100);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package com.baeldung.algorithms.primechecker;
|
package com.baeldung.algorithms.primechecker;
|
||||||
|
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.LongStream;
|
||||||
|
|
||||||
public class BruteForcePrimeChecker implements PrimeChecker{
|
public class BruteForcePrimeChecker implements PrimeChecker<Integer>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrime(int number) {
|
public boolean isPrime(Integer number) {
|
||||||
return IntStream.range(2, number).noneMatch(n -> (number % n == 0));
|
|
||||||
|
return number > 2 ? IntStream.range(2, number)
|
||||||
|
.noneMatch(n -> (number % n == 0)) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package com.baeldung.algorithms.primechecker;
|
package com.baeldung.algorithms.primechecker;
|
||||||
|
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.LongStream;
|
||||||
|
|
||||||
public class OptimisedPrimeChecker implements PrimeChecker{
|
public class OptimisedPrimeChecker implements PrimeChecker<Integer>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrime(int number) {
|
public boolean isPrime(Integer number) {
|
||||||
return IntStream.range(2, (int)Math.sqrt(number) + 1)
|
return number > 2 ? IntStream.rangeClosed(2, (int) Math.sqrt(number))
|
||||||
.noneMatch(n -> (number % n == 0));
|
.noneMatch(n -> (number % n == 0)) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.baeldung.algorithms.primechecker;
|
package com.baeldung.algorithms.primechecker;
|
||||||
|
|
||||||
public interface PrimeChecker {
|
public interface PrimeChecker <T> {
|
||||||
|
|
||||||
public boolean isPrime( int number );
|
public boolean isPrime( T number );
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@ package com.baeldung.algorithms.primechecker;
|
|||||||
|
|
||||||
import org.apache.commons.math3.primes.Primes;
|
import org.apache.commons.math3.primes.Primes;
|
||||||
|
|
||||||
public class PrimesPrimeChecker implements PrimeChecker{
|
public class PrimesPrimeChecker implements PrimeChecker<Integer>{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrime(int number) {
|
public boolean isPrime(Integer number) {
|
||||||
return Primes.isPrime(number);
|
return Primes.isPrime(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,18 +9,20 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
|
|||||||
|
|
||||||
public class BigIntegerPrimeCheckerTest {
|
public class BigIntegerPrimeCheckerTest {
|
||||||
|
|
||||||
PrimeChecker primeChecker = new BigIntegerPrimeChecker();
|
BigIntegerPrimeChecker primeChecker = new BigIntegerPrimeChecker();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
|
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
|
||||||
assertTrue(primeChecker.isPrime(13));
|
assertTrue(primeChecker.isPrime(13l));
|
||||||
assertTrue(primeChecker.isPrime(1009));
|
assertTrue(primeChecker.isPrime(1009L));
|
||||||
|
assertTrue(primeChecker.isPrime(74207281L));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenNonPrimeNumber_whenCheckIsPrime_thenFalse(){
|
public void givenNonPrimeNumber_whenCheckIsPrime_thenFalse(){
|
||||||
assertTrue(!primeChecker.isPrime(50));
|
assertTrue(!primeChecker.isPrime(50L));
|
||||||
assertTrue(!primeChecker.isPrime(1001));
|
assertTrue(!primeChecker.isPrime(1001L));
|
||||||
|
assertTrue(!primeChecker.isPrime(74207282L));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
|
|||||||
|
|
||||||
public class OptimisedPrimeCheckerTest {
|
public class OptimisedPrimeCheckerTest {
|
||||||
|
|
||||||
PrimeChecker primeChecker = new OptimisedPrimeChecker();
|
OptimisedPrimeChecker primeChecker = new OptimisedPrimeChecker();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
|
public void givenPrimeNumber_whenCheckIsPrime_thenTrue(){
|
||||||
|
@ -8,7 +8,7 @@ import com.baeldung.algorithms.primechecker.PrimeChecker;
|
|||||||
import com.baeldung.algorithms.primechecker.PrimesPrimeChecker;
|
import com.baeldung.algorithms.primechecker.PrimesPrimeChecker;
|
||||||
|
|
||||||
public class PrimesPrimeCheckerTest {
|
public class PrimesPrimeCheckerTest {
|
||||||
PrimeChecker primeChecker = new PrimesPrimeChecker();
|
PrimesPrimeChecker primeChecker = new PrimesPrimeChecker();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenPrimeNumber_whenCheckIsPrime_thenTrue() {
|
public void givenPrimeNumber_whenCheckIsPrime_thenTrue() {
|
||||||
|
@ -101,9 +101,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dbdoclet</groupId>
|
<groupId>org.dbdoclet</groupId>
|
||||||
<artifactId>herold</artifactId>
|
<artifactId>herold</artifactId>
|
||||||
<version>6.1.0</version>
|
<version>8.0.4</version>
|
||||||
<scope>system</scope>
|
|
||||||
<systemPath>${basedir}/src/test/resources/jars/herold.jar</systemPath>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -140,6 +138,8 @@
|
|||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${maven-surefire-plugin.version}</version>
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<forkCount>3</forkCount>
|
||||||
|
<reuseForks>true</reuseForks>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<exclude>**/*LiveTest.java</exclude>
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
@ -19,21 +19,21 @@ import javax.xml.transform.stream.StreamSource;
|
|||||||
import org.apache.fop.apps.Fop;
|
import org.apache.fop.apps.Fop;
|
||||||
import org.apache.fop.apps.FopFactory;
|
import org.apache.fop.apps.FopFactory;
|
||||||
import org.apache.xmlgraphics.util.MimeConstants;
|
import org.apache.xmlgraphics.util.MimeConstants;
|
||||||
import org.dbdoclet.trafo.html.docbook.DocBookTransformer;
|
import org.dbdoclet.trafo.html.docbook.HtmlDocBookTrafo;
|
||||||
import org.dbdoclet.trafo.script.Script;
|
import org.dbdoclet.trafo.script.Script;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.tidy.Tidy;
|
import org.w3c.tidy.Tidy;
|
||||||
|
|
||||||
public class ApacheFOPConvertHTMLIntegrationTest {
|
public class ApacheFOPConvertHTMLIntegrationTest {
|
||||||
private String inputFile = "src/test/resources/input.html";
|
private final String inputFile = "src/test/resources/input.html";
|
||||||
private String style = "src/test/resources/xhtml2fo.xsl";
|
private final String style = "src/test/resources/xhtml2fo.xsl";
|
||||||
private String style1 = "src/test/resources/docbook-xsl/fo/docbook.xsl";
|
private final String style1 = "src/test/resources/docbook-xsl/fo/docbook.xsl";
|
||||||
private String output_jtidy = "src/test/resources/output_jtidy.pdf";
|
private final String output_jtidy = "src/test/resources/output_jtidy.pdf";
|
||||||
private String output_html2fo = "src/test/resources/output_html2fo.pdf";
|
private final String output_html2fo = "src/test/resources/output_html2fo.pdf";
|
||||||
private String output_herold = "src/test/resources/output_herold.pdf";
|
private final String output_herold = "src/test/resources/output_herold.pdf";
|
||||||
private String foFile = "src/test/resources/input.fo";
|
private final String foFile = "src/test/resources/input.fo";
|
||||||
private String xmlFile = "src/test/resources/input.xml";
|
private final String xmlFile = "src/test/resources/input.xml";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenTransformHTMLToPDFUsingJTidy_thenCorrect() throws Exception {
|
public void whenTransformHTMLToPDFUsingJTidy_thenCorrect() throws Exception {
|
||||||
@ -114,8 +114,9 @@ public class ApacheFOPConvertHTMLIntegrationTest {
|
|||||||
|
|
||||||
private void fromHTMLTOXMLUsingHerold() throws Exception {
|
private void fromHTMLTOXMLUsingHerold() throws Exception {
|
||||||
final Script script = new Script();
|
final Script script = new Script();
|
||||||
final DocBookTransformer transformer = new DocBookTransformer();
|
final HtmlDocBookTrafo transformer = new HtmlDocBookTrafo();
|
||||||
transformer.setScript(script);
|
transformer.setInputStream(new FileInputStream(inputFile));
|
||||||
transformer.convert(new FileInputStream(inputFile), new FileOutputStream(xmlFile));
|
transformer.setOutputStream(new FileOutputStream(xmlFile));
|
||||||
|
transformer.transform(script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import javax.xml.transform.Result;
|
import javax.xml.transform.Result;
|
||||||
@ -25,19 +26,15 @@ import org.apache.fop.apps.Fop;
|
|||||||
import org.apache.fop.apps.FopFactory;
|
import org.apache.fop.apps.FopFactory;
|
||||||
import org.apache.xmlgraphics.util.MimeConstants;
|
import org.apache.xmlgraphics.util.MimeConstants;
|
||||||
import org.dbdoclet.trafo.TrafoScriptManager;
|
import org.dbdoclet.trafo.TrafoScriptManager;
|
||||||
import org.dbdoclet.trafo.html.docbook.DocBookTransformer;
|
import org.dbdoclet.trafo.html.docbook.HtmlDocBookTrafo;
|
||||||
import org.dbdoclet.trafo.script.Script;
|
import org.dbdoclet.trafo.script.Script;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
public class ApacheFOPHeroldLiveTest {
|
public class ApacheFOPHeroldLiveTest {
|
||||||
private String[] inputUrls = {// @formatter:off
|
private final String[] inputUrls = {// @formatter:off
|
||||||
"http://www.baeldung.com/2011/10/20/bootstraping-a-web-application-with-spring-3-1-and-java-based-configuration-part-1/",
|
// "http://www.baeldung.com/spring-security-basic-authentication",
|
||||||
"http://www.baeldung.com/2011/10/25/building-a-restful-web-service-with-spring-3-1-and-java-based-configuration-part-2/",
|
"http://www.baeldung.com/spring-security-digest-authentication"
|
||||||
"http://www.baeldung.com/2011/10/31/securing-a-restful-web-service-with-spring-security-3-1-part-3/",
|
|
||||||
"http://www.baeldung.com/spring-security-basic-authentication",
|
|
||||||
"http://www.baeldung.com/spring-security-digest-authentication",
|
|
||||||
"http://www.baeldung.com/2011/11/20/basic-and-digest-authentication-for-a-restful-service-with-spring-security-3-1/",
|
|
||||||
//"http://www.baeldung.com/spring-httpmessageconverter-rest",
|
//"http://www.baeldung.com/spring-httpmessageconverter-rest",
|
||||||
//"http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/",
|
//"http://www.baeldung.com/2011/11/06/restful-web-service-discoverability-part-4/",
|
||||||
//"http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/",
|
//"http://www.baeldung.com/2011/11/13/rest-service-discoverability-with-spring-part-5/",
|
||||||
@ -49,10 +46,10 @@ public class ApacheFOPHeroldLiveTest {
|
|||||||
//"http://www.baeldung.com/2013/01/18/testing-rest-with-multiple-mime-types/"
|
//"http://www.baeldung.com/2013/01/18/testing-rest-with-multiple-mime-types/"
|
||||||
}; // @formatter:on
|
}; // @formatter:on
|
||||||
|
|
||||||
private String style_file = "src/test/resources/docbook-xsl/fo/docbook.xsl";
|
private final String style_file = "src/test/resources/docbook-xsl/fo/docbook.xsl";
|
||||||
private String output_file = "src/test/resources/final_output.pdf";
|
private final String output_file = "src/test/resources/final_output.pdf";
|
||||||
private String xmlInput = "src/test/resources/input.xml";
|
private final String xmlInput = "src/test/resources/input.xml";
|
||||||
private String xmlOutput = "src/test/resources/output.xml";
|
private final String xmlOutput = "src/test/resources/output.xml";
|
||||||
|
|
||||||
// tests
|
// tests
|
||||||
|
|
||||||
@ -75,10 +72,11 @@ public class ApacheFOPHeroldLiveTest {
|
|||||||
final TrafoScriptManager mgr = new TrafoScriptManager();
|
final TrafoScriptManager mgr = new TrafoScriptManager();
|
||||||
final File profileFile = new File("src/test/resources/default.her");
|
final File profileFile = new File("src/test/resources/default.her");
|
||||||
script = mgr.parseScript(profileFile);
|
script = mgr.parseScript(profileFile);
|
||||||
final DocBookTransformer transformer = new DocBookTransformer();
|
final HtmlDocBookTrafo transformer = new HtmlDocBookTrafo();
|
||||||
transformer.setScript(script);
|
transformer.setInputStream(getInputStream(input));
|
||||||
|
transformer.setOutputStream(new FileOutputStream(xmlInput, append));
|
||||||
|
|
||||||
transformer.convert(getInputStream(input), new FileOutputStream(xmlInput, append));
|
transformer.transform(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Document fromXMLFileToFO() throws Exception {
|
private Document fromXMLFileToFO() throws Exception {
|
||||||
@ -112,7 +110,9 @@ public class ApacheFOPHeroldLiveTest {
|
|||||||
|
|
||||||
private InputStream getInputStream(final String input) throws IOException {
|
private InputStream getInputStream(final String input) throws IOException {
|
||||||
final URL url = new URL(input);
|
final URL url = new URL(input);
|
||||||
return url.openStream();
|
final HttpURLConnection httpcon = (HttpURLConnection) url.openConnection();
|
||||||
|
httpcon.addRequestProperty("User-Agent", "Mozilla/4.0");
|
||||||
|
return httpcon.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fixXML(final String input, final String output) throws IOException {
|
private void fixXML(final String input, final String output) throws IOException {
|
||||||
@ -127,7 +127,7 @@ public class ApacheFOPHeroldLiveTest {
|
|||||||
|
|
||||||
if (line.contains("info>")) {
|
if (line.contains("info>")) {
|
||||||
writer.write(line.replace("info>", "section>"));
|
writer.write(line.replace("info>", "section>"));
|
||||||
} else if (!((line.startsWith("<?xml") || line.startsWith("<article") || line.startsWith("</article")) && count > 4)) {
|
} else if (!((line.startsWith("<?xml") || line.startsWith("<article") || line.startsWith("</article")) && (count > 4))) {
|
||||||
writer.write(line.replaceAll("xml:id=\"", "xml:id=\"" + count));
|
writer.write(line.replaceAll("xml:id=\"", "xml:id=\"" + count));
|
||||||
}
|
}
|
||||||
writer.write("\n");
|
writer.write("\n");
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,82 @@
|
|||||||
|
package com.baeldung.java9.reactive;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.Flow.Subscriber;
|
||||||
|
import java.util.concurrent.Flow.Subscription;
|
||||||
|
|
||||||
|
public class BaeldungBatchSubscriberImpl<T> implements Subscriber<String> {
|
||||||
|
private Subscription subscription;
|
||||||
|
private boolean completed = false;
|
||||||
|
private int counter;
|
||||||
|
private ArrayList<String> buffer;
|
||||||
|
public static final int BUFFER_SIZE = 5;
|
||||||
|
|
||||||
|
public BaeldungBatchSubscriberImpl() {
|
||||||
|
buffer = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompleted(boolean completed) {
|
||||||
|
this.completed = completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCounter(int counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Subscription subscription) {
|
||||||
|
this.subscription = subscription;
|
||||||
|
subscription.request(BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(String item) {
|
||||||
|
buffer.add(item);
|
||||||
|
// if buffer is full, process the items.
|
||||||
|
if (buffer.size() >= BUFFER_SIZE) {
|
||||||
|
processBuffer();
|
||||||
|
}
|
||||||
|
//request more items.
|
||||||
|
subscription.request(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBuffer() {
|
||||||
|
if (buffer.isEmpty())
|
||||||
|
return;
|
||||||
|
// Process all items in the buffer. Here, we just print it and sleep for 1 second.
|
||||||
|
System.out.print("Processed items: ");
|
||||||
|
buffer.stream()
|
||||||
|
.forEach(item -> {
|
||||||
|
System.out.print(" " + item);
|
||||||
|
});
|
||||||
|
System.out.println();
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
counter = counter + buffer.size();
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
completed = true;
|
||||||
|
// process any remaining items in buffer before
|
||||||
|
processBuffer();
|
||||||
|
subscription.cancel();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.baeldung.java9.reactive;
|
||||||
|
|
||||||
|
import java.util.concurrent.Flow.Subscriber;
|
||||||
|
import java.util.concurrent.Flow.Subscription;
|
||||||
|
|
||||||
|
public class BaeldungSubscriberImpl<T> implements Subscriber<String> {
|
||||||
|
private Subscription subscription;
|
||||||
|
private boolean completed = false;
|
||||||
|
private int counter;
|
||||||
|
|
||||||
|
public boolean isCompleted() {
|
||||||
|
return completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompleted(boolean completed) {
|
||||||
|
this.completed = completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCounter(int counter) {
|
||||||
|
this.counter = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(Subscription subscription) {
|
||||||
|
this.subscription = subscription;
|
||||||
|
subscription.request(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(String item) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
System.out.println("Processed item : " + item);
|
||||||
|
subscription.request(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
completed = true;
|
||||||
|
subscription.cancel();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.baeldung.java9.reactive;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.SubmissionPublisher;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.Stopwatch;
|
||||||
|
|
||||||
|
public class BaeldungBatchSubscriberImplTest {
|
||||||
|
|
||||||
|
private static final int ITEM_SIZE = 10;
|
||||||
|
private SubmissionPublisher<String> publisher;
|
||||||
|
private BaeldungBatchSubscriberImpl<String> subscriber;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void initialize() {
|
||||||
|
this.publisher = new SubmissionPublisher<String>(ForkJoinPool.commonPool(), 6);
|
||||||
|
this.subscriber = new BaeldungBatchSubscriberImpl<String>();
|
||||||
|
publisher.subscribe(subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public Stopwatch stopwatch = new Stopwatch() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReactiveStreamCount() {
|
||||||
|
IntStream.range(0, ITEM_SIZE)
|
||||||
|
.forEach(item -> publisher.submit(item + ""));
|
||||||
|
publisher.close();
|
||||||
|
|
||||||
|
do {
|
||||||
|
// wait for subscribers to complete all processing.
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} while (!subscriber.isCompleted());
|
||||||
|
|
||||||
|
int count = subscriber.getCounter();
|
||||||
|
|
||||||
|
assertEquals(ITEM_SIZE, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReactiveStreamTime() {
|
||||||
|
IntStream.range(0, ITEM_SIZE)
|
||||||
|
.forEach(item -> publisher.submit(item + ""));
|
||||||
|
publisher.close();
|
||||||
|
|
||||||
|
do {
|
||||||
|
// wait for subscribers to complete all processing.
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} while (!subscriber.isCompleted());
|
||||||
|
|
||||||
|
// The runtime in seconds should be equal to the number of items in each batch.
|
||||||
|
assertTrue(stopwatch.runtime(TimeUnit.SECONDS) >= (ITEM_SIZE / subscriber.BUFFER_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,100 @@
|
|||||||
|
package com.baeldung.java9.reactive;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.SubmissionPublisher;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.Stopwatch;
|
||||||
|
|
||||||
|
public class BaeldungSubscriberImplTest {
|
||||||
|
|
||||||
|
private static final int ITEM_SIZE = 10;
|
||||||
|
private SubmissionPublisher<String> publisher;
|
||||||
|
private BaeldungSubscriberImpl<String> subscriber;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void initialize() {
|
||||||
|
// create Publisher with max buffer capacity 3.
|
||||||
|
this.publisher = new SubmissionPublisher<String>(ForkJoinPool.commonPool(), 3);
|
||||||
|
this.subscriber = new BaeldungSubscriberImpl<String>();
|
||||||
|
publisher.subscribe(subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public Stopwatch stopwatch = new Stopwatch() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReactiveStreamCount() {
|
||||||
|
IntStream.range(0, ITEM_SIZE)
|
||||||
|
.forEach(item -> publisher.submit(item + ""));
|
||||||
|
publisher.close();
|
||||||
|
|
||||||
|
do {
|
||||||
|
// wait for subscribers to complete all processing.
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} while (!subscriber.isCompleted());
|
||||||
|
|
||||||
|
int count = subscriber.getCounter();
|
||||||
|
|
||||||
|
assertEquals(ITEM_SIZE, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReactiveStreamTime() {
|
||||||
|
IntStream.range(0, ITEM_SIZE)
|
||||||
|
.forEach(item -> publisher.submit(item + ""));
|
||||||
|
publisher.close();
|
||||||
|
|
||||||
|
do {
|
||||||
|
// wait for subscribers to complete all processing.
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} while (!subscriber.isCompleted());
|
||||||
|
|
||||||
|
// The runtime in seconds should be equal to the number of items.
|
||||||
|
assertTrue(stopwatch.runtime(TimeUnit.SECONDS) >= ITEM_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReactiveStreamOffer() {
|
||||||
|
IntStream.range(0, ITEM_SIZE)
|
||||||
|
.forEach(item -> publisher.offer(item + "", (subscriber, string) -> {
|
||||||
|
// Returning false means this item will be dropped (no retry), if blocked.
|
||||||
|
return false;
|
||||||
|
}));
|
||||||
|
publisher.close();
|
||||||
|
|
||||||
|
do {
|
||||||
|
// wait for subscribers to complete all processing.
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} while (!subscriber.isCompleted());
|
||||||
|
|
||||||
|
int count = subscriber.getCounter();
|
||||||
|
// Because 10 items were offered and the buffer capacity was 3, few items will not be processed.
|
||||||
|
assertTrue(ITEM_SIZE > count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,6 +11,9 @@
|
|||||||
- [Converting between a List and a Set in Java](http://www.baeldung.com/convert-list-to-set-and-set-to-list)
|
- [Converting between a List and a Set in Java](http://www.baeldung.com/convert-list-to-set-and-set-to-list)
|
||||||
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
|
- [Convert a Map to an Array, List or Set in Java](http://www.baeldung.com/convert-map-values-to-array-list-set)
|
||||||
- [Java – Write to File](http://www.baeldung.com/java-write-to-file)
|
- [Java – Write to File](http://www.baeldung.com/java-write-to-file)
|
||||||
|
- [Java - Convert File to InputStream](http://www.baeldung.com/convert-file-to-input-stream)
|
||||||
|
- [Java – Random Long, Float, Integer and Double](http://www.baeldung.com/java-generate-random-long-float-integer-double)
|
||||||
|
- [Java – Generate Random String](http://www.baeldung.com/java-random-string)
|
||||||
- [Java Scanner](http://www.baeldung.com/java-scanner)
|
- [Java Scanner](http://www.baeldung.com/java-scanner)
|
||||||
- [Java Timer](http://www.baeldung.com/java-timer-and-timertask)
|
- [Java Timer](http://www.baeldung.com/java-timer-and-timertask)
|
||||||
- [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer)
|
- [Java – Byte Array to Writer](http://www.baeldung.com/java-convert-byte-array-to-writer)
|
||||||
@ -85,4 +88,7 @@
|
|||||||
- [Java Primitive Conversions](http://www.baeldung.com/java-primitive-conversions)
|
- [Java Primitive Conversions](http://www.baeldung.com/java-primitive-conversions)
|
||||||
- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
|
- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
|
||||||
- [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing)
|
- [Guide to Java 8 Comparator.comparing()](http://www.baeldung.com/java-8-comparator-comparing)
|
||||||
|
- [Avoiding ConcurrentModificationException when iterating and removing](http://www.baeldung.com/avoiding-concurrentmodificationexception-when-iterating-and-removing)
|
||||||
|
- [Removing all nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list)
|
||||||
|
- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list)
|
||||||
|
|
||||||
|
@ -172,6 +172,12 @@
|
|||||||
<version>1.1</version>
|
<version>1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.owasp.esapi</groupId>
|
||||||
|
<artifactId>esapi</artifactId>
|
||||||
|
<version>2.1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.logforging;
|
||||||
|
|
||||||
|
import org.owasp.esapi.ESAPI;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class LogForgingDemo {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(LogForgingDemo.class);
|
||||||
|
|
||||||
|
public void addLog(String amount) {
|
||||||
|
logger.info("Amount credited = {}", amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
LogForgingDemo demo = new LogForgingDemo();
|
||||||
|
demo.addLog(String.valueOf(300));
|
||||||
|
demo.addLog(String.valueOf(300 + "\n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully"));
|
||||||
|
demo.addLog(String.valueOf(encode(300 + "\n\nweb - 2017-04-12 17:47:08,957 [main] INFO Amount reversed successfully")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String encode(String message) {
|
||||||
|
message = message.replace('\n', '_').replace('\r', '_').replace('\t', '_');
|
||||||
|
message = ESAPI.encoder().encodeForHTML(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
package com.baeldung.stringtokenizer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
public class Application {
|
|
||||||
|
|
||||||
public List<String> getTokens(String str) {
|
|
||||||
List<String> tokens = new ArrayList<String>();
|
|
||||||
// StringTokenizer tokenizer = new StringTokenizer( str );
|
|
||||||
StringTokenizer tokenizer = new StringTokenizer( str , "," );
|
|
||||||
// StringTokenizer tokenizer = new StringTokenizer( str , "," , true );
|
|
||||||
while (tokenizer.hasMoreElements()) {
|
|
||||||
tokens.add( tokenizer.nextToken() );
|
|
||||||
// tokens.add( tokenizer.nextToken( "," ) );
|
|
||||||
}
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.baeldung.stringtokenizer;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class MyTokenizer {
|
||||||
|
|
||||||
|
public List<String> getTokens(String str) {
|
||||||
|
List<String> tokens = new ArrayList<>();
|
||||||
|
// StringTokenizer tokenizer = new StringTokenizer( str );
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(str, ",");
|
||||||
|
// StringTokenizer tokenizer = new StringTokenizer( str , "," , true );
|
||||||
|
while (tokenizer.hasMoreElements()) {
|
||||||
|
tokens.add(tokenizer.nextToken());
|
||||||
|
// tokens.add( tokenizer.nextToken("e") );
|
||||||
|
}
|
||||||
|
int tokenLength = tokens.size();
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTokensWithCollection(String str) {
|
||||||
|
return Collections
|
||||||
|
.list(new StringTokenizer(str, ","))
|
||||||
|
.stream()
|
||||||
|
.map(token -> (String) token)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTokensFromFile(String path, String delim) {
|
||||||
|
List<String> tokens = new ArrayList<>();
|
||||||
|
String currLine;
|
||||||
|
StringTokenizer tokenizer;
|
||||||
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(MyTokenizer.class.getResourceAsStream("/" + path)))) {
|
||||||
|
while ((currLine = br.readLine()) != null) {
|
||||||
|
tokenizer = new StringTokenizer(currLine, delim);
|
||||||
|
while (tokenizer.hasMoreElements()) {
|
||||||
|
tokens.add(tokenizer.nextToken());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.threadlocal;
|
||||||
|
|
||||||
|
|
||||||
|
public class Context {
|
||||||
|
private final String userName;
|
||||||
|
|
||||||
|
public Context(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Context{" +
|
||||||
|
"userNameSecret='" + userName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.threadlocal;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class SharedMapWithUserContext implements Runnable {
|
||||||
|
public final static Map<Integer, Context> userContextPerUserId = new ConcurrentHashMap<>();
|
||||||
|
private final Integer userId;
|
||||||
|
private UserRepository userRepository = new UserRepository();
|
||||||
|
|
||||||
|
public SharedMapWithUserContext(Integer userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String userName = userRepository.getUserNameForUserId(userId);
|
||||||
|
userContextPerUserId.put(userId, new Context(userName));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.threadlocal;
|
||||||
|
|
||||||
|
|
||||||
|
public class ThreadLocalWithUserContext implements Runnable {
|
||||||
|
private static final ThreadLocal<Context> userContext = new ThreadLocal<>();
|
||||||
|
private final Integer userId;
|
||||||
|
private UserRepository userRepository = new UserRepository();
|
||||||
|
|
||||||
|
public ThreadLocalWithUserContext(Integer userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String userName = userRepository.getUserNameForUserId(userId);
|
||||||
|
userContext.set(new Context(userName));
|
||||||
|
System.out.println("thread context for given userId: " + userId + " is: " + userContext.get());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.threadlocal;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
public class UserRepository {
|
||||||
|
public String getUserNameForUserId(Integer userId) {
|
||||||
|
return UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
}
|
453
core-java/src/main/resources/ESAPI.properties
Normal file
453
core-java/src/main/resources/ESAPI.properties
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
#
|
||||||
|
# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version
|
||||||
|
#
|
||||||
|
# This file is part of the Open Web Application Security Project (OWASP)
|
||||||
|
# Enterprise Security API (ESAPI) project. For details, please see
|
||||||
|
# http://www.owasp.org/index.php/ESAPI.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008,2009 - The OWASP Foundation
|
||||||
|
#
|
||||||
|
# DISCUSS: This may cause a major backwards compatibility issue, etc. but
|
||||||
|
# from a name space perspective, we probably should have prefaced
|
||||||
|
# all the property names with ESAPI or at least OWASP. Otherwise
|
||||||
|
# there could be problems is someone loads this properties file into
|
||||||
|
# the System properties. We could also put this file into the
|
||||||
|
# esapi.jar file (perhaps as a ResourceBundle) and then allow an external
|
||||||
|
# ESAPI properties be defined that would overwrite these defaults.
|
||||||
|
# That keeps the application's properties relatively simple as usually
|
||||||
|
# they will only want to override a few properties. If looks like we
|
||||||
|
# already support multiple override levels of this in the
|
||||||
|
# DefaultSecurityConfiguration class, but I'm suggesting placing the
|
||||||
|
# defaults in the esapi.jar itself. That way, if the jar is signed,
|
||||||
|
# we could detect if those properties had been tampered with. (The
|
||||||
|
# code to check the jar signatures is pretty simple... maybe 70-90 LOC,
|
||||||
|
# but off course there is an execution penalty (similar to the way
|
||||||
|
# that the separate sunjce.jar used to be when a class from it was
|
||||||
|
# first loaded). Thoughts?
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# WARNING: Operating system protection should be used to lock down the .esapi
|
||||||
|
# resources directory and all the files inside and all the directories all the
|
||||||
|
# way up to the root directory of the file system. Note that if you are using
|
||||||
|
# file-based implementations, that some files may need to be read-write as they
|
||||||
|
# get updated dynamically.
|
||||||
|
#
|
||||||
|
# Before using, be sure to update the MasterKey and MasterSalt as described below.
|
||||||
|
# N.B.: If you had stored data that you have previously encrypted with ESAPI 1.4,
|
||||||
|
# you *must* FIRST decrypt it using ESAPI 1.4 and then (if so desired)
|
||||||
|
# re-encrypt it with ESAPI 2.0. If you fail to do this, you will NOT be
|
||||||
|
# able to decrypt your data with ESAPI 2.0.
|
||||||
|
#
|
||||||
|
# YOU HAVE BEEN WARNED!!! More details are in the ESAPI 2.0 Release Notes.
|
||||||
|
#
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Configuration
|
||||||
|
#
|
||||||
|
# If true, then print all the ESAPI properties set here when they are loaded.
|
||||||
|
# If false, they are not printed. Useful to reduce output when running JUnit tests.
|
||||||
|
# If you need to troubleshoot a properties related problem, turning this on may help.
|
||||||
|
# This is 'false' in the src/test/resources/.esapi version. It is 'true' by
|
||||||
|
# default for reasons of backward compatibility with earlier ESAPI versions.
|
||||||
|
ESAPI.printProperties=true
|
||||||
|
|
||||||
|
# ESAPI is designed to be easily extensible. You can use the reference implementation
|
||||||
|
# or implement your own providers to take advantage of your enterprise's security
|
||||||
|
# infrastructure. The functions in ESAPI are referenced using the ESAPI locator, like:
|
||||||
|
#
|
||||||
|
# String ciphertext =
|
||||||
|
# ESAPI.encryptor().encrypt("Secret message"); // Deprecated in 2.0
|
||||||
|
# CipherText cipherText =
|
||||||
|
# ESAPI.encryptor().encrypt(new PlainText("Secret message")); // Preferred
|
||||||
|
#
|
||||||
|
# Below you can specify the classname for the provider that you wish to use in your
|
||||||
|
# application. The only requirement is that it implement the appropriate ESAPI interface.
|
||||||
|
# This allows you to switch security implementations in the future without rewriting the
|
||||||
|
# entire application.
|
||||||
|
#
|
||||||
|
# ExperimentalAccessController requires ESAPI-AccessControlPolicy.xml in .esapi directory
|
||||||
|
ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController
|
||||||
|
# FileBasedAuthenticator requires users.txt file in .esapi directory
|
||||||
|
ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator
|
||||||
|
ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder
|
||||||
|
ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor
|
||||||
|
|
||||||
|
ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor
|
||||||
|
ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities
|
||||||
|
ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector
|
||||||
|
# Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html
|
||||||
|
ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory
|
||||||
|
#ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory
|
||||||
|
ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer
|
||||||
|
ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Authenticator
|
||||||
|
#
|
||||||
|
Authenticator.AllowedLoginAttempts=3
|
||||||
|
Authenticator.MaxOldPasswordHashes=13
|
||||||
|
Authenticator.UsernameParameterName=username
|
||||||
|
Authenticator.PasswordParameterName=password
|
||||||
|
# RememberTokenDuration (in days)
|
||||||
|
Authenticator.RememberTokenDuration=14
|
||||||
|
# Session Timeouts (in minutes)
|
||||||
|
Authenticator.IdleTimeoutDuration=20
|
||||||
|
Authenticator.AbsoluteTimeoutDuration=120
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Encoder
|
||||||
|
#
|
||||||
|
# ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks.
|
||||||
|
# Failure to canonicalize input is a very common mistake when implementing validation schemes.
|
||||||
|
# Canonicalization is automatic when using the ESAPI Validator, but you can also use the
|
||||||
|
# following code to canonicalize data.
|
||||||
|
#
|
||||||
|
# ESAPI.Encoder().canonicalize( "%22hello world"" );
|
||||||
|
#
|
||||||
|
# Multiple encoding is when a single encoding format is applied multiple times. Allowing
|
||||||
|
# multiple encoding is strongly discouraged.
|
||||||
|
Encoder.AllowMultipleEncoding=false
|
||||||
|
|
||||||
|
# Mixed encoding is when multiple different encoding formats are applied, or when
|
||||||
|
# multiple formats are nested. Allowing multiple encoding is strongly discouraged.
|
||||||
|
Encoder.AllowMixedEncoding=false
|
||||||
|
|
||||||
|
# The default list of codecs to apply when canonicalizing untrusted data. The list should include the codecs
|
||||||
|
# for all downstream interpreters or decoders. For example, if the data is likely to end up in a URL, HTML, or
|
||||||
|
# inside JavaScript, then the list of codecs below is appropriate. The order of the list is not terribly important.
|
||||||
|
Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec
|
||||||
|
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Encryption
|
||||||
|
#
|
||||||
|
# The ESAPI Encryptor provides basic cryptographic functions with a simplified API.
|
||||||
|
# To get started, generate a new key using java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor
|
||||||
|
# There is not currently any support for key rotation, so be careful when changing your key and salt as it
|
||||||
|
# will invalidate all signed, encrypted, and hashed data.
|
||||||
|
#
|
||||||
|
# WARNING: Not all combinations of algorithms and key lengths are supported.
|
||||||
|
# If you choose to use a key length greater than 128, you MUST download the
|
||||||
|
# unlimited strength policy files and install in the lib directory of your JRE/JDK.
|
||||||
|
# See http://java.sun.com/javase/downloads/index.jsp for more information.
|
||||||
|
#
|
||||||
|
# Backward compatibility with ESAPI Java 1.4 is supported by the two deprecated API
|
||||||
|
# methods, Encryptor.encrypt(String) and Encryptor.decrypt(String). However, whenever
|
||||||
|
# possible, these methods should be avoided as they use ECB cipher mode, which in almost
|
||||||
|
# all circumstances a poor choice because of it's weakness. CBC cipher mode is the default
|
||||||
|
# for the new Encryptor encrypt / decrypt methods for ESAPI Java 2.0. In general, you
|
||||||
|
# should only use this compatibility setting if you have persistent data encrypted with
|
||||||
|
# version 1.4 and even then, you should ONLY set this compatibility mode UNTIL
|
||||||
|
# you have decrypted all of your old encrypted data and then re-encrypted it with
|
||||||
|
# ESAPI 2.0 using CBC mode. If you have some reason to mix the deprecated 1.4 mode
|
||||||
|
# with the new 2.0 methods, make sure that you use the same cipher algorithm for both
|
||||||
|
# (256-bit AES was the default for 1.4; 128-bit is the default for 2.0; see below for
|
||||||
|
# more details.) Otherwise, you will have to use the new 2.0 encrypt / decrypt methods
|
||||||
|
# where you can specify a SecretKey. (Note that if you are using the 256-bit AES,
|
||||||
|
# that requires downloading the special jurisdiction policy files mentioned above.)
|
||||||
|
#
|
||||||
|
# ***** IMPORTANT: Do NOT forget to replace these with your own values! *****
|
||||||
|
# To calculate these values, you can run:
|
||||||
|
# java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor
|
||||||
|
#
|
||||||
|
Encryptor.MasterKey=tzfztf56ftv
|
||||||
|
Encryptor.MasterSalt=123456ztrewq
|
||||||
|
|
||||||
|
# Provides the default JCE provider that ESAPI will "prefer" for its symmetric
|
||||||
|
# encryption and hashing. (That is it will look to this provider first, but it
|
||||||
|
# will defer to other providers if the requested algorithm is not implemented
|
||||||
|
# by this provider.) If left unset, ESAPI will just use your Java VM's current
|
||||||
|
# preferred JCE provider, which is generally set in the file
|
||||||
|
# "$JAVA_HOME/jre/lib/security/java.security".
|
||||||
|
#
|
||||||
|
# The main intent of this is to allow ESAPI symmetric encryption to be
|
||||||
|
# used with a FIPS 140-2 compliant crypto-module. For details, see the section
|
||||||
|
# "Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules" in
|
||||||
|
# the ESAPI 2.0 Symmetric Encryption User Guide, at:
|
||||||
|
# http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html
|
||||||
|
# However, this property also allows you to easily use an alternate JCE provider
|
||||||
|
# such as "Bouncy Castle" without having to make changes to "java.security".
|
||||||
|
# See Javadoc for SecurityProviderLoader for further details. If you wish to use
|
||||||
|
# a provider that is not known to SecurityProviderLoader, you may specify the
|
||||||
|
# fully-qualified class name of the JCE provider class that implements
|
||||||
|
# java.security.Provider. If the name contains a '.', this is interpreted as
|
||||||
|
# a fully-qualified class name that implements java.security.Provider.
|
||||||
|
#
|
||||||
|
# NOTE: Setting this property has the side-effect of changing it in your application
|
||||||
|
# as well, so if you are using JCE in your application directly rather than
|
||||||
|
# through ESAPI (you wouldn't do that, would you? ;-), it will change the
|
||||||
|
# preferred JCE provider there as well.
|
||||||
|
#
|
||||||
|
# Default: Keeps the JCE provider set to whatever JVM sets it to.
|
||||||
|
Encryptor.PreferredJCEProvider=
|
||||||
|
|
||||||
|
# AES is the most widely used and strongest encryption algorithm. This
|
||||||
|
# should agree with your Encryptor.CipherTransformation property.
|
||||||
|
# By default, ESAPI Java 1.4 uses "PBEWithMD5AndDES" and which is
|
||||||
|
# very weak. It is essentially a password-based encryption key, hashed
|
||||||
|
# with MD5 around 1K times and then encrypted with the weak DES algorithm
|
||||||
|
# (56-bits) using ECB mode and an unspecified padding (it is
|
||||||
|
# JCE provider specific, but most likely "NoPadding"). However, 2.0 uses
|
||||||
|
# "AES/CBC/PKCSPadding". If you want to change these, change them here.
|
||||||
|
# Warning: This property does not control the default reference implementation for
|
||||||
|
# ESAPI 2.0 using JavaEncryptor. Also, this property will be dropped
|
||||||
|
# in the future.
|
||||||
|
# @deprecated
|
||||||
|
Encryptor.EncryptionAlgorithm=AES
|
||||||
|
# For ESAPI Java 2.0 - New encrypt / decrypt methods use this.
|
||||||
|
Encryptor.CipherTransformation=AES/CBC/PKCS5Padding
|
||||||
|
|
||||||
|
# Applies to ESAPI 2.0 and later only!
|
||||||
|
# Comma-separated list of cipher modes that provide *BOTH*
|
||||||
|
# confidentiality *AND* message authenticity. (NIST refers to such cipher
|
||||||
|
# modes as "combined modes" so that's what we shall call them.) If any of these
|
||||||
|
# cipher modes are used then no MAC is calculated and stored
|
||||||
|
# in the CipherText upon encryption. Likewise, if one of these
|
||||||
|
# cipher modes is used with decryption, no attempt will be made
|
||||||
|
# to validate the MAC contained in the CipherText object regardless
|
||||||
|
# of whether it contains one or not. Since the expectation is that
|
||||||
|
# these cipher modes support support message authenticity already,
|
||||||
|
# injecting a MAC in the CipherText object would be at best redundant.
|
||||||
|
#
|
||||||
|
# Note that as of JDK 1.5, the SunJCE provider does not support *any*
|
||||||
|
# of these cipher modes. Of these listed, only GCM and CCM are currently
|
||||||
|
# NIST approved. YMMV for other JCE providers. E.g., Bouncy Castle supports
|
||||||
|
# GCM and CCM with "NoPadding" mode, but not with "PKCS5Padding" or other
|
||||||
|
# padding modes.
|
||||||
|
Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC
|
||||||
|
|
||||||
|
# Applies to ESAPI 2.0 and later only!
|
||||||
|
# Additional cipher modes allowed for ESAPI 2.0 encryption. These
|
||||||
|
# cipher modes are in _addition_ to those specified by the property
|
||||||
|
# 'Encryptor.cipher_modes.combined_modes'.
|
||||||
|
# Note: We will add support for streaming modes like CFB & OFB once
|
||||||
|
# we add support for 'specified' to the property 'Encryptor.ChooseIVMethod'
|
||||||
|
# (probably in ESAPI 2.1).
|
||||||
|
# DISCUSS: Better name?
|
||||||
|
Encryptor.cipher_modes.additional_allowed=CBC
|
||||||
|
|
||||||
|
# 128-bit is almost always sufficient and appears to be more resistant to
|
||||||
|
# related key attacks than is 256-bit AES. Use '_' to use default key size
|
||||||
|
# for cipher algorithms (where it makes sense because the algorithm supports
|
||||||
|
# a variable key size). Key length must agree to what's provided as the
|
||||||
|
# cipher transformation, otherwise this will be ignored after logging a
|
||||||
|
# warning.
|
||||||
|
#
|
||||||
|
# NOTE: This is what applies BOTH ESAPI 1.4 and 2.0. See warning above about mixing!
|
||||||
|
Encryptor.EncryptionKeyLength=128
|
||||||
|
|
||||||
|
# Because 2.0 uses CBC mode by default, it requires an initialization vector (IV).
|
||||||
|
# (All cipher modes except ECB require an IV.) There are two choices: we can either
|
||||||
|
# use a fixed IV known to both parties or allow ESAPI to choose a random IV. While
|
||||||
|
# the IV does not need to be hidden from adversaries, it is important that the
|
||||||
|
# adversary not be allowed to choose it. Also, random IVs are generally much more
|
||||||
|
# secure than fixed IVs. (In fact, it is essential that feed-back cipher modes
|
||||||
|
# such as CFB and OFB use a different IV for each encryption with a given key so
|
||||||
|
# in such cases, random IVs are much preferred. By default, ESAPI 2.0 uses random
|
||||||
|
# IVs. If you wish to use 'fixed' IVs, set 'Encryptor.ChooseIVMethod=fixed' and
|
||||||
|
# uncomment the Encryptor.fixedIV.
|
||||||
|
#
|
||||||
|
# Valid values: random|fixed|specified 'specified' not yet implemented; planned for 2.1
|
||||||
|
Encryptor.ChooseIVMethod=random
|
||||||
|
# If you choose to use a fixed IV, then you must place a fixed IV here that
|
||||||
|
# is known to all others who are sharing your secret key. The format should
|
||||||
|
# be a hex string that is the same length as the cipher block size for the
|
||||||
|
# cipher algorithm that you are using. The following is an *example* for AES
|
||||||
|
# from an AES test vector for AES-128/CBC as described in:
|
||||||
|
# NIST Special Publication 800-38A (2001 Edition)
|
||||||
|
# "Recommendation for Block Cipher Modes of Operation".
|
||||||
|
# (Note that the block size for AES is 16 bytes == 128 bits.)
|
||||||
|
#
|
||||||
|
Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f
|
||||||
|
|
||||||
|
# Whether or not CipherText should use a message authentication code (MAC) with it.
|
||||||
|
# This prevents an adversary from altering the IV as well as allowing a more
|
||||||
|
# fool-proof way of determining the decryption failed because of an incorrect
|
||||||
|
# key being supplied. This refers to the "separate" MAC calculated and stored
|
||||||
|
# in CipherText, not part of any MAC that is calculated as a result of a
|
||||||
|
# "combined mode" cipher mode.
|
||||||
|
#
|
||||||
|
# If you are using ESAPI with a FIPS 140-2 cryptographic module, you *must* also
|
||||||
|
# set this property to false.
|
||||||
|
Encryptor.CipherText.useMAC=true
|
||||||
|
|
||||||
|
# Whether or not the PlainText object may be overwritten and then marked
|
||||||
|
# eligible for garbage collection. If not set, this is still treated as 'true'.
|
||||||
|
Encryptor.PlainText.overwrite=true
|
||||||
|
|
||||||
|
# Do not use DES except in a legacy situations. 56-bit is way too small key size.
|
||||||
|
#Encryptor.EncryptionKeyLength=56
|
||||||
|
#Encryptor.EncryptionAlgorithm=DES
|
||||||
|
|
||||||
|
# TripleDES is considered strong enough for most purposes.
|
||||||
|
# Note: There is also a 112-bit version of DESede. Using the 168-bit version
|
||||||
|
# requires downloading the special jurisdiction policy from Sun.
|
||||||
|
#Encryptor.EncryptionKeyLength=168
|
||||||
|
#Encryptor.EncryptionAlgorithm=DESede
|
||||||
|
|
||||||
|
Encryptor.HashAlgorithm=SHA-512
|
||||||
|
Encryptor.HashIterations=1024
|
||||||
|
Encryptor.DigitalSignatureAlgorithm=SHA1withDSA
|
||||||
|
Encryptor.DigitalSignatureKeyLength=1024
|
||||||
|
Encryptor.RandomAlgorithm=SHA1PRNG
|
||||||
|
Encryptor.CharacterEncoding=UTF-8
|
||||||
|
|
||||||
|
# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function
|
||||||
|
# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and
|
||||||
|
# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for
|
||||||
|
# the MAC, mostly to keep the overall size at a minimum.)
|
||||||
|
#
|
||||||
|
# Currently supported choices for JDK 1.5 and 1.6 are:
|
||||||
|
# HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and
|
||||||
|
# HmacSHA512 (512 bits).
|
||||||
|
# Note that HmacMD5 is *not* supported for the PRF used by the KDF even though
|
||||||
|
# the JDKs support it. See the ESAPI 2.0 Symmetric Encryption User Guide
|
||||||
|
# further details.
|
||||||
|
Encryptor.KDF.PRF=HmacSHA256
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI HttpUtilties
|
||||||
|
#
|
||||||
|
# The HttpUtilities provide basic protections to HTTP requests and responses. Primarily these methods
|
||||||
|
# protect against malicious data from attackers, such as unprintable characters, escaped characters,
|
||||||
|
# and other simple attacks. The HttpUtilities also provides utility methods for dealing with cookies,
|
||||||
|
# headers, and CSRF tokens.
|
||||||
|
#
|
||||||
|
# Default file upload location (remember to escape backslashes with \\)
|
||||||
|
HttpUtilities.UploadDir=C:\\ESAPI\\testUpload
|
||||||
|
HttpUtilities.UploadTempDir=C:\\temp
|
||||||
|
# Force flags on cookies, if you use HttpUtilities to set cookies
|
||||||
|
HttpUtilities.ForceHttpOnlySession=false
|
||||||
|
HttpUtilities.ForceSecureSession=false
|
||||||
|
HttpUtilities.ForceHttpOnlyCookies=true
|
||||||
|
HttpUtilities.ForceSecureCookies=true
|
||||||
|
# Maximum size of HTTP headers
|
||||||
|
HttpUtilities.MaxHeaderSize=4096
|
||||||
|
# File upload configuration
|
||||||
|
HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll
|
||||||
|
HttpUtilities.MaxUploadFileBytes=500000000
|
||||||
|
# Using UTF-8 throughout your stack is highly recommended. That includes your database driver,
|
||||||
|
# container, and any other technologies you may be using. Failure to do this may expose you
|
||||||
|
# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization.
|
||||||
|
HttpUtilities.ResponseContentType=text/html; charset=UTF-8
|
||||||
|
# This is the name of the cookie used to represent the HTTP session
|
||||||
|
# Typically this will be the default "JSESSIONID"
|
||||||
|
HttpUtilities.HttpSessionIdName=JSESSIONID
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Executor
|
||||||
|
# CHECKME - Not sure what this is used for, but surely it should be made OS independent.
|
||||||
|
Executor.WorkingDirectory=C:\\Windows\\Temp
|
||||||
|
Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe
|
||||||
|
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Logging
|
||||||
|
# Set the application name if these logs are combined with other applications
|
||||||
|
Logger.ApplicationName=ExampleApplication
|
||||||
|
# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true
|
||||||
|
Logger.LogEncodingRequired=false
|
||||||
|
# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments.
|
||||||
|
Logger.LogApplicationName=true
|
||||||
|
# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments.
|
||||||
|
Logger.LogServerIP=true
|
||||||
|
# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you
|
||||||
|
# want to place it in a specific directory.
|
||||||
|
Logger.LogFileName=ESAPI_logging_file
|
||||||
|
# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000)
|
||||||
|
Logger.MaxLogFileSize=10000000
|
||||||
|
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Intrusion Detection
|
||||||
|
#
|
||||||
|
# Each event has a base to which .count, .interval, and .action are added
|
||||||
|
# The IntrusionException will fire if we receive "count" events within "interval" seconds
|
||||||
|
# The IntrusionDetector is configurable to take the following actions: log, logout, and disable
|
||||||
|
# (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable
|
||||||
|
#
|
||||||
|
# Custom Events
|
||||||
|
# Names must start with "event." as the base
|
||||||
|
# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here
|
||||||
|
# You can also disable intrusion detection completely by changing
|
||||||
|
# the following parameter to true
|
||||||
|
#
|
||||||
|
IntrusionDetector.Disable=false
|
||||||
|
#
|
||||||
|
IntrusionDetector.event.test.count=2
|
||||||
|
IntrusionDetector.event.test.interval=10
|
||||||
|
IntrusionDetector.event.test.actions=disable,log
|
||||||
|
|
||||||
|
# Exception Events
|
||||||
|
# All EnterpriseSecurityExceptions are registered automatically
|
||||||
|
# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException
|
||||||
|
# Use the fully qualified classname of the exception as the base
|
||||||
|
|
||||||
|
# any intrusion is an attack
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout
|
||||||
|
|
||||||
|
# for test purposes
|
||||||
|
# CHECKME: Shouldn't there be something in the property name itself that designates
|
||||||
|
# that these are for testing???
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout
|
||||||
|
|
||||||
|
# rapid validation errors indicate scans or attacks in progress
|
||||||
|
# org.owasp.esapi.errors.ValidationException.count=10
|
||||||
|
# org.owasp.esapi.errors.ValidationException.interval=10
|
||||||
|
# org.owasp.esapi.errors.ValidationException.actions=log,logout
|
||||||
|
|
||||||
|
# sessions jumping between hosts indicates session hijacking
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10
|
||||||
|
IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout
|
||||||
|
|
||||||
|
|
||||||
|
#===========================================================================
|
||||||
|
# ESAPI Validation
|
||||||
|
#
|
||||||
|
# The ESAPI Validator works on regular expressions with defined names. You can define names
|
||||||
|
# either here, or you may define application specific patterns in a separate file defined below.
|
||||||
|
# This allows enterprises to specify both organizational standards as well as application specific
|
||||||
|
# validation rules.
|
||||||
|
#
|
||||||
|
Validator.ConfigurationFile=validation.properties
|
||||||
|
|
||||||
|
# Validators used by ESAPI
|
||||||
|
Validator.AccountName=^[a-zA-Z0-9]{3,20}$
|
||||||
|
Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$
|
||||||
|
Validator.RoleName=^[a-z]{1,20}$
|
||||||
|
|
||||||
|
#the word TEST below should be changed to your application
|
||||||
|
#name - only relative URL's are supported
|
||||||
|
Validator.Redirect=^\\/test.*$
|
||||||
|
|
||||||
|
# Global HTTP Validation Rules
|
||||||
|
# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=]
|
||||||
|
Validator.HTTPScheme=^(http|https)$
|
||||||
|
Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$
|
||||||
|
Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$
|
||||||
|
Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$
|
||||||
|
Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$
|
||||||
|
Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$
|
||||||
|
Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,32}$
|
||||||
|
Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
|
||||||
|
Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$
|
||||||
|
Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$
|
||||||
|
Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$
|
||||||
|
Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$
|
||||||
|
Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$
|
||||||
|
Validator.HTTPURL=^.*$
|
||||||
|
Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$
|
||||||
|
|
||||||
|
# Validation of file related input
|
||||||
|
Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$
|
||||||
|
Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$
|
||||||
|
|
||||||
|
# Validation of dates. Controls whether or not 'lenient' dates are accepted.
|
||||||
|
# See DataFormat.setLenient(boolean flag) for further details.
|
||||||
|
Validator.AcceptLenientDates=false
|
||||||
|
|
3
core-java/src/main/resources/data.csv
Normal file
3
core-java/src/main/resources/data.csv
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
1|IND|India
|
||||||
|
2|MY|Malaysia
|
||||||
|
3|AU|Australia
|
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.baeldung.java.collections;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ConcurrentModificationExceptionTest {
|
||||||
|
@Test
|
||||||
|
public void changingContentWithSetDoesNotThrowConcurrentModificationException() throws Exception {
|
||||||
|
ArrayList<Object> array = new ArrayList<>(asList(0, "one", 2, "three"));
|
||||||
|
|
||||||
|
for (Object item : array) {
|
||||||
|
array.set(3, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removingElementUsingIteratorAPI() throws Exception {
|
||||||
|
List<String> originalList = new ArrayList<>(asList("zero", "one", "two", "three"));
|
||||||
|
|
||||||
|
Iterator<String> iterator = originalList.iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String next = iterator.next();
|
||||||
|
if (Objects.equals(next, "one")) iterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(originalList, asList("zero", "two", "three"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void modifyingContentAndIteratingUsingListIteratorAPI() throws Exception {
|
||||||
|
List<String> originalList = new ArrayList<>(asList("zero", "one", "two", "three"));
|
||||||
|
|
||||||
|
ListIterator<String> iterator = originalList.listIterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String next = iterator.next();
|
||||||
|
if (Objects.equals(next, "one")) {
|
||||||
|
iterator.set("another");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(next, "two")) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(next, "three")) {
|
||||||
|
iterator.add("four");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(originalList, asList("zero", "another", "three", "four"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removingElementUsingCopyAndListAPI() throws Exception {
|
||||||
|
List<String> originalList = new ArrayList<>(asList("zero", "one", "two", "three"));
|
||||||
|
|
||||||
|
List<String> listCopy = new ArrayList<>(originalList);
|
||||||
|
|
||||||
|
for (String next : listCopy) {
|
||||||
|
if (Objects.equals(next, "one")) originalList.remove(originalList.indexOf(next) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(originalList, asList("one", "two", "three"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copyOnWriteList() throws Exception {
|
||||||
|
List<String> originalList = new CopyOnWriteArrayList<>(asList("zero", "one", "two", "three"));
|
||||||
|
|
||||||
|
for (String next : originalList) {
|
||||||
|
if (Objects.equals(next, "one")) originalList.remove(originalList.indexOf(next) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(originalList, asList("one", "two", "three"));
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ public class FlattenNestedListTest {
|
|||||||
List<List<String>> lol = asList(asList("one:one"), asList("two:one", "two:two", "two:three"), asList("three:one", "three:two", "three:three", "three:four"));
|
List<List<String>> lol = asList(asList("one:one"), asList("two:one", "two:two", "two:three"), asList("three:one", "three:two", "three:three", "three:four"));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenNestedList_thenFlattenNestedListImperative() {
|
public void givenNestedList_thenFlattenImperatively() {
|
||||||
List<String> ls = flattenListOfListsImperatively(lol);
|
List<String> ls = flattenListOfListsImperatively(lol);
|
||||||
|
|
||||||
assertNotNull(ls);
|
assertNotNull(ls);
|
||||||
@ -27,7 +27,7 @@ public class FlattenNestedListTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenNestedList_thenFlattenNestedListStream() {
|
public void givenNestedList_thenFlattenFunctionally() {
|
||||||
List<String> ls = flattenListOfListsStream(lol);
|
List<String> ls = flattenListOfListsStream(lol);
|
||||||
|
|
||||||
assertNotNull(ls);
|
assertNotNull(ls);
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
package com.baeldung.stringtokenizer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
public class ApplicationTest {
|
|
||||||
|
|
||||||
Application application = new Application();
|
|
||||||
List<String> expectedTokens = new ArrayList<String>();
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() {
|
|
||||||
expectedTokens.add( "Welcome" );
|
|
||||||
expectedTokens.add( "to" );
|
|
||||||
expectedTokens.add( "baeldung.com" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenString_thenGetListOfString() {
|
|
||||||
String str = "Welcome,to,baeldung.com";
|
|
||||||
List<String> actualTokens = application.getTokens(str);
|
|
||||||
assertEquals(expectedTokens, actualTokens);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.baeldung.stringtokenizer;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class TokenizerTest {
|
||||||
|
|
||||||
|
private final MyTokenizer myTokenizer = new MyTokenizer();
|
||||||
|
private final List<String> expectedTokensForString = Arrays.asList("Welcome", "to", "baeldung.com");
|
||||||
|
private final List<String> expectedTokensForFile = Arrays.asList("1", "IND", "India", "2", "MY", "Malaysia", "3", "AU", "Australia");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenString_thenGetListOfString() {
|
||||||
|
String str = "Welcome,to,baeldung.com";
|
||||||
|
List<String> actualTokens = myTokenizer.getTokens(str);
|
||||||
|
assertEquals(expectedTokensForString, actualTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFile_thenGetListOfString() {
|
||||||
|
List<String> actualTokens = myTokenizer.getTokensFromFile("data.csv", "|");
|
||||||
|
assertEquals(expectedTokensForFile, actualTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.baeldung.threadlocal;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ThreadLocalTest {
|
||||||
|
@Test
|
||||||
|
public void givenThreadThatStoresContextInAMap_whenStartThread_thenShouldSetContextForBothUsers() throws ExecutionException, InterruptedException {
|
||||||
|
//when
|
||||||
|
SharedMapWithUserContext firstUser = new SharedMapWithUserContext(1);
|
||||||
|
SharedMapWithUserContext secondUser = new SharedMapWithUserContext(2);
|
||||||
|
new Thread(firstUser).start();
|
||||||
|
new Thread(secondUser).start();
|
||||||
|
|
||||||
|
Thread.sleep(3000);
|
||||||
|
//then
|
||||||
|
assertEquals(SharedMapWithUserContext.userContextPerUserId.size(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenThreadThatStoresContextInThreadLocal_whenStartThread_thenShouldStoreContextInThreadLocal() throws ExecutionException, InterruptedException {
|
||||||
|
//when
|
||||||
|
ThreadLocalWithUserContext firstUser = new ThreadLocalWithUserContext(1);
|
||||||
|
ThreadLocalWithUserContext secondUser = new ThreadLocalWithUserContext(2);
|
||||||
|
new Thread(firstUser).start();
|
||||||
|
new Thread(secondUser).start();
|
||||||
|
|
||||||
|
Thread.sleep(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
core-java/src/test/java/com/baeldung/unsafe/CASCounter.java
Normal file
33
core-java/src/test/java/com/baeldung/unsafe/CASCounter.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.unsafe;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
class CASCounter {
|
||||||
|
private final Unsafe unsafe;
|
||||||
|
private volatile long counter = 0;
|
||||||
|
private long offset;
|
||||||
|
|
||||||
|
private Unsafe getUnsafe() throws IllegalAccessException, NoSuchFieldException {
|
||||||
|
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
f.setAccessible(true);
|
||||||
|
return (Unsafe) f.get(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CASCounter() throws Exception {
|
||||||
|
unsafe = getUnsafe();
|
||||||
|
offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("counter"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment() {
|
||||||
|
long before = counter;
|
||||||
|
while (!unsafe.compareAndSwapLong(this, offset, before, before + 1)) {
|
||||||
|
before = counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.baeldung.unsafe;
|
||||||
|
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
class OffHeapArray {
|
||||||
|
private final static int BYTE = 1;
|
||||||
|
private long size;
|
||||||
|
private long address;
|
||||||
|
|
||||||
|
private Unsafe getUnsafe() throws IllegalAccessException, NoSuchFieldException {
|
||||||
|
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
f.setAccessible(true);
|
||||||
|
return (Unsafe) f.get(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffHeapArray(long size) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
this.size = size;
|
||||||
|
address = getUnsafe().allocateMemory(size * BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(long i, byte value) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
getUnsafe().putByte(address + i * BYTE, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(long idx) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
return getUnsafe().getByte(address + idx * BYTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void freeMemory() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
getUnsafe().freeMemory(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
123
core-java/src/test/java/com/baeldung/unsafe/UnsafeTest.java
Normal file
123
core-java/src/test/java/com/baeldung/unsafe/UnsafeTest.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package com.baeldung.unsafe;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class UnsafeTest {
|
||||||
|
|
||||||
|
private Unsafe unsafe;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
f.setAccessible(true);
|
||||||
|
unsafe = (Unsafe) f.get(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenClass_whenInitializeIt_thenShouldHaveDifferentStateWhenUseUnsafe() throws IllegalAccessException, InstantiationException {
|
||||||
|
//when
|
||||||
|
InitializationOrdering o1 = new InitializationOrdering();
|
||||||
|
assertEquals(o1.getA(), 1);
|
||||||
|
|
||||||
|
//when
|
||||||
|
InitializationOrdering o3 = (InitializationOrdering) unsafe.allocateInstance(InitializationOrdering.class);
|
||||||
|
assertEquals(o3.getA(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPrivateMethod_whenUsingUnsafe_thenCanModifyPrivateField() throws NoSuchFieldException {
|
||||||
|
//given
|
||||||
|
SecretHolder secretHolder = new SecretHolder();
|
||||||
|
|
||||||
|
//when
|
||||||
|
Field f = secretHolder.getClass().getDeclaredField("SECRET_VALUE");
|
||||||
|
unsafe.putInt(secretHolder, unsafe.objectFieldOffset(f), 1);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertTrue(secretHolder.secretIsDisclosed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IOException.class)
|
||||||
|
public void givenUnsafeThrowException_whenThrowCheckedException_thenNotNeedToCatchIt() {
|
||||||
|
unsafe.throwException(new IOException());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayBiggerThatMaxInt_whenAllocateItOffHeapMemory_thenSuccess() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
//given
|
||||||
|
long SUPER_SIZE = (long) Integer.MAX_VALUE * 2;
|
||||||
|
OffHeapArray array = new OffHeapArray(SUPER_SIZE);
|
||||||
|
|
||||||
|
//when
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
array.set((long) Integer.MAX_VALUE + i, (byte) 3);
|
||||||
|
sum += array.get((long) Integer.MAX_VALUE + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
long arraySize = array.size();
|
||||||
|
|
||||||
|
array.freeMemory();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(arraySize, SUPER_SIZE);
|
||||||
|
assertEquals(sum, 300);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnsafeCompareAndSwap_whenUseIt_thenCounterYildCorrectLockFreeResults() throws Exception {
|
||||||
|
//given
|
||||||
|
int NUM_OF_THREADS = 1_000;
|
||||||
|
int NUM_OF_INCREMENTS = 10_000;
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(NUM_OF_THREADS);
|
||||||
|
CASCounter casCounter = new CASCounter();
|
||||||
|
|
||||||
|
//when
|
||||||
|
IntStream.rangeClosed(0, NUM_OF_THREADS - 1)
|
||||||
|
.forEach(i -> service.submit(() -> IntStream
|
||||||
|
.rangeClosed(0, NUM_OF_INCREMENTS - 1)
|
||||||
|
.forEach(j -> casCounter.increment())));
|
||||||
|
|
||||||
|
service.shutdown();
|
||||||
|
service.awaitTermination(1, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertEquals(NUM_OF_INCREMENTS * NUM_OF_THREADS, casCounter.getCounter());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class InitializationOrdering {
|
||||||
|
private long a;
|
||||||
|
|
||||||
|
public InitializationOrdering() {
|
||||||
|
this.a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getA() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SecretHolder {
|
||||||
|
private int SECRET_VALUE = 0;
|
||||||
|
|
||||||
|
public boolean secretIsDisclosed() {
|
||||||
|
return SECRET_VALUE == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
93
cucumber/pom.xml
Normal file
93
cucumber/pom.xml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<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>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>cucumber</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.source.version>1.8</java.source.version>
|
||||||
|
<java.target.version>1.8</java.target.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
|
||||||
|
<slf4j.version>1.7.21</slf4j.version>
|
||||||
|
<logback.version>1.1.7</logback.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<hamcrest.library.version>1.3</hamcrest.library.version>
|
||||||
|
<cucumber.version>1.2.5</cucumber.version>
|
||||||
|
<surefire.plugin.version>2.19.1</surefire.plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>info.cukes</groupId>
|
||||||
|
<artifactId>cucumber-junit</artifactId>
|
||||||
|
<version>${cucumber.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>info.cukes</groupId>
|
||||||
|
<artifactId>cucumber-java</artifactId>
|
||||||
|
<version>${cucumber.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-library</artifactId>
|
||||||
|
<version>${hamcrest.library.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>${maven.compiler.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<verbose>true</verbose>
|
||||||
|
<fork>true</fork>
|
||||||
|
<source>${java.source.version}</source>
|
||||||
|
<target>${java.target.version}</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${surefire.plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/CalculatorTest.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.cucumber.calculator;
|
||||||
|
|
||||||
|
public class Calculator {
|
||||||
|
public int add(int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.cucumber.calculator;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import cucumber.api.java.Before;
|
||||||
|
import cucumber.api.java.en.Given;
|
||||||
|
import cucumber.api.java.en.Then;
|
||||||
|
import cucumber.api.java.en.When;
|
||||||
|
|
||||||
|
public class CalculatorRunSteps {
|
||||||
|
|
||||||
|
private int total;
|
||||||
|
|
||||||
|
private Calculator calculator;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
private void init() {
|
||||||
|
total = -999;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Given("^I have a calculator$")
|
||||||
|
public void initializeCalculator() throws Throwable {
|
||||||
|
calculator = new Calculator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@When("^I add (-?\\d+) and (-?\\d+)$")
|
||||||
|
public void testAdd(int num1, int num2) throws Throwable {
|
||||||
|
total = calculator.add(num1, num2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Then("^the result should be (-?\\d+)$")
|
||||||
|
public void validateResult(int result) throws Throwable {
|
||||||
|
Assert.assertThat(total, Matchers.equalTo(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.cucumber.calculator;
|
||||||
|
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import cucumber.api.CucumberOptions;
|
||||||
|
import cucumber.api.junit.Cucumber;
|
||||||
|
|
||||||
|
@RunWith(Cucumber.class)
|
||||||
|
@CucumberOptions(
|
||||||
|
features={"classpath:features/calculator.feature", "classpath:features/calculator-scenario-outline.feature"}
|
||||||
|
, plugin = { "pretty", "json:target/reports/json/calculator.json" }
|
||||||
|
, glue = {"com.baeldung.cucumber.calculator"}
|
||||||
|
)
|
||||||
|
public class CalculatorTest {
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
Feature: Calculator
|
||||||
|
As a user
|
||||||
|
I want to use a calculator to add numbers
|
||||||
|
So that I don't need to add myself
|
||||||
|
|
||||||
|
Scenario Outline: Add two numbers <num1> & <num2>
|
||||||
|
Given I have a calculator
|
||||||
|
When I add <num1> and <num2>
|
||||||
|
Then the result should be <total>
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| num1 | num2 | total |
|
||||||
|
| -2 | 3 | 1 |
|
||||||
|
| 10 | 15 | 25 |
|
||||||
|
| 99 | -99 | 0 |
|
||||||
|
| -1 | -10 | -11 |
|
24
cucumber/src/test/resources/features/calculator.feature
Normal file
24
cucumber/src/test/resources/features/calculator.feature
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
Feature: Calculator
|
||||||
|
As a user
|
||||||
|
I want to use a calculator to add numbers
|
||||||
|
So that I don't need to add myself
|
||||||
|
|
||||||
|
Scenario: Add two numbers -2 & 3
|
||||||
|
Given I have a calculator
|
||||||
|
When I add -2 and 3
|
||||||
|
Then the result should be 1
|
||||||
|
|
||||||
|
Scenario: Add two numbers 10 & 15
|
||||||
|
Given I have a calculator
|
||||||
|
When I add 10 and 15
|
||||||
|
Then the result should be 25
|
||||||
|
|
||||||
|
Scenario: Add two numbers 99 & -99
|
||||||
|
Given I have a calculator
|
||||||
|
When I add 99 and -99
|
||||||
|
Then the result should be 0
|
||||||
|
|
||||||
|
Scenario: Add two numbers -1 & -10
|
||||||
|
Given I have a calculator
|
||||||
|
When I add -1 and -10
|
||||||
|
Then the result should be -11
|
13
cucumber/src/test/resources/logback-test.xml
Normal file
13
cucumber/src/test/resources/logback-test.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<configuration scan="true">
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
@ -1,167 +1,195 @@
|
|||||||
package org.baeldung.guava;
|
package org.baeldung.guava;
|
||||||
|
|
||||||
import com.google.common.math.DoubleMath;
|
import static org.hamcrest.core.IsEqual.equalTo;
|
||||||
import com.google.common.math.IntMath;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
import static org.hamcrest.core.IsEqual.equalTo;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertThat;
|
import com.google.common.math.DoubleMath;
|
||||||
import static org.junit.Assert.assertTrue;
|
import com.google.common.math.IntMath;
|
||||||
|
|
||||||
public class GuavaMathTest {
|
public class GuavaMathTest {
|
||||||
@Test
|
@Test(expected = ArithmeticException.class)
|
||||||
public void testIntMathAdd() {
|
public void whenSumOverflow_thenThrowException() {
|
||||||
try {
|
IntMath.checkedAdd(Integer.MAX_VALUE, 1);
|
||||||
IntMath.checkedAdd(Integer.MAX_VALUE, 1);
|
}
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
@Test(expected = ArithmeticException.class)
|
||||||
IntMath.checkedAdd(Integer.MIN_VALUE, -1);
|
public void whenSumUnderflow_thenThrowException() {
|
||||||
assertTrue(false);
|
IntMath.checkedAdd(Integer.MIN_VALUE, -1);
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int result1 = IntMath.checkedAdd(2, 1);
|
|
||||||
assertThat(result1, equalTo(3));
|
|
||||||
|
|
||||||
int result2 = IntMath.saturatedAdd(Integer.MAX_VALUE, 100);
|
|
||||||
assertThat(result2, equalTo(Integer.MAX_VALUE));
|
|
||||||
|
|
||||||
int result3 = IntMath.saturatedAdd(Integer.MIN_VALUE, -100);
|
|
||||||
assertThat(result3, equalTo(Integer.MIN_VALUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIntMathSubtract() {
|
public void should_calculate_sum() {
|
||||||
try {
|
int result = IntMath.checkedAdd(2, 1);
|
||||||
IntMath.checkedSubtract(Integer.MIN_VALUE, 1);
|
assertThat(result, equalTo(3));
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
IntMath.checkedSubtract(Integer.MAX_VALUE, -1);
|
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
int result1 = IntMath.checkedSubtract(200, 100);
|
|
||||||
assertThat(result1, equalTo(100));
|
|
||||||
|
|
||||||
int result2 = IntMath.saturatedSubtract(Integer.MIN_VALUE, 1);
|
|
||||||
assertThat(result2, equalTo(Integer.MIN_VALUE));
|
|
||||||
|
|
||||||
int result3 = IntMath.saturatedSubtract(Integer.MAX_VALUE, -1);
|
|
||||||
assertThat(result3, equalTo(Integer.MAX_VALUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIntMathMultiply() {
|
public void whenSumOverflow_thenReturnMaxInteger() {
|
||||||
try {
|
int result = IntMath.saturatedAdd(Integer.MAX_VALUE, 100);
|
||||||
IntMath.checkedMultiply(Integer.MAX_VALUE, 2);
|
assertThat(result, equalTo(Integer.MAX_VALUE));
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
IntMath.checkedMultiply(Integer.MIN_VALUE, 2);
|
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int result1 = IntMath.checkedMultiply(21, 3);
|
|
||||||
assertThat(result1, equalTo(63));
|
|
||||||
|
|
||||||
int result2 = IntMath.saturatedMultiply(Integer.MAX_VALUE, 2);
|
|
||||||
assertThat(result2, equalTo(Integer.MAX_VALUE));
|
|
||||||
|
|
||||||
int result3 = IntMath.saturatedMultiply(Integer.MIN_VALUE, 2);
|
|
||||||
assertThat(result3, equalTo(Integer.MIN_VALUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIntMathPow() {
|
public void whenSumUnderflow_thenReturnMinInteger() {
|
||||||
try {
|
int result = IntMath.saturatedAdd(Integer.MIN_VALUE, -100);
|
||||||
IntMath.checkedPow(Integer.MAX_VALUE, 2);
|
assertThat(result, equalTo(Integer.MIN_VALUE));
|
||||||
assertTrue(false);
|
}
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
@Test(expected = ArithmeticException.class)
|
||||||
IntMath.checkedPow(Integer.MIN_VALUE, 3);
|
public void whenDifferenceOverflow_thenThrowException() {
|
||||||
assertTrue(false);
|
IntMath.checkedSubtract(Integer.MAX_VALUE, -1);
|
||||||
} catch (ArithmeticException e) {
|
}
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int result1 = IntMath.saturatedPow(3, 3);
|
@Test(expected = ArithmeticException.class)
|
||||||
assertThat(result1, equalTo(27));
|
public void whenDifferenceUnderflow_thenThrowException() {
|
||||||
|
IntMath.checkedSubtract(Integer.MIN_VALUE, 1);
|
||||||
int result2 = IntMath.saturatedPow(Integer.MAX_VALUE, 2);
|
|
||||||
assertThat(result2, equalTo(Integer.MAX_VALUE));
|
|
||||||
|
|
||||||
int result3 = IntMath.saturatedPow(Integer.MIN_VALUE, 3);
|
|
||||||
assertThat(result3, equalTo(Integer.MIN_VALUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIntMathRound() {
|
public void should_calculate_difference() {
|
||||||
|
int result = IntMath.checkedSubtract(200, 100);
|
||||||
|
assertThat(result, equalTo(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDifferenceOverflow_thenReturnMaxInteger() {
|
||||||
|
int result = IntMath.saturatedSubtract(Integer.MAX_VALUE, -1);
|
||||||
|
assertThat(result, equalTo(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenDifferenceUnderflow_thenReturnMinInteger() {
|
||||||
|
int result = IntMath.saturatedSubtract(Integer.MIN_VALUE, 1);
|
||||||
|
assertThat(result, equalTo(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ArithmeticException.class)
|
||||||
|
public void whenProductOverflow_thenThrowException() {
|
||||||
|
IntMath.checkedMultiply(Integer.MAX_VALUE, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ArithmeticException.class)
|
||||||
|
public void whenProductUnderflow_thenThrowException() {
|
||||||
|
IntMath.checkedMultiply(Integer.MIN_VALUE, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_product() {
|
||||||
|
int result = IntMath.checkedMultiply(21, 3);
|
||||||
|
assertThat(result, equalTo(63));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenProductOverflow_thenReturnMaxInteger() {
|
||||||
|
int result = IntMath.saturatedMultiply(Integer.MAX_VALUE, 2);
|
||||||
|
assertThat(result, equalTo(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenProductUnderflow_thenReturnMinInteger() {
|
||||||
|
int result = IntMath.saturatedMultiply(Integer.MIN_VALUE, 2);
|
||||||
|
assertThat(result, equalTo(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ArithmeticException.class)
|
||||||
|
public void whenPowerOverflow_thenThrowException() {
|
||||||
|
IntMath.checkedPow(Integer.MAX_VALUE, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = ArithmeticException.class)
|
||||||
|
public void whenPowerUnderflow_thenThrowException() {
|
||||||
|
IntMath.checkedPow(Integer.MIN_VALUE, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_power() {
|
||||||
|
int result = IntMath.saturatedPow(3, 3);
|
||||||
|
assertThat(result, equalTo(27));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPowerOverflow_thenReturnMaxInteger() {
|
||||||
|
int result = IntMath.saturatedPow(Integer.MAX_VALUE, 2);
|
||||||
|
assertThat(result, equalTo(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPowerUnderflow_thenReturnMinInteger() {
|
||||||
|
int result = IntMath.saturatedPow(Integer.MIN_VALUE, 3);
|
||||||
|
assertThat(result, equalTo(Integer.MIN_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_round_divide_result() {
|
||||||
int result1 = IntMath.divide(3, 2, RoundingMode.DOWN);
|
int result1 = IntMath.divide(3, 2, RoundingMode.DOWN);
|
||||||
assertThat(result1, equalTo(1));
|
assertThat(result1, equalTo(1));
|
||||||
|
|
||||||
int result2 = IntMath.divide(3, 2, RoundingMode.UP);
|
int result2 = IntMath.divide(3, 2, RoundingMode.UP);
|
||||||
assertThat(result2, equalTo(2));
|
assertThat(result2, equalTo(2));
|
||||||
|
|
||||||
int result3 = IntMath.log2(5, RoundingMode.FLOOR);
|
|
||||||
assertThat(result3, equalTo(2));
|
|
||||||
int result4 = IntMath.log2(5, RoundingMode.CEILING);
|
|
||||||
assertThat(result4, equalTo(3));
|
|
||||||
|
|
||||||
int result5 = IntMath.log10(11, RoundingMode.HALF_UP);
|
|
||||||
assertThat(result5, equalTo(1));
|
|
||||||
|
|
||||||
int result6 = IntMath.sqrt(4, RoundingMode.UNNECESSARY);
|
|
||||||
assertThat(result6, equalTo(2));
|
|
||||||
try {
|
|
||||||
IntMath.sqrt(5, RoundingMode.UNNECESSARY);
|
|
||||||
assertTrue(false);
|
|
||||||
} catch (ArithmeticException e) {
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIntMathAdditionalFunctions() {
|
public void should_round_log2_result() {
|
||||||
int result1 = IntMath.gcd(15, 20);
|
int result1 = IntMath.log2(5, RoundingMode.FLOOR);
|
||||||
assertThat(result1, equalTo(5));
|
assertThat(result1, equalTo(2));
|
||||||
|
|
||||||
int result2 = IntMath.mod(8, 3);
|
int result2 = IntMath.log2(5, RoundingMode.CEILING);
|
||||||
assertThat(result2, equalTo(2));
|
assertThat(result2, equalTo(3));
|
||||||
|
}
|
||||||
|
|
||||||
boolean result3 = IntMath.isPowerOfTwo(8);
|
@Test
|
||||||
assertTrue(result3);
|
public void should_round_log10_result() {
|
||||||
boolean result4 = IntMath.isPowerOfTwo(9);
|
int result = IntMath.log10(11, RoundingMode.HALF_UP);
|
||||||
assertFalse(result4);
|
assertThat(result, equalTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
int result5 = IntMath.factorial(4);
|
@Test
|
||||||
assertThat(result5, equalTo(24));
|
public void should_round_sqrt_result() {
|
||||||
|
int result = IntMath.sqrt(4, RoundingMode.UNNECESSARY);
|
||||||
|
assertThat(result, equalTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
int result6 = IntMath.binomial(7, 3);
|
@Test(expected = ArithmeticException.class)
|
||||||
assertThat(result6, equalTo(35));
|
public void whenNeedRounding_thenThrowException() {
|
||||||
|
IntMath.sqrt(5, RoundingMode.UNNECESSARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_gcd() {
|
||||||
|
int result = IntMath.gcd(15, 20);
|
||||||
|
assertThat(result, equalTo(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_mod() {
|
||||||
|
int result = IntMath.mod(8, 3);
|
||||||
|
assertThat(result, equalTo(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_test_if_is_power_of_two() {
|
||||||
|
boolean result1 = IntMath.isPowerOfTwo(8);
|
||||||
|
assertTrue(result1);
|
||||||
|
|
||||||
|
boolean result2 = IntMath.isPowerOfTwo(9);
|
||||||
|
assertFalse(result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_factorial() {
|
||||||
|
int result = IntMath.factorial(4);
|
||||||
|
assertThat(result, equalTo(24));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_calculate_binomial() {
|
||||||
|
int result = IntMath.binomial(7, 3);
|
||||||
|
assertThat(result, equalTo(35));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
76
jee7/pom.xml
76
jee7/pom.xml
@ -7,7 +7,6 @@
|
|||||||
<artifactId>jee7</artifactId>
|
<artifactId>jee7</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<description>JavaEE 7 Arquillian Archetype Sample</description>
|
<description>JavaEE 7 Arquillian Archetype Sample</description>
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.min.version>1.8</java.min.version>
|
<java.min.version>1.8</java.min.version>
|
||||||
@ -28,6 +27,7 @@
|
|||||||
|
|
||||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<prerequisites>
|
<prerequisites>
|
||||||
@ -43,6 +43,13 @@
|
|||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.arquillian.extension</groupId>
|
||||||
|
<artifactId>arquillian-drone-bom</artifactId>
|
||||||
|
<version>2.0.1.Final</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
@ -65,6 +72,13 @@
|
|||||||
<artifactId>arquillian-junit-container</artifactId>
|
<artifactId>arquillian-junit-container</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.arquillian.graphene</groupId>
|
||||||
|
<artifactId>graphene-webdriver</artifactId>
|
||||||
|
<version>2.1.0.Final</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.jayway.awaitility</groupId>
|
<groupId>com.jayway.awaitility</groupId>
|
||||||
<artifactId>awaitility</artifactId>
|
<artifactId>awaitility</artifactId>
|
||||||
@ -84,7 +98,47 @@
|
|||||||
<artifactId>shrinkwrap-resolver-impl-maven-archive</artifactId>
|
<artifactId>shrinkwrap-resolver-impl-maven-archive</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.faces</groupId>
|
||||||
|
<artifactId>jsf-api</artifactId>
|
||||||
|
<version>2.2.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.faces</groupId>
|
||||||
|
<artifactId>jsf-impl</artifactId>
|
||||||
|
<version>2.2.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>jstl</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet.jsp</groupId>
|
||||||
|
<artifactId>jsp-api</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>taglibs</groupId>
|
||||||
|
<artifactId>standard</artifactId>
|
||||||
|
<version>1.1.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -167,6 +221,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
@ -206,6 +261,7 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
@ -331,5 +387,21 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</profile>
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>webdriver-chrome</id>
|
||||||
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<browser>chrome</browser>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>webdriver-firefox</id>
|
||||||
|
<properties>
|
||||||
|
<browser>firefox</browser>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
56
jee7/src/main/java/com/baeldung/convListVal/ConvListVal.java
Normal file
56
jee7/src/main/java/com/baeldung/convListVal/ConvListVal.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.convListVal;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.faces.bean.ManagedBean;
|
||||||
|
|
||||||
|
@ManagedBean
|
||||||
|
public class ConvListVal {
|
||||||
|
|
||||||
|
private Integer age;
|
||||||
|
private Double average;
|
||||||
|
private Date myDate;
|
||||||
|
private String name;
|
||||||
|
private String surname;
|
||||||
|
|
||||||
|
public Integer getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAge(Integer age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAverage() {
|
||||||
|
return average;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAverage(Double average) {
|
||||||
|
this.average = average;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getMyDate() {
|
||||||
|
return myDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMyDate(Date myDate) {
|
||||||
|
this.myDate = myDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
jee7/src/main/java/com/baeldung/convListVal/MyListener.java
Normal file
21
jee7/src/main/java/com/baeldung/convListVal/MyListener.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.convListVal;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.faces.event.AbortProcessingException;
|
||||||
|
import javax.faces.event.ValueChangeEvent;
|
||||||
|
import javax.faces.event.ValueChangeListener;
|
||||||
|
|
||||||
|
public class MyListener implements ValueChangeListener {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(MyListener.class.getName());
|
||||||
|
@Override
|
||||||
|
public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
|
||||||
|
if (event.getNewValue() != null) {
|
||||||
|
LOG.log(Level.INFO, "\tNew Value:{0}", event.getNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,8 +12,17 @@ NOTES: @WebServlet annotation designates the AccountServlet class as a Servlet c
|
|||||||
An initialization parameter 'type' is being set to denote the type of the bank account.
|
An initialization parameter 'type' is being set to denote the type of the bank account.
|
||||||
|
|
||||||
@ServletSecurity annotation imposes security constraints on the AccountServlet based on
|
@ServletSecurity annotation imposes security constraints on the AccountServlet based on
|
||||||
the tomcat-users.xml (this code assumes there is a role 'admin' in your tomcat-users.xml)
|
the tomcat-users.xml.
|
||||||
|
|
||||||
|
This code assumes that your tomcat-users.xml looks as follows:
|
||||||
|
|
||||||
|
<role rolename="Admin"/>
|
||||||
|
<role rolename="Member"/>
|
||||||
|
<role rolename="Guest"/>
|
||||||
|
<user username="Annie" password="admin" roles="Admin, Member, Guest" />
|
||||||
|
<user username="Diane" password="coder" roles="Member, Guest" />
|
||||||
|
<user username="Ted" password="newbie" roles="Guest" />
|
||||||
|
|
||||||
N.B : To see @ServletSecurity annotation in action, please uncomment the annotation code
|
N.B : To see @ServletSecurity annotation in action, please uncomment the annotation code
|
||||||
for @ServletSecurity.
|
for @ServletSecurity.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.javaeeannotations;
|
package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@ -17,8 +17,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
initParams = { @WebInitParam(name = "type", value = "savings") }
|
initParams = { @WebInitParam(name = "type", value = "savings") }
|
||||||
)
|
)
|
||||||
/*@ServletSecurity(
|
/*@ServletSecurity(
|
||||||
value = @HttpConstraint(rolesAllowed = {"admin"}),
|
value = @HttpConstraint(rolesAllowed = {"Member"}),
|
||||||
httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"admin"})}
|
httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"Admin"})}
|
||||||
)*/
|
)*/
|
||||||
public class AccountServlet extends javax.servlet.http.HttpServlet {
|
public class AccountServlet extends javax.servlet.http.HttpServlet {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.javaeeannotations;
|
package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations;
|
||||||
|
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
import javax.servlet.ServletContextListener;
|
import javax.servlet.ServletContextListener;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.javaeeannotations;
|
package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.javaeeannotations;
|
package com.baeldung.javaeeannotations.JavaEEAnnotationsSample.src.main.java.com.baeldung.javaeeannotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
@ -7,5 +7,4 @@
|
|||||||
<auth-method>BASIC</auth-method>
|
<auth-method>BASIC</auth-method>
|
||||||
<realm-name>default</realm-name>
|
<realm-name>default</realm-name>
|
||||||
</login-config>
|
</login-config>
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
@ -1,13 +1,9 @@
|
|||||||
package com.baeldung.jaxws.exception;
|
package com.baeldung.jaxws.exception;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.xml.ws.WebFault;
|
import javax.xml.ws.WebFault;
|
||||||
|
|
||||||
@WebFault
|
@WebFault
|
||||||
public class EmployeeAlreadyExists extends Exception implements Serializable {
|
public class EmployeeAlreadyExists extends Exception {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public EmployeeAlreadyExists() {
|
public EmployeeAlreadyExists() {
|
||||||
super("This employee already exists");
|
super("This employee already exists");
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package com.baeldung.jaxws.exception;
|
package com.baeldung.jaxws.exception;
|
||||||
|
|
||||||
import javax.xml.ws.WebFault;
|
import javax.xml.ws.WebFault;
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@WebFault
|
@WebFault
|
||||||
public class EmployeeNotFound extends Exception implements Serializable {
|
public class EmployeeNotFound extends Exception {
|
||||||
|
|
||||||
public EmployeeNotFound() {
|
public EmployeeNotFound() {
|
||||||
super("The specified employee does not exist");
|
super("The specified employee does not exist");
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package com.baeldung.jaxws.model;
|
package com.baeldung.jaxws.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
public class Employee {
|
||||||
|
|
||||||
public class Employee implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private int id;
|
private int id;
|
||||||
private String firstName;
|
private String firstName;
|
||||||
|
|
||||||
|
50
jee7/src/main/webapp/ConvListVal.xhtml
Normal file
50
jee7/src/main/webapp/ConvListVal.xhtml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core">
|
||||||
|
|
||||||
|
<h:head>
|
||||||
|
<title>Converters, Listeners and Validators</title>
|
||||||
|
</h:head>
|
||||||
|
<h:body>
|
||||||
|
<h1>Testing converters</h1>
|
||||||
|
<h:form id="myForm">
|
||||||
|
<h:outputLabel value="Age:"/>
|
||||||
|
<h:inputText id="age" value="#{convListVal.age}">
|
||||||
|
<f:converter converterId="javax.faces.Integer" />
|
||||||
|
</h:inputText>
|
||||||
|
<h:message id="ageError" for="age" />
|
||||||
|
<br/>
|
||||||
|
<h:outputLabel value="Average:"/>
|
||||||
|
<h:inputText id="average" value="#{convListVal.average}">
|
||||||
|
<f:converter converterId="javax.faces.Double" />
|
||||||
|
</h:inputText>
|
||||||
|
<h:message id = "averageError" for="average" />
|
||||||
|
<br/>
|
||||||
|
<h:outputLabel value="Date:"/>
|
||||||
|
<h:inputText id="myDate" value="#{convListVal.myDate}">
|
||||||
|
<f:convertDateTime pattern="dd/MM/yyyy" />
|
||||||
|
</h:inputText>
|
||||||
|
<h:message id="myDateError" for="myDate" />
|
||||||
|
<br/>
|
||||||
|
<h:outputText value="#{convListVal.myDate}">
|
||||||
|
<f:convertDateTime dateStyle="full" locale="en"/>
|
||||||
|
</h:outputText>
|
||||||
|
<br/>
|
||||||
|
<h:outputLabel value="Name:"/>
|
||||||
|
<h:inputText id="name" size="30" value="#{convListVal.name}">
|
||||||
|
<f:valueChangeListener type="com.baeldung.convListVal.MyListener" />
|
||||||
|
</h:inputText>
|
||||||
|
<br/>
|
||||||
|
<h:outputLabel value="surname" for="surname"/>
|
||||||
|
<h:panelGroup>
|
||||||
|
<h:inputText id="surname" value="#{convListVal.surname}">
|
||||||
|
<f:validateLength minimum="5" maximum="10"/>
|
||||||
|
</h:inputText>
|
||||||
|
<h:message id="surnameError" for="surname" errorStyle="color:red" />
|
||||||
|
</h:panelGroup>
|
||||||
|
<br/>
|
||||||
|
<h:commandButton id="send" value="submit" type="submit" />
|
||||||
|
</h:form>
|
||||||
|
</h:body>
|
||||||
|
</html>
|
13
jee7/src/main/webapp/WEB-INF/faces-config.xml
Normal file
13
jee7/src/main/webapp/WEB-INF/faces-config.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<faces-config
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||||
|
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
|
||||||
|
version="2.0">
|
||||||
|
<managed-bean>
|
||||||
|
<managed-bean-name>convListVal</managed-bean-name>
|
||||||
|
<managed-bean-class>com.baeldung.convListVal.ConvListVal</managed-bean-class>
|
||||||
|
<managed-bean-scope>session</managed-bean-scope>
|
||||||
|
</managed-bean>
|
||||||
|
</faces-config>
|
41
jee7/src/main/webapp/WEB-INF/web.xml
Normal file
41
jee7/src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
|
||||||
|
<!-- The bare minimum needed for JSF 2.2 is a servlet 2.5 or later
|
||||||
|
declaration (this uses 3.0) and the mapping for the FacesServlet.
|
||||||
|
Setting PROJECT_STAGE to Development is highly recommended
|
||||||
|
during initial development so that you get more helpful
|
||||||
|
error messages. Whether you want server-side state saving
|
||||||
|
(default) or client-side is a more complicated question:
|
||||||
|
client-side uses more bandwidth but fewer server resources.
|
||||||
|
Client-side also helps to avoid the dreaded view expired exceptions.
|
||||||
|
|
||||||
|
From JSF 2 and PrimeFaces tutorial
|
||||||
|
at http://www.coreservlets.com/JSF-Tutorial/jsf2/
|
||||||
|
-->
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>Faces Servlet</servlet-name>
|
||||||
|
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>Faces Servlet</servlet-name>
|
||||||
|
<url-pattern>*.jsf</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
<context-param>
|
||||||
|
<param-name>javax.faces.PROJECT_STAGE</param-name>
|
||||||
|
<param-value>Development</param-value>
|
||||||
|
</context-param>
|
||||||
|
<context-param>
|
||||||
|
<description>State saving method: 'client' or 'server' (default). See JSF Specification section 2.5.2</description>
|
||||||
|
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
|
||||||
|
<param-value>client</param-value>
|
||||||
|
</context-param>
|
||||||
|
<!-- If you go to http://host/project/ (with no file name), it will
|
||||||
|
try index.jsf first, welcome.jsf next, and so forth.
|
||||||
|
-->
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>index.jsf</welcome-file>
|
||||||
|
<welcome-file>welcome.jsf</welcome-file>
|
||||||
|
<welcome-file>index.html</welcome-file>
|
||||||
|
<welcome-file>index.jsp</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
</web-app>
|
101
jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
Normal file
101
jee7/src/test/java/com/baeldung/convListVal/ConvListValTest.java
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package com.baeldung.convListVal;
|
||||||
|
|
||||||
|
import static org.jboss.arquillian.graphene.Graphene.guardHttp;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment;
|
||||||
|
import org.jboss.arquillian.container.test.api.RunAsClient;
|
||||||
|
import org.jboss.arquillian.drone.api.annotation.Drone;
|
||||||
|
import org.jboss.arquillian.junit.Arquillian;
|
||||||
|
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
|
||||||
|
@RunWith(Arquillian.class)
|
||||||
|
public class ConvListValTest {
|
||||||
|
|
||||||
|
@ArquillianResource
|
||||||
|
private URL deploymentUrl;
|
||||||
|
|
||||||
|
private static final String WEBAPP_SRC = "src/main/webapp";
|
||||||
|
|
||||||
|
@Deployment(testable = false)
|
||||||
|
public static WebArchive createDeployment() {
|
||||||
|
return ( ShrinkWrap.create(
|
||||||
|
WebArchive.class, "jee7.war").
|
||||||
|
addClasses(ConvListVal.class, MyListener.class)).
|
||||||
|
addAsWebResource(new File(WEBAPP_SRC, "ConvListVal.xhtml")).
|
||||||
|
addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Drone
|
||||||
|
WebDriver browser;
|
||||||
|
|
||||||
|
@ArquillianResource
|
||||||
|
URL contextPath;
|
||||||
|
|
||||||
|
@FindBy(id="myForm:age")
|
||||||
|
private WebElement ageInput;
|
||||||
|
|
||||||
|
@FindBy(id="myForm:average")
|
||||||
|
private WebElement averageInput;
|
||||||
|
|
||||||
|
@FindBy(id="myForm:send")
|
||||||
|
private WebElement sendButton;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RunAsClient
|
||||||
|
public void givenAge_whenAgeInvalid_thenErrorMessage() throws Exception {
|
||||||
|
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||||
|
ageInput.sendKeys("stringage");
|
||||||
|
guardHttp(sendButton).click();
|
||||||
|
Assert.assertTrue("Show Age error message", browser.findElements(By.id("myForm:ageError")).size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RunAsClient
|
||||||
|
public void givenAverage_whenAverageInvalid_thenErrorMessage() throws Exception {
|
||||||
|
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||||
|
averageInput.sendKeys("stringaverage");
|
||||||
|
guardHttp(sendButton).click();
|
||||||
|
Assert.assertTrue("Show Average error message", browser.findElements(By.id("myForm:averageError")).size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RunAsClient
|
||||||
|
public void givenDate_whenDateInvalid_thenErrorMessage() throws Exception {
|
||||||
|
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||||
|
averageInput.sendKeys("123");
|
||||||
|
guardHttp(sendButton).click();
|
||||||
|
Assert.assertTrue("Show Date error message", browser.findElements(By.id("myForm:myDateError")).size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RunAsClient
|
||||||
|
public void givenSurname_whenSurnameMinLenghtInvalid_thenErrorMessage() throws Exception {
|
||||||
|
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||||
|
averageInput.sendKeys("aaa");
|
||||||
|
guardHttp(sendButton).click();
|
||||||
|
Assert.assertTrue("Show Surname error message", browser.findElements(By.id("myForm:surnameError")).size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@RunAsClient
|
||||||
|
public void givenSurname_whenSurnameMaxLenghtInvalid_thenErrorMessage() throws Exception {
|
||||||
|
browser.get(deploymentUrl.toExternalForm() + "ConvListVal.jsf");
|
||||||
|
averageInput.sendKeys("aaaaabbbbbc");
|
||||||
|
guardHttp(sendButton).click();
|
||||||
|
Assert.assertTrue("Show Surname error message", browser.findElements(By.id("myForm:surnameError")).size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.jaxws;
|
/*package com.baeldung.jaxws;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@ -108,3 +108,4 @@ public class EmployeeServiceLiveTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
@ -5,6 +5,7 @@
|
|||||||
- [String Processing with Apache Commons Lang 3](http://www.baeldung.com/string-processing-commons-lang)
|
- [String Processing with Apache Commons Lang 3](http://www.baeldung.com/string-processing-commons-lang)
|
||||||
- [Introduction to Javatuples](http://www.baeldung.com/java-tuples)
|
- [Introduction to Javatuples](http://www.baeldung.com/java-tuples)
|
||||||
- [Introduction to Javassist](http://www.baeldung.com/javassist)
|
- [Introduction to Javassist](http://www.baeldung.com/javassist)
|
||||||
|
- [Embedded Jetty Server in Java](http://www.baeldung.com/jetty-embedded)
|
||||||
|
|
||||||
|
|
||||||
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
|
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-modules</artifactId>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
@ -20,6 +20,31 @@
|
|||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<version>3.3.0</version>
|
||||||
|
<type>maven-plugin</type>
|
||||||
|
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@ -72,6 +97,62 @@
|
|||||||
<artifactId>javers-core</artifactId>
|
<artifactId>javers-core</artifactId>
|
||||||
<version>${javers.version}</version>
|
<version>${javers.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons.io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-server</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
<version>${jetty.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons.io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.flink</groupId>
|
||||||
|
<artifactId>flink-core</artifactId>
|
||||||
|
<version>${flink.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.flink</groupId>
|
||||||
|
<artifactId>flink-java</artifactId>
|
||||||
|
<version>${flink.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.flink</groupId>
|
||||||
|
<artifactId>flink-test-utils_2.10</artifactId>
|
||||||
|
<version>${flink.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -84,6 +165,14 @@
|
|||||||
<assertj.version>3.6.2</assertj.version>
|
<assertj.version>3.6.2</assertj.version>
|
||||||
<jsonassert.version>1.5.0</jsonassert.version>
|
<jsonassert.version>1.5.0</jsonassert.version>
|
||||||
<javers.version>3.1.0</javers.version>
|
<javers.version>3.1.0</javers.version>
|
||||||
|
<jetty.version>9.4.3.v20170317</jetty.version>
|
||||||
|
<httpclient.version>4.5.3</httpclient.version>
|
||||||
|
<commons.io.version>2.5</commons.io.version>
|
||||||
|
<jetty.version>9.4.2.v20170220</jetty.version>
|
||||||
|
<httpclient.version>4.5.3</httpclient.version>
|
||||||
|
<commons.io.version>2.5</commons.io.version>
|
||||||
|
<flink.version>1.2.0</flink.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
20
libraries/src/main/java/com/baeldung/flink/LineSplitter.java
Normal file
20
libraries/src/main/java/com/baeldung/flink/LineSplitter.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.flink;
|
||||||
|
|
||||||
|
import org.apache.flink.api.common.functions.FlatMapFunction;
|
||||||
|
import org.apache.flink.api.java.tuple.Tuple2;
|
||||||
|
import org.apache.flink.util.Collector;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class LineSplitter implements FlatMapFunction<String, Tuple2<String, Integer>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
|
||||||
|
|
||||||
|
String[] tokens = value.toLowerCase().split("\\W+");
|
||||||
|
Stream.of(tokens)
|
||||||
|
.filter(t -> t.length() > 0)
|
||||||
|
.forEach(token -> out.collect(new Tuple2<>(token, 1)));
|
||||||
|
}
|
||||||
|
}
|
20
libraries/src/main/java/com/baeldung/flink/WordCount.java
Normal file
20
libraries/src/main/java/com/baeldung/flink/WordCount.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.flink;
|
||||||
|
|
||||||
|
import org.apache.flink.api.java.DataSet;
|
||||||
|
import org.apache.flink.api.java.ExecutionEnvironment;
|
||||||
|
import org.apache.flink.api.java.aggregation.Aggregations;
|
||||||
|
import org.apache.flink.api.java.tuple.Tuple2;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WordCount {
|
||||||
|
|
||||||
|
public static DataSet<Tuple2<String, Integer>> startWordCount(ExecutionEnvironment env, List<String> lines) throws Exception {
|
||||||
|
DataSet<String> text = env.fromCollection(lines);
|
||||||
|
|
||||||
|
return text.flatMap(new LineSplitter())
|
||||||
|
.groupBy(0)
|
||||||
|
.aggregate(Aggregations.SUM, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
libraries/src/main/java/com/baeldung/jetty/AsyncServlet.java
Normal file
42
libraries/src/main/java/com/baeldung/jetty/AsyncServlet.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.jetty;
|
||||||
|
|
||||||
|
import javax.servlet.AsyncContext;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.WriteListener;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class AsyncServlet extends HttpServlet {
|
||||||
|
private static final String HEAVY_RESOURCE = "This is some heavy resource that will be served in an async way";
|
||||||
|
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
ByteBuffer content = ByteBuffer.wrap(HEAVY_RESOURCE.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
AsyncContext async = request.startAsync();
|
||||||
|
ServletOutputStream out = response.getOutputStream();
|
||||||
|
out.setWriteListener(new WriteListener() {
|
||||||
|
@Override
|
||||||
|
public void onWritePossible() throws IOException {
|
||||||
|
while (out.isReady()) {
|
||||||
|
if (!content.hasRemaining()) {
|
||||||
|
response.setStatus(200);
|
||||||
|
async.complete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.write(content.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable t) {
|
||||||
|
getServletContext().log("Async Error", t);
|
||||||
|
async.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.jetty;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class BlockingServlet extends HttpServlet {
|
||||||
|
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
response.getWriter().println("{ \"status\": \"ok\"}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
39
libraries/src/main/java/com/baeldung/jetty/JettyServer.java
Normal file
39
libraries/src/main/java/com/baeldung/jetty/JettyServer.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.baeldung.jetty;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Connector;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.server.ServerConnector;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||||
|
|
||||||
|
public class JettyServer {
|
||||||
|
|
||||||
|
private Server server;
|
||||||
|
|
||||||
|
public void start() throws Exception {
|
||||||
|
|
||||||
|
int maxThreads = 100;
|
||||||
|
int minThreads = 10;
|
||||||
|
int idleTimeout = 120;
|
||||||
|
|
||||||
|
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, minThreads, idleTimeout);
|
||||||
|
|
||||||
|
server = new Server(threadPool);
|
||||||
|
ServerConnector connector = new ServerConnector(server);
|
||||||
|
connector.setPort(8090);
|
||||||
|
server.setConnectors(new Connector[]{connector});
|
||||||
|
|
||||||
|
ServletHandler servletHandler = new ServletHandler();
|
||||||
|
server.setHandler(servletHandler);
|
||||||
|
|
||||||
|
servletHandler.addServletWithMapping(BlockingServlet.class, "/status");
|
||||||
|
servletHandler.addServletWithMapping(AsyncServlet.class, "/heavy/async");
|
||||||
|
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws Exception {
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
package com.baeldung.flink;
|
||||||
|
|
||||||
|
import org.apache.flink.api.common.operators.Order;
|
||||||
|
import org.apache.flink.api.java.DataSet;
|
||||||
|
import org.apache.flink.api.java.ExecutionEnvironment;
|
||||||
|
import org.apache.flink.api.java.functions.KeySelector;
|
||||||
|
import org.apache.flink.api.java.tuple.Tuple2;
|
||||||
|
import org.apache.flink.api.java.tuple.Tuple3;
|
||||||
|
import org.apache.flink.streaming.api.datastream.DataStream;
|
||||||
|
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
|
||||||
|
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
|
||||||
|
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor;
|
||||||
|
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
|
||||||
|
import org.apache.flink.streaming.api.windowing.time.Time;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
|
||||||
|
public class WordCountIntegrationTest {
|
||||||
|
private final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDataSet_whenExecuteWordCount_thenReturnWordCount() throws Exception {
|
||||||
|
//given
|
||||||
|
List<String> lines = Arrays.asList("This is a first sentence", "This is a second sentence with a one word");
|
||||||
|
|
||||||
|
//when
|
||||||
|
DataSet<Tuple2<String, Integer>> result = WordCount.startWordCount(env, lines);
|
||||||
|
|
||||||
|
//then
|
||||||
|
List<Tuple2<String, Integer>> collect = result.collect();
|
||||||
|
assertThat(collect).containsExactlyInAnyOrder(
|
||||||
|
new Tuple2<>("a", 3), new Tuple2<>("sentence", 2), new Tuple2<>("word", 1),
|
||||||
|
new Tuple2<>("is", 2), new Tuple2<>("this", 2), new Tuple2<>("second", 1),
|
||||||
|
new Tuple2<>("first", 1), new Tuple2<>("with", 1), new Tuple2<>("one", 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenListOfAmounts_whenUseMapReduce_thenSumAmountsThatAreOnlyAboveThreshold() throws Exception {
|
||||||
|
//given
|
||||||
|
DataSet<Integer> amounts = env.fromElements(1, 29, 40, 50);
|
||||||
|
int threshold = 30;
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Integer> collect = amounts
|
||||||
|
.filter(a -> a > threshold)
|
||||||
|
.reduce((integer, t1) -> integer + t1)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(collect.get(0)).isEqualTo(90);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDataSetOfComplexObjects_whenMapToGetOneField_thenReturnedListHaveProperElements() throws Exception {
|
||||||
|
//given
|
||||||
|
DataSet<Person> personDataSource = env.fromCollection(Arrays.asList(new Person(23, "Tom"), new Person(75, "Michael")));
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Integer> ages = personDataSource.map(p -> p.age).collect();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(ages).hasSize(2);
|
||||||
|
assertThat(ages).contains(23, 75);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDataSet_whenSortItByOneField_thenShouldReturnSortedDataSet() throws Exception {
|
||||||
|
//given
|
||||||
|
Tuple2<Integer, String> secondPerson = new Tuple2<>(4, "Tom");
|
||||||
|
Tuple2<Integer, String> thirdPerson = new Tuple2<>(5, "Scott");
|
||||||
|
Tuple2<Integer, String> fourthPerson = new Tuple2<>(200, "Michael");
|
||||||
|
Tuple2<Integer, String> firstPerson = new Tuple2<>(1, "Jack");
|
||||||
|
DataSet<Tuple2<Integer, String>> transactions = env.fromElements(fourthPerson, secondPerson,
|
||||||
|
thirdPerson, firstPerson);
|
||||||
|
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Tuple2<Integer, String>> sorted = transactions
|
||||||
|
.sortPartition(new IdKeySelectorTransaction(), Order.ASCENDING)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(sorted).containsExactly(firstPerson, secondPerson, thirdPerson, fourthPerson);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void giveTwoDataSets_whenJoinUsingId_thenProduceJoinedData() throws Exception {
|
||||||
|
//given
|
||||||
|
Tuple3<Integer, String, String> address = new Tuple3<>(1, "5th Avenue", "London");
|
||||||
|
DataSet<Tuple3<Integer, String, String>> addresses = env.fromElements(address);
|
||||||
|
|
||||||
|
Tuple2<Integer, String> firstTransaction = new Tuple2<>(1, "Transaction_1");
|
||||||
|
DataSet<Tuple2<Integer, String>> transactions =
|
||||||
|
env.fromElements(firstTransaction, new Tuple2<>(12, "Transaction_2"));
|
||||||
|
|
||||||
|
|
||||||
|
//when
|
||||||
|
List<Tuple2<Tuple2<Integer, String>, Tuple3<Integer, String, String>>> joined =
|
||||||
|
transactions.join(addresses)
|
||||||
|
.where(new IdKeySelectorTransaction())
|
||||||
|
.equalTo(new IdKeySelectorAddress())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(joined).hasSize(1);
|
||||||
|
assertThat(joined).contains(new Tuple2<>(firstTransaction, address));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStreamOfEvents_whenProcessEvents_thenShouldPrintResultsOnSinkOperation() throws Exception {
|
||||||
|
//given
|
||||||
|
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
|
||||||
|
|
||||||
|
DataStream<String> text
|
||||||
|
= env.fromElements("This is a first sentence", "This is a second sentence with a one word");
|
||||||
|
|
||||||
|
|
||||||
|
SingleOutputStreamOperator<String> upperCase = text.map(String::toUpperCase);
|
||||||
|
|
||||||
|
upperCase.print();
|
||||||
|
|
||||||
|
//when
|
||||||
|
env.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenStreamOfEvents_whenProcessEvents_thenShouldApplyWindowingOnTransformation() throws Exception {
|
||||||
|
//given
|
||||||
|
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
|
||||||
|
|
||||||
|
SingleOutputStreamOperator<Tuple2<Integer, Long>> windowed = env.fromElements(
|
||||||
|
new Tuple2<>(16, ZonedDateTime.now().plusMinutes(25).toInstant().getEpochSecond()),
|
||||||
|
new Tuple2<>(15, ZonedDateTime.now().plusMinutes(2).toInstant().getEpochSecond())
|
||||||
|
).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<Tuple2<Integer, Long>>(Time.seconds(20)) {
|
||||||
|
@Override
|
||||||
|
public long extractTimestamp(Tuple2<Integer, Long> element) {
|
||||||
|
return element.f1 * 1000;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SingleOutputStreamOperator<Tuple2<Integer, Long>> reduced = windowed
|
||||||
|
.windowAll(TumblingEventTimeWindows.of(Time.seconds(5)))
|
||||||
|
.maxBy(0, true);
|
||||||
|
|
||||||
|
reduced.print();
|
||||||
|
|
||||||
|
//when
|
||||||
|
env.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class IdKeySelectorTransaction implements KeySelector<Tuple2<Integer, String>, Integer> {
|
||||||
|
@Override
|
||||||
|
public Integer getKey(Tuple2<Integer, String> value) {
|
||||||
|
return value.f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IdKeySelectorAddress implements KeySelector<Tuple3<Integer, String, String>, Integer> {
|
||||||
|
@Override
|
||||||
|
public Integer getKey(Tuple3<Integer, String, String> value) {
|
||||||
|
return value.f0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Person {
|
||||||
|
private final int age;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private Person(int age, String name) {
|
||||||
|
this.age = age;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
libraries/src/test/java/com/baeldung/jetty/JettyTest.java
Normal file
58
libraries/src/test/java/com/baeldung/jetty/JettyTest.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package com.baeldung.jetty;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||||
|
|
||||||
|
public class JettyTest {
|
||||||
|
private JettyServer jettyServer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
jettyServer = new JettyServer();
|
||||||
|
jettyServer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() throws Exception {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
jettyServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenServer_whenSendRequestToBlockingServlet_thenReturnStatusOK() throws Exception {
|
||||||
|
//given
|
||||||
|
String url = "http://localhost:8090/status";
|
||||||
|
HttpClient client = HttpClientBuilder.create().build();
|
||||||
|
HttpGet request = new HttpGet(url);
|
||||||
|
HttpResponse response = client.execute(request);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenServer_whenSendRequestToNonBlockingServlet_thenReturnStatusOK() throws Exception {
|
||||||
|
//when
|
||||||
|
String url = "http://localhost:8090/heavy/async";
|
||||||
|
HttpClient client = HttpClientBuilder.create().build();
|
||||||
|
HttpGet request = new HttpGet(url);
|
||||||
|
HttpResponse response = client.execute(request);
|
||||||
|
|
||||||
|
//then
|
||||||
|
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
|
||||||
|
String responseContent = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
assertThat(responseContent).isEqualTo("This is some heavy resource that will be served in an async way");
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,16 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package com.mogronalol;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class DemoApplication {
|
public class DemoApplication {
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
package com.mogronalol;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
@ -1,11 +1,10 @@
|
|||||||
package com.mogronalol;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringBootTest(classes = {DemoApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(classes = {DemoApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
public class DemoApplicationTests {
|
public class DemoApplicationIntegrationTest {
|
||||||
|
|
||||||
private RestTemplate restTemplate;
|
private RestTemplate restTemplate;
|
||||||
|
|
@ -2,8 +2,6 @@ package org.baeldung.mockito;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
@ -69,7 +67,7 @@ public class MockitoConfigExamplesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenMockMethodCallIsConfiguredToCallTheRealMethod_thenRealMetehodIsCalled() {
|
public final void whenMockMethodCallIsConfiguredToCallTheRealMethod_thenRealMethodIsCalled() {
|
||||||
final MyList listMock = Mockito.mock(MyList.class);
|
final MyList listMock = Mockito.mock(MyList.class);
|
||||||
when(listMock.size()).thenCallRealMethod();
|
when(listMock.size()).thenCallRealMethod();
|
||||||
|
|
||||||
@ -77,14 +75,9 @@ public class MockitoConfigExamplesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public final void whenMockMethodCallIsConfiguredWithCustomAnswer_thenRealMetehodIsCalled() {
|
public final void whenMockMethodCallIsConfiguredWithCustomAnswer_thenRealMethodIsCalled() {
|
||||||
final MyList listMock = Mockito.mock(MyList.class);
|
final MyList listMock = Mockito.mock(MyList.class);
|
||||||
doAnswer(new Answer<String>() {
|
doAnswer(invocation -> "Always the same").when(listMock).get(anyInt());
|
||||||
@Override
|
|
||||||
public final String answer(final InvocationOnMock invocation) {
|
|
||||||
return "Always the same";
|
|
||||||
}
|
|
||||||
}).when(listMock).get(anyInt());
|
|
||||||
|
|
||||||
final String element = listMock.get(1);
|
final String element = listMock.get(1);
|
||||||
assertThat(element, is(equalTo("Always the same")));
|
assertThat(element, is(equalTo("Always the same")));
|
||||||
|
34
mybatis/pom.xml
Normal file
34
mybatis/pom.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<properties>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
<derby.version>10.13.1.1</derby.version>
|
||||||
|
<mybatis.version>3.2.2</mybatis.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.derby</groupId>
|
||||||
|
<artifactId>derby</artifactId>
|
||||||
|
<version>${derby.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
<version>${mybatis.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.mybatis.mapper;
|
||||||
|
|
||||||
|
import com.baeldung.mybatis.model.Address;
|
||||||
|
import com.baeldung.mybatis.model.Person;
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
|
||||||
|
|
||||||
|
public interface AddressMapper {
|
||||||
|
|
||||||
|
@Insert("Insert into address (streetAddress,personId) values(#{streetAddress},#{personId})")
|
||||||
|
@Options(useGeneratedKeys = true,flushCache=true )
|
||||||
|
public Integer saveAddress(Address address);
|
||||||
|
|
||||||
|
@Select("SELECT addressId, streetAddress FROM Address WHERE addressId = #{addressId}")
|
||||||
|
@Results(value = {
|
||||||
|
@Result(property = "addressId", column = "addressId"),
|
||||||
|
@Result(property = "streetAddress", column = "streetAddress"),
|
||||||
|
@Result(property = "person", column = "personId",javaType =Person.class,one=@One(select = "getPerson"))
|
||||||
|
})
|
||||||
|
Address getAddresses(Integer addressID);
|
||||||
|
|
||||||
|
@Select("SELECT personId FROM address WHERE addressId = #{addressId})")
|
||||||
|
Person getPerson(Integer personId);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.baeldung.mybatis.mapper;
|
||||||
|
|
||||||
|
import com.baeldung.mybatis.model.Address;
|
||||||
|
import com.baeldung.mybatis.model.Person;
|
||||||
|
import com.baeldung.mybatis.utils.MyBatisUtil;
|
||||||
|
import org.apache.ibatis.annotations.*;
|
||||||
|
import org.apache.ibatis.mapping.StatementType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public interface PersonMapper {
|
||||||
|
|
||||||
|
@Insert("Insert into person(name) values (#{name})")
|
||||||
|
public Integer save(Person person);
|
||||||
|
|
||||||
|
@Update("Update Person set name= #{name} where personId=#{personId}")
|
||||||
|
public void updatePerson(Person person);
|
||||||
|
|
||||||
|
@Delete("Delete from Person where personId=#{personId}")
|
||||||
|
public void deletePersonById(Integer personId);
|
||||||
|
|
||||||
|
@Select("SELECT person.personId, person.name FROM person WHERE person.personId = #{personId}")
|
||||||
|
Person getPerson(Integer personId);
|
||||||
|
|
||||||
|
@Select("Select personId,name from Person where personId=#{personId}")
|
||||||
|
@Results(value ={
|
||||||
|
@Result(property = "personId", column = "personId"),
|
||||||
|
@Result(property="name", column = "name"),
|
||||||
|
@Result(property = "addresses",javaType = List.class,column = "personId",
|
||||||
|
many=@Many(select = "getAddresses"))
|
||||||
|
|
||||||
|
})
|
||||||
|
public Person getPersonById(Integer personId);
|
||||||
|
|
||||||
|
@Select("select addressId,streetAddress,personId from address where personId=#{personId}")
|
||||||
|
public Address getAddresses(Integer personId);
|
||||||
|
|
||||||
|
@Select("select * from Person ")
|
||||||
|
@MapKey("personId")
|
||||||
|
Map<Integer,Person> getAllPerson();
|
||||||
|
|
||||||
|
@SelectProvider(type=MyBatisUtil.class,method="getPersonByName")
|
||||||
|
public Person getPersonByName(String name);
|
||||||
|
|
||||||
|
|
||||||
|
@Select(value= "{ CALL getPersonByProc( #{personId, mode=IN, jdbcType=INTEGER})}")
|
||||||
|
@Options(statementType = StatementType.CALLABLE)
|
||||||
|
public Person getPersonByProc(Integer personId);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.baeldung.mybatis.model;
|
||||||
|
|
||||||
|
|
||||||
|
public class Address {
|
||||||
|
|
||||||
|
private Integer addressId;
|
||||||
|
private String streetAddress;
|
||||||
|
private Integer personId;
|
||||||
|
|
||||||
|
public Address() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPersonId() {
|
||||||
|
return personId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonId(Integer personId) {
|
||||||
|
this.personId = personId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Address(String streetAddress) {
|
||||||
|
this.streetAddress =streetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person getPerson() {
|
||||||
|
return person;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPerson(Person person) {
|
||||||
|
this.person = person;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Person person;
|
||||||
|
|
||||||
|
public Address(int i, String name) {
|
||||||
|
this.streetAddress = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAddressId() {
|
||||||
|
return addressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStreetAddress() {
|
||||||
|
return streetAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
Normal file
40
mybatis/src/main/java/com/baeldung/mybatis/model/Person.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung.mybatis.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public class Person {
|
||||||
|
|
||||||
|
private Integer personId;
|
||||||
|
private String name;
|
||||||
|
private List<Address> addresses;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(Integer personId, String name) {
|
||||||
|
this.personId=personId;
|
||||||
|
this.name = name;
|
||||||
|
addresses = new ArrayList<Address>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(String name) {
|
||||||
|
this.name=name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPersonId() {
|
||||||
|
return personId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void addAddress(Address address){
|
||||||
|
addresses.add(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Address> getAddresses() {
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.mybatis.utils;
|
||||||
|
import org.apache.ibatis.io.Resources;
|
||||||
|
import org.apache.ibatis.jdbc.SQL;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class MyBatisUtil {
|
||||||
|
private static SqlSessionFactory sqlSessionFactory;
|
||||||
|
static {
|
||||||
|
String resource = "mybatis-config.xml";
|
||||||
|
InputStream inputStream;
|
||||||
|
try {
|
||||||
|
inputStream = Resources.getResourceAsStream(resource);
|
||||||
|
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static SqlSessionFactory getSqlSessionFactory(){
|
||||||
|
return sqlSessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPersonByName(String name){
|
||||||
|
return new SQL(){{
|
||||||
|
SELECT("*");
|
||||||
|
FROM("person");
|
||||||
|
WHERE("name like #{name} || '%'");
|
||||||
|
}}.toString();
|
||||||
|
}
|
||||||
|
}
|
21
mybatis/src/main/resources/mybatis-config.xml
Normal file
21
mybatis/src/main/resources/mybatis-config.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE configuration
|
||||||
|
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||||
|
<configuration>
|
||||||
|
<environments default="development">
|
||||||
|
<environment id="development">
|
||||||
|
<transactionManager type="JDBC"/>
|
||||||
|
<dataSource type="POOLED">
|
||||||
|
<property name="driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
|
||||||
|
<property name="url" value="jdbc:derby:testdb1;create=true"/>
|
||||||
|
<property name="username" value="sa"/>
|
||||||
|
<property name="password" value="pass123"/>
|
||||||
|
</dataSource>
|
||||||
|
</environment>
|
||||||
|
</environments>
|
||||||
|
<mappers>
|
||||||
|
<mapper class="com.baeldung.mybatis.mapper.PersonMapper"/>
|
||||||
|
<mapper class="com.baeldung.mybatis.mapper.AddressMapper"/>
|
||||||
|
</mappers>
|
||||||
|
</configuration>
|
@ -0,0 +1,149 @@
|
|||||||
|
package com.baeldung.mybatis.mapper;
|
||||||
|
|
||||||
|
import com.baeldung.mybatis.model.Address;
|
||||||
|
import com.baeldung.mybatis.model.Person;
|
||||||
|
import com.baeldung.mybatis.utils.MyBatisUtil;
|
||||||
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
public class PersonMapperTest {
|
||||||
|
|
||||||
|
SqlSession session;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws SQLException {
|
||||||
|
|
||||||
|
session = MyBatisUtil.getSqlSessionFactory().openSession();
|
||||||
|
createTables(session);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTables(SqlSession session) throws SQLException {
|
||||||
|
|
||||||
|
String createPersonTable = "create table person ("
|
||||||
|
+ "personId integer not null generated always as"
|
||||||
|
+ " identity (start with 1, increment by 1), "
|
||||||
|
+ "name varchar(30) not null, "
|
||||||
|
+ "constraint primary_key_person primary key (personId))";
|
||||||
|
|
||||||
|
String createAddressTable = "create table address ("
|
||||||
|
+ "addressId integer not null generated always as"
|
||||||
|
+ " identity (start with 1, increment by 1), "
|
||||||
|
+ "streetAddress varchar(300), personId integer, "
|
||||||
|
+ "constraint primary_key_address primary key (addressId))";
|
||||||
|
|
||||||
|
String alterTable="ALTER TABLE " +
|
||||||
|
" address ADD CONSTRAINT fk_person FOREIGN KEY (personId) REFERENCES person (personId)";
|
||||||
|
|
||||||
|
|
||||||
|
session.getConnection().createStatement().execute(createPersonTable);
|
||||||
|
session.getConnection().createStatement().execute(createAddressTable);
|
||||||
|
session.getConnection().createStatement().execute(alterTable);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonAdressSaved_ThenPersonAddressCanBeQueried(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
addressMapper.saveAddress(address);
|
||||||
|
|
||||||
|
Person returnedPerson= personMapper.getPersonById(id);
|
||||||
|
assertEquals("Baljeet S", returnedPerson.getName());
|
||||||
|
assertEquals("Pune", returnedPerson.getAddresses().get(0).getStreetAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonSaved_ThenPersonCanBeQueried(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
addressMapper.saveAddress(address);
|
||||||
|
|
||||||
|
Person returnedPerson= personMapper.getPerson(id);
|
||||||
|
assertEquals("Baljeet S", returnedPerson.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonUpdated_ThenPersonIsChanged(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
addressMapper.saveAddress(address);
|
||||||
|
|
||||||
|
personMapper.updatePerson(new Person(id,"Baljeet1"));
|
||||||
|
Person returnedPerson= personMapper.getPerson(id);
|
||||||
|
assertEquals("Baljeet1", returnedPerson.getName());
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void whenPersoSaved_ThenMapIsReturned(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
addressMapper.saveAddress(address);
|
||||||
|
|
||||||
|
Map<Integer, Person> returnedPerson= personMapper.getAllPerson();
|
||||||
|
assertEquals(1, returnedPerson.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenPersonSearched_ThenResultIsReturned(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
addressMapper.saveAddress(address);
|
||||||
|
|
||||||
|
Person returnedPerson= personMapper.getPersonByName("Baljeet S");
|
||||||
|
assertEquals("Baljeet S", returnedPerson.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAddressSearched_ThenResultIsReturned(){
|
||||||
|
Person person=new Person("Baljeet S");
|
||||||
|
Address address = new Address("Pune");
|
||||||
|
PersonMapper personMapper=session.getMapper(PersonMapper.class);
|
||||||
|
Integer id =personMapper.save(person);
|
||||||
|
address.setPersonId(id);
|
||||||
|
AddressMapper addressMapper=session.getMapper(AddressMapper.class);
|
||||||
|
Integer addressId=addressMapper.saveAddress(address);
|
||||||
|
Address returnedAddress=addressMapper.getAddresses(addressId);
|
||||||
|
|
||||||
|
assertEquals("Pune", returnedAddress.getStreetAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() throws SQLException {
|
||||||
|
session.getConnection().createStatement().execute("drop table address");
|
||||||
|
session.getConnection().createStatement().execute("drop table person");
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
pom.xml
9
pom.xml
@ -35,7 +35,7 @@
|
|||||||
<module>deltaspike</module>
|
<module>deltaspike</module>
|
||||||
<module>dozer</module>
|
<module>dozer</module>
|
||||||
|
|
||||||
<module>ejb</module>
|
<!--<module>ejb</module>-->
|
||||||
|
|
||||||
<module>feign</module>
|
<module>feign</module>
|
||||||
<module>flyway</module>
|
<module>flyway</module>
|
||||||
@ -66,7 +66,7 @@
|
|||||||
<module>javax-servlets</module>
|
<module>javax-servlets</module>
|
||||||
<module>javaxval</module>
|
<module>javaxval</module>
|
||||||
<module>jaxb</module>
|
<module>jaxb</module>
|
||||||
<module>jee7</module>
|
<!--<module>jee7</module>-->
|
||||||
<!-- <module>jhipster</module> -->
|
<!-- <module>jhipster</module> -->
|
||||||
<module>jjwt</module>
|
<module>jjwt</module>
|
||||||
<module>jooq</module>
|
<module>jooq</module>
|
||||||
@ -153,7 +153,6 @@
|
|||||||
<module>spring-mvc-email</module>
|
<module>spring-mvc-email</module>
|
||||||
<module>spring-mvc-forms</module>
|
<module>spring-mvc-forms</module>
|
||||||
<module>spring-mvc-java</module>
|
<module>spring-mvc-java</module>
|
||||||
<module>spring-mvc-no-xml</module>
|
|
||||||
<module>spring-mvc-tiles</module>
|
<module>spring-mvc-tiles</module>
|
||||||
<module>spring-mvc-velocity</module>
|
<module>spring-mvc-velocity</module>
|
||||||
<module>spring-mvc-web-vs-initializer</module>
|
<module>spring-mvc-web-vs-initializer</module>
|
||||||
@ -215,6 +214,8 @@
|
|||||||
<module>rabbitmq</module>
|
<module>rabbitmq</module>
|
||||||
<module>vertx</module>
|
<module>vertx</module>
|
||||||
<module>spring-data-gemfire</module>
|
<module>spring-data-gemfire</module>
|
||||||
|
<module>cucumber</module>
|
||||||
|
<module>mybatis</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -233,6 +234,8 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<forkCount>3</forkCount>
|
||||||
|
<reuseForks>true</reuseForks>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<exclude>**/*LongRunningUnitTest.java</exclude>
|
<exclude>**/*LongRunningUnitTest.java</exclude>
|
||||||
|
@ -181,6 +181,8 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<forkCount>3</forkCount>
|
||||||
|
<reuseForks>true</reuseForks>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<exclude>**/*LiveTest.java</exclude>
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
|
@ -1,164 +1,171 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>rest-testing</artifactId>
|
<artifactId>rest-testing</artifactId>
|
||||||
<version>0.1-SNAPSHOT</version>
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
|
||||||
<name>rest-testing</name>
|
<name>rest-testing</name>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<!-- utils -->
|
<!-- utils -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>${commons-io.version}</version>
|
<version>${commons-io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- http client -->
|
<!-- http client -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>${httpclient.version}</version>
|
<version>${httpclient.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpcore</artifactId>
|
<artifactId>httpcore</artifactId>
|
||||||
<version>${httpcore.version}</version>
|
<version>${httpcore.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- marshalling -->
|
<!-- marshalling -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- logging -->
|
<!-- logging -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ch.qos.logback</groupId>
|
<groupId>ch.qos.logback</groupId>
|
||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>${logback.version}</version>
|
<version>${logback.version}</version>
|
||||||
<!-- <scope>runtime</scope> -->
|
<!-- <scope>runtime</scope> -->
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
<dependency> <!-- needed to bridge to slf4j for projects that use the log4j APIs directly -->
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>log4j-over-slf4j</artifactId>
|
<artifactId>log4j-over-slf4j</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- test scoped -->
|
<!-- test scoped -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-core</artifactId>
|
<artifactId>hamcrest-core</artifactId>
|
||||||
<version>${org.hamcrest.version}</version>
|
<version>${org.hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>hamcrest-library</artifactId>
|
<artifactId>hamcrest-library</artifactId>
|
||||||
<version>${org.hamcrest.version}</version>
|
<version>${org.hamcrest.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.tomakehurst</groupId>
|
<groupId>com.github.tomakehurst</groupId>
|
||||||
<artifactId>wiremock</artifactId>
|
<artifactId>wiremock</artifactId>
|
||||||
<version>${wiremock.version}</version>
|
<version>${wiremock.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.cukes</groupId>
|
<groupId>info.cukes</groupId>
|
||||||
<artifactId>cucumber-java</artifactId>
|
<artifactId>cucumber-java</artifactId>
|
||||||
<version>${cucumber.version}</version>
|
<version>${cucumber.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.cukes</groupId>
|
<groupId>info.cukes</groupId>
|
||||||
<artifactId>cucumber-junit</artifactId>
|
<artifactId>cucumber-junit</artifactId>
|
||||||
<version>${cucumber.version}</version>
|
<version>${cucumber.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
<dependency>
|
||||||
<finalName>rest-testing</finalName>
|
<groupId>org.jbehave</groupId>
|
||||||
<resources>
|
<artifactId>jbehave-core</artifactId>
|
||||||
<resource>
|
<version>${jbehave.version}</version>
|
||||||
<directory>src/main/resources</directory>
|
<scope>test</scope>
|
||||||
<filtering>true</filtering>
|
</dependency>
|
||||||
</resource>
|
</dependencies>
|
||||||
</resources>
|
|
||||||
|
|
||||||
<plugins>
|
<build>
|
||||||
|
<finalName>rest-testing</finalName>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
<plugin>
|
<plugins>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>${maven-compiler-plugin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>${maven-surefire-plugin.version}</version>
|
<version>${maven-compiler-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*IntegrationTest.java</exclude>
|
<exclude>**/*IntegrationTest.java</exclude>
|
||||||
<exclude>**/*LiveTest.java</exclude>
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
@ -177,10 +184,10 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*UnitTest.java</exclude>
|
<exclude>**/*UnitTest.java</exclude>
|
||||||
|
<exclude>**/*LiveTest.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/*IntegrationTest.java</include>
|
<include>**/*IntegrationTest.java</include>
|
||||||
<exclude>**/*LiveTest.java</exclude>
|
|
||||||
</includes>
|
</includes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
@ -196,36 +203,37 @@
|
|||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- marshalling -->
|
<!-- marshalling -->
|
||||||
<jackson.version>2.8.5</jackson.version>
|
<jackson.version>2.8.5</jackson.version>
|
||||||
|
|
||||||
<!-- logging -->
|
<!-- logging -->
|
||||||
<org.slf4j.version>1.7.21</org.slf4j.version>
|
<org.slf4j.version>1.7.21</org.slf4j.version>
|
||||||
<logback.version>1.1.7</logback.version>
|
<logback.version>1.1.7</logback.version>
|
||||||
|
|
||||||
<!-- util -->
|
<!-- util -->
|
||||||
<guava.version>19.0</guava.version>
|
<guava.version>19.0</guava.version>
|
||||||
<commons-lang3.version>3.5</commons-lang3.version>
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
<commons-io.version>2.5</commons-io.version>
|
<commons-io.version>2.5</commons-io.version>
|
||||||
|
|
||||||
<!-- testing -->
|
<!-- testing -->
|
||||||
<org.hamcrest.version>1.3</org.hamcrest.version>
|
<org.hamcrest.version>1.3</org.hamcrest.version>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<mockito.version>1.10.19</mockito.version>
|
<mockito.version>1.10.19</mockito.version>
|
||||||
<rest-assured.version>2.9.0</rest-assured.version>
|
<rest-assured.version>2.9.0</rest-assured.version>
|
||||||
<cucumber.version>1.2.5</cucumber.version>
|
<cucumber.version>1.2.5</cucumber.version>
|
||||||
<wiremock.version>2.4.1</wiremock.version>
|
<wiremock.version>2.4.1</wiremock.version>
|
||||||
|
|
||||||
<httpcore.version>4.4.5</httpcore.version>
|
<httpcore.version>4.4.5</httpcore.version>
|
||||||
<httpclient.version>4.5.2</httpclient.version>
|
<httpclient.version>4.5.2</httpclient.version>
|
||||||
|
|
||||||
|
<jbehave.version>4.1</jbehave.version>
|
||||||
|
|
||||||
<!-- maven plugins -->
|
<!-- maven plugins -->
|
||||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
<maven-war-plugin.version>2.6</maven-war-plugin.version>
|
||||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.baeldung.rest.jbehave;
|
||||||
|
|
||||||
|
import org.jbehave.core.configuration.Configuration;
|
||||||
|
import org.jbehave.core.configuration.MostUsefulConfiguration;
|
||||||
|
import org.jbehave.core.io.LoadFromClasspath;
|
||||||
|
import org.jbehave.core.junit.JUnitStories;
|
||||||
|
import org.jbehave.core.reporters.StoryReporterBuilder;
|
||||||
|
import org.jbehave.core.steps.InjectableStepsFactory;
|
||||||
|
import org.jbehave.core.steps.InstanceStepsFactory;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
|
||||||
|
import static org.jbehave.core.reporters.Format.CONSOLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aiet
|
||||||
|
*/
|
||||||
|
public abstract class AbstractStory extends JUnitStories {
|
||||||
|
|
||||||
|
abstract String storyName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Configuration configuration() {
|
||||||
|
return new MostUsefulConfiguration()
|
||||||
|
.useStoryLoader(new LoadFromClasspath(this.getClass()))
|
||||||
|
.useStoryReporterBuilder(new StoryReporterBuilder()
|
||||||
|
.withCodeLocation(codeLocationFromClass(this.getClass()))
|
||||||
|
.withFormats(CONSOLE));
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract Object stepInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InjectableStepsFactory stepsFactory() {
|
||||||
|
return new InstanceStepsFactory(configuration(), stepInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> storyPaths() {
|
||||||
|
return Arrays.asList(storyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.rest.jbehave;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.jbehave.core.annotations.Given;
|
||||||
|
import org.jbehave.core.annotations.Then;
|
||||||
|
import org.jbehave.core.annotations.When;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||||
|
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GithubUserNotFoundSteps {
|
||||||
|
|
||||||
|
private String api;
|
||||||
|
private String nonExistentUser;
|
||||||
|
private int githubResponseCode;
|
||||||
|
|
||||||
|
@Given("github user profile api")
|
||||||
|
public void givenGithubUserProfileApi() {
|
||||||
|
api = "https://api.github.com/users/%s";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Given("a random non-existent username")
|
||||||
|
public void givenANonexistentUsername() {
|
||||||
|
nonExistentUser = randomAlphabetic(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@When("I look for the random user via the api")
|
||||||
|
public void whenILookForTheUserViaTheApi() throws IOException {
|
||||||
|
githubResponseCode = getGithubUserProfile(api, nonExistentUser)
|
||||||
|
.getStatusLine()
|
||||||
|
.getStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@When("I look for $user via the api")
|
||||||
|
public void whenILookForSomeNonExistentUserViaTheApi(String user) throws IOException {
|
||||||
|
githubResponseCode = getGithubUserProfile(api, user)
|
||||||
|
.getStatusLine()
|
||||||
|
.getStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
static HttpResponse getGithubUserProfile(String api, String username) throws IOException {
|
||||||
|
HttpUriRequest request = new HttpGet(String.format(api, username));
|
||||||
|
return HttpClientBuilder
|
||||||
|
.create()
|
||||||
|
.build()
|
||||||
|
.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Then("github respond: 404 not found")
|
||||||
|
public void thenGithubRespond404NotFound() {
|
||||||
|
assertTrue(SC_NOT_FOUND == githubResponseCode);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.baeldung.rest.jbehave;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author aiet
|
||||||
|
*/
|
||||||
|
public class GithubUserNotFoundStoryLiveTest extends AbstractStory {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String storyName() {
|
||||||
|
return "github_user_not_found.story";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Object stepInstance() {
|
||||||
|
return new GithubUserNotFoundSteps();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user