Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
5160ff98d8
|
@ -0,0 +1,22 @@
|
||||||
|
package com.baeldung.java14.record;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public record Person (String name, String address) {
|
||||||
|
|
||||||
|
public static String UNKWOWN_ADDRESS = "Unknown";
|
||||||
|
public static String UNNAMED = "Unnamed";
|
||||||
|
|
||||||
|
public Person {
|
||||||
|
Objects.requireNonNull(name);
|
||||||
|
Objects.requireNonNull(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Person(String name) {
|
||||||
|
this(name, UNKWOWN_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Person unnamed(String address) {
|
||||||
|
return new Person(UNNAMED, address);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.baeldung.java14.foreign.api;
|
||||||
|
|
||||||
|
import jdk.incubator.foreign.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.lang.invoke.VarHandle;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public class ForeignMemoryUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAValueIsSet_thenAccessTheValue() {
|
||||||
|
long value = 10;
|
||||||
|
MemoryAddress memoryAddress =
|
||||||
|
MemorySegment.allocateNative(8).baseAddress();
|
||||||
|
VarHandle varHandle = MemoryHandles.varHandle(long.class,
|
||||||
|
ByteOrder.nativeOrder());
|
||||||
|
varHandle.set(memoryAddress, value);
|
||||||
|
assertThat(varHandle.get(memoryAddress), is(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenMultipleValuesAreSet_thenAccessAll() {
|
||||||
|
VarHandle varHandle = MemoryHandles.varHandle(int.class,
|
||||||
|
ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
try(MemorySegment memorySegment =
|
||||||
|
MemorySegment.allocateNative(100)) {
|
||||||
|
MemoryAddress base = memorySegment.baseAddress();
|
||||||
|
for(int i=0; i<25; i++) {
|
||||||
|
varHandle.set(base.addOffset((i*4)), i);
|
||||||
|
}
|
||||||
|
for(int i=0; i<25; i++) {
|
||||||
|
assertThat(varHandle.get(base.addOffset((i*4))), is(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSetValuesWithMemoryLayout_thenTheyCanBeRetrieved() {
|
||||||
|
SequenceLayout sequenceLayout =
|
||||||
|
MemoryLayout.ofSequence(25,
|
||||||
|
MemoryLayout.ofValueBits(64, ByteOrder.nativeOrder()));
|
||||||
|
VarHandle varHandle =
|
||||||
|
sequenceLayout.varHandle(long.class,
|
||||||
|
MemoryLayout.PathElement.sequenceElement());
|
||||||
|
|
||||||
|
try(MemorySegment memorySegment =
|
||||||
|
MemorySegment.allocateNative(sequenceLayout)) {
|
||||||
|
MemoryAddress base = memorySegment.baseAddress();
|
||||||
|
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||||
|
varHandle.set(base, i, i);
|
||||||
|
}
|
||||||
|
for(long i=0; i<sequenceLayout.elementCount().getAsLong(); i++) {
|
||||||
|
assertThat(varHandle.get(base, i), is(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSlicingMemorySegment_thenTheyCanBeAccessedIndividually() {
|
||||||
|
MemoryAddress memoryAddress =
|
||||||
|
MemorySegment.allocateNative(12).baseAddress();
|
||||||
|
MemoryAddress memoryAddress1 =
|
||||||
|
memoryAddress.segment().asSlice(0,4).baseAddress();
|
||||||
|
MemoryAddress memoryAddress2 =
|
||||||
|
memoryAddress.segment().asSlice(4,4).baseAddress();
|
||||||
|
MemoryAddress memoryAddress3 =
|
||||||
|
memoryAddress.segment().asSlice(8,4).baseAddress();
|
||||||
|
|
||||||
|
VarHandle intHandle =
|
||||||
|
MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
|
||||||
|
intHandle.set(memoryAddress1, Integer.MIN_VALUE);
|
||||||
|
intHandle.set(memoryAddress2, 0);
|
||||||
|
intHandle.set(memoryAddress3, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
assertThat(intHandle.get(memoryAddress1), is(Integer.MIN_VALUE));
|
||||||
|
assertThat(intHandle.get(memoryAddress2), is(0));
|
||||||
|
assertThat(intHandle.get(memoryAddress3), is(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package com.baeldung.java14.record;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class PersonTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSameNameAndAddress_whenEquals_thenPersonsEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, address);
|
||||||
|
Person person2 = new Person(name, address);
|
||||||
|
|
||||||
|
assertTrue(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentObject_whenEquals_thenNotEqual() {
|
||||||
|
|
||||||
|
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||||
|
|
||||||
|
assertFalse(person.equals(new Object()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentName_whenEquals_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person("Jane Doe", address);
|
||||||
|
Person person2 = new Person("John Doe", address);
|
||||||
|
|
||||||
|
assertFalse(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentAddress_whenEquals_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, "100 Linda Ln.");
|
||||||
|
Person person2 = new Person(name, "200 London Ave.");
|
||||||
|
|
||||||
|
assertFalse(person1.equals(person2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSameNameAndAddress_whenHashCode_thenPersonsEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, address);
|
||||||
|
Person person2 = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentObject_whenHashCode_thenNotEqual() {
|
||||||
|
|
||||||
|
Person person = new Person("John Doe", "100 Linda Ln.");
|
||||||
|
|
||||||
|
assertNotEquals(person.hashCode(), new Object().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentName_whenHashCode_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person1 = new Person("Jane Doe", address);
|
||||||
|
Person person2 = new Person("John Doe", address);
|
||||||
|
|
||||||
|
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenDifferentAddress_whenHashCode_thenPersonsNotEqual() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person1 = new Person(name, "100 Linda Ln.");
|
||||||
|
Person person2 = new Person(name, "200 London Ave.");
|
||||||
|
|
||||||
|
assertNotEquals(person1.hashCode(), person2.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals(name, person.name());
|
||||||
|
assertEquals(address, person.address());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenValidNameAndAddress_whenToString_thenCorrectStringReturned() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = new Person(name, address);
|
||||||
|
|
||||||
|
assertEquals("Person[name=" + name + ", address=" + address + "]", person.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void givenNullName_whenConstruct_thenErrorThrown() {
|
||||||
|
new Person(null, "100 Linda Ln.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void givenNullAddress_whenConstruct_thenErrorThrown() {
|
||||||
|
new Person("John Doe", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnknownAddress_whenConstructing_thenAddressPopulated() {
|
||||||
|
|
||||||
|
String name = "John Doe";
|
||||||
|
|
||||||
|
Person person = new Person(name);
|
||||||
|
|
||||||
|
assertEquals(name, person.name());
|
||||||
|
assertEquals(Person.UNKWOWN_ADDRESS, person.address());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenUnnamed_whenConstructingThroughFactory_thenNamePopulated() {
|
||||||
|
|
||||||
|
String address = "100 Linda Ln.";
|
||||||
|
|
||||||
|
Person person = Person.unnamed(address);
|
||||||
|
|
||||||
|
assertEquals(Person.UNNAMED, person.name());
|
||||||
|
assertEquals(address, person.address());
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import org.apache.commons.collections4.MapUtils;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ConvertListToMapService {
|
public class ConvertListToMapService {
|
||||||
|
@ -21,7 +22,7 @@ public class ConvertListToMapService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, Animal> convertListAfterJava8(List<Animal> list) {
|
public Map<Integer, Animal> convertListAfterJava8(List<Animal> list) {
|
||||||
Map<Integer, Animal> map = list.stream().collect(Collectors.toMap(Animal::getId, animal -> animal));
|
Map<Integer, Animal> map = list.stream().collect(Collectors.toMap(Animal::getId, Function.identity()));
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class CollectionToArrayListUnitTest {
|
||||||
@Test
|
@Test
|
||||||
public void whenUsingDeepCopy_thenVerifyDeepCopy() {
|
public void whenUsingDeepCopy_thenVerifyDeepCopy() {
|
||||||
ArrayList<Foo> newList = srcCollection.stream()
|
ArrayList<Foo> newList = srcCollection.stream()
|
||||||
.map(foo -> foo.deepCopy())
|
.map(Foo::deepCopy)
|
||||||
.collect(toCollection(ArrayList::new));
|
.collect(toCollection(ArrayList::new));
|
||||||
|
|
||||||
verifyDeepCopy(srcCollection, newList);
|
verifyDeepCopy(srcCollection, newList);
|
||||||
|
@ -83,13 +83,13 @@ public class CollectionToArrayListUnitTest {
|
||||||
* @param a
|
* @param a
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
private void verifyShallowCopy(Collection a, Collection b) {
|
private void verifyShallowCopy(Collection<Foo> a, Collection<Foo> b) {
|
||||||
assertEquals("Collections have different lengths", a.size(), b.size());
|
assertEquals("Collections have different lengths", a.size(), b.size());
|
||||||
Iterator<Foo> iterA = a.iterator();
|
Iterator<Foo> iterA = a.iterator();
|
||||||
Iterator<Foo> iterB = b.iterator();
|
Iterator<Foo> iterB = b.iterator();
|
||||||
while (iterA.hasNext()) {
|
while (iterA.hasNext()) {
|
||||||
// use '==' to test instance identity
|
// use '==' to test instance identity
|
||||||
assertTrue("Foo instances differ!", iterA.next() == iterB.next());
|
assertSame("Foo instances differ!", iterA.next(), iterB.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ public class CollectionToArrayListUnitTest {
|
||||||
* @param a
|
* @param a
|
||||||
* @param b
|
* @param b
|
||||||
*/
|
*/
|
||||||
private void verifyDeepCopy(Collection a, Collection b) {
|
private void verifyDeepCopy(Collection<Foo> a, Collection<Foo> b) {
|
||||||
assertEquals("Collections have different lengths", a.size(), b.size());
|
assertEquals("Collections have different lengths", a.size(), b.size());
|
||||||
Iterator<Foo> iterA = a.iterator();
|
Iterator<Foo> iterA = a.iterator();
|
||||||
Iterator<Foo> iterB = b.iterator();
|
Iterator<Foo> iterB = b.iterator();
|
||||||
|
@ -106,7 +106,7 @@ public class CollectionToArrayListUnitTest {
|
||||||
Foo nextA = iterA.next();
|
Foo nextA = iterA.next();
|
||||||
Foo nextB = iterB.next();
|
Foo nextB = iterB.next();
|
||||||
// should not be same instance
|
// should not be same instance
|
||||||
assertFalse("Foo instances are the same!", nextA == nextB);
|
assertNotSame("Foo instances are the same!", nextA, nextB);
|
||||||
// but should have same content
|
// but should have same content
|
||||||
assertFalse("Foo instances have different content!", fooDiff(nextA, nextB));
|
assertFalse("Foo instances have different content!", fooDiff(nextA, nextB));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
||||||
Iterator<Integer> iterator;
|
Iterator<Integer> iterator;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
iterator = Arrays.asList(1, 2, 3)
|
iterator = Arrays.asList(1, 2, 3)
|
||||||
.iterator();
|
.iterator();
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
||||||
@Test
|
@Test
|
||||||
public void givenAnIterator_whenConvertIteratorToListUsingWhileLoop_thenReturnAList() {
|
public void givenAnIterator_whenConvertIteratorToListUsingWhileLoop_thenReturnAList() {
|
||||||
|
|
||||||
List<Integer> actualList = new ArrayList<Integer>();
|
List<Integer> actualList = new ArrayList<>();
|
||||||
|
|
||||||
// Convert Iterator to List using while loop dsf
|
// Convert Iterator to List using while loop dsf
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
|
@ -44,7 +44,7 @@ public class ConvertIteratorToListServiceUnitTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenAnIterator_whenConvertIteratorToListAfterJava8_thenReturnAList() {
|
public void givenAnIterator_whenConvertIteratorToListAfterJava8_thenReturnAList() {
|
||||||
List<Integer> actualList = new ArrayList<Integer>();
|
List<Integer> actualList = new ArrayList<>();
|
||||||
|
|
||||||
// Convert Iterator to List using Java 8
|
// Convert Iterator to List using Java 8
|
||||||
iterator.forEachRemaining(actualList::add);
|
iterator.forEachRemaining(actualList::add);
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.logging.log4j2.plugins;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||||
|
import org.apache.logging.log4j.core.pattern.ConverterKeys;
|
||||||
|
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
|
||||||
|
import org.apache.logging.log4j.core.pattern.PatternConverter;
|
||||||
|
|
||||||
|
@Plugin(name = "DockerPatternConverter", category = PatternConverter.CATEGORY)
|
||||||
|
@ConverterKeys({"docker", "container"})
|
||||||
|
public class DockerPatternConverter extends LogEventPatternConverter {
|
||||||
|
|
||||||
|
private DockerPatternConverter(String[] options) {
|
||||||
|
super("Docker", "docker");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DockerPatternConverter newInstance(String[] options) {
|
||||||
|
return new DockerPatternConverter(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void format(LogEvent event, StringBuilder toAppendTo) {
|
||||||
|
toAppendTo.append(dockerContainer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String dockerContainer() {
|
||||||
|
//get docker container ID inside which application is running here
|
||||||
|
return "container-1";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
package com.baeldung.logging.log4j2.plugins;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.core.Core;
|
||||||
|
import org.apache.logging.log4j.core.Filter;
|
||||||
|
import org.apache.logging.log4j.core.Layout;
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Plugin(name = "Kafka2", category = Core.CATEGORY_NAME)
|
||||||
|
public class KafkaAppender extends AbstractAppender {
|
||||||
|
|
||||||
|
@PluginBuilderFactory
|
||||||
|
public static Builder newBuilder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder implements org.apache.logging.log4j.core.util.Builder<KafkaAppender> {
|
||||||
|
|
||||||
|
@PluginBuilderAttribute("name")
|
||||||
|
@Required
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@PluginBuilderAttribute("ip")
|
||||||
|
private String ipAddress;
|
||||||
|
|
||||||
|
@PluginBuilderAttribute("port")
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@PluginBuilderAttribute("topic")
|
||||||
|
private String topic;
|
||||||
|
|
||||||
|
@PluginBuilderAttribute("partition")
|
||||||
|
private String partition;
|
||||||
|
|
||||||
|
@PluginElement("Layout")
|
||||||
|
private Layout<? extends Serializable> layout;
|
||||||
|
|
||||||
|
@PluginElement("Filter")
|
||||||
|
private Filter filter;
|
||||||
|
|
||||||
|
public Layout<? extends Serializable> getLayout() {
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setLayout(Layout<? extends Serializable> layout) {
|
||||||
|
this.layout = layout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Filter getFilter() {
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setFilter(Filter filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIpAddress() {
|
||||||
|
return ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setIpAddress(String ipAddress) {
|
||||||
|
this.ipAddress = ipAddress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setTopic(String topic) {
|
||||||
|
this.topic = topic;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartition() {
|
||||||
|
return partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setPartition(String partition) {
|
||||||
|
this.partition = partition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KafkaAppender build() {
|
||||||
|
return new KafkaAppender(getName(), getFilter(), getLayout(), true, new KafkaBroker(ipAddress, port, topic, partition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KafkaBroker broker;
|
||||||
|
|
||||||
|
private KafkaAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, KafkaBroker broker) {
|
||||||
|
super(name, filter, layout, ignoreExceptions);
|
||||||
|
this.broker = broker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(LogEvent event) {
|
||||||
|
|
||||||
|
connectAndSendToKafka(broker, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connectAndSendToKafka(KafkaBroker broker, LogEvent event) {
|
||||||
|
//send to Kafka
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.baeldung.logging.log4j2.plugins;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class KafkaBroker implements Serializable {
|
||||||
|
|
||||||
|
private final String ipAddress;
|
||||||
|
private final int port;
|
||||||
|
|
||||||
|
public KafkaBroker(String ipAddress, int port, String topic, String partition) {
|
||||||
|
this.ipAddress = ipAddress;
|
||||||
|
this.port = port;
|
||||||
|
this.topic = topic;
|
||||||
|
this.partition = partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTopic() {
|
||||||
|
return topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPartition() {
|
||||||
|
return partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String topic;
|
||||||
|
private final String partition;
|
||||||
|
|
||||||
|
|
||||||
|
public String getIpAddress() {
|
||||||
|
return ipAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.logging.log4j2.plugins;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||||
|
import org.apache.logging.log4j.core.lookup.StrLookup;
|
||||||
|
|
||||||
|
@Plugin(name = "kafka", category = StrLookup.CATEGORY)
|
||||||
|
public class KafkaLookup implements StrLookup {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String lookup(String key) {
|
||||||
|
return getFromKafka(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String lookup(LogEvent event, String key) {
|
||||||
|
return getFromKafka(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getFromKafka(String topicName) {
|
||||||
|
//kafka search logic should go here
|
||||||
|
return "topic1-p1";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.baeldung.logging.log4j2.plugins;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.apache.logging.log4j.core.Appender;
|
||||||
|
import org.apache.logging.log4j.core.Core;
|
||||||
|
import org.apache.logging.log4j.core.Filter;
|
||||||
|
import org.apache.logging.log4j.core.LogEvent;
|
||||||
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||||
|
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Collections.synchronizedList;
|
||||||
|
|
||||||
|
@Plugin(name = "ListAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
|
||||||
|
public class ListAppender extends AbstractAppender {
|
||||||
|
|
||||||
|
private List<LogEvent> logList;
|
||||||
|
|
||||||
|
protected ListAppender(String name, Filter filter) {
|
||||||
|
super(name, filter, null);
|
||||||
|
logList = synchronizedList(new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PluginFactory
|
||||||
|
public static ListAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filter") final Filter filter) {
|
||||||
|
return new ListAppender(name, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void append(LogEvent event) {
|
||||||
|
if (event.getLevel()
|
||||||
|
.isLessSpecificThan(Level.WARN)) {
|
||||||
|
error("Unable to log less than WARN level.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logList.add(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -50,6 +50,12 @@
|
||||||
</Policies>
|
</Policies>
|
||||||
</RollingFile>
|
</RollingFile>
|
||||||
<MapAppender name="MapAppender"/>
|
<MapAppender name="MapAppender"/>
|
||||||
|
<Console name="DockerConsoleLogger" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="%pid %docker" />
|
||||||
|
</Console>
|
||||||
|
<Kafka2 name="KafkaLogger" ip ="127.0.0.1" port="9010" topic="log" partition="p-1">
|
||||||
|
<PatternLayout pattern="%pid%style{%message}{red}%n" />
|
||||||
|
</Kafka2>
|
||||||
</Appenders>
|
</Appenders>
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE"
|
<Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE"
|
||||||
|
@ -80,6 +86,9 @@
|
||||||
additivity="false">
|
additivity="false">
|
||||||
<AppenderRef ref="ConsoleJSONAppender" />
|
<AppenderRef ref="ConsoleJSONAppender" />
|
||||||
</Logger>
|
</Logger>
|
||||||
|
<Logger name="com.baeldung.logging.log4j2.plugins" level="INFO">
|
||||||
|
<AppenderRef ref="KafkaLogger" />
|
||||||
|
</Logger>
|
||||||
<Root level="DEBUG">
|
<Root level="DEBUG">
|
||||||
<AppenderRef ref="ConsoleAppender" />
|
<AppenderRef ref="ConsoleAppender" />
|
||||||
<AppenderRef ref="MapAppender" />
|
<AppenderRef ref="MapAppender" />
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-1</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../parent-boot-1</relativePath>
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-1</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-boot-1</relativePath>
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.session</groupId>
|
<groupId>org.springframework.session</groupId>
|
||||||
<artifactId>spring-session</artifactId>
|
<artifactId>spring-session-data-redis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -36,6 +36,11 @@
|
||||||
<artifactId>embedded-redis</artifactId>
|
<artifactId>embedded-redis</artifactId>
|
||||||
<version>${embedded-redis.version}</version>
|
<version>${embedded-redis.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
<type>jar</type>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package com.baeldung.spring.session;
|
package com.baeldung.spring.session;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
|
@ -13,11 +16,16 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.inMemoryAuthentication().withUser("admin").password("password").roles("ADMIN");
|
auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("password")).roles("ADMIN");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http.httpBasic().and().authorizeRequests().antMatchers("/").hasRole("ADMIN").anyRequest().authenticated();
|
http.httpBasic().and().authorizeRequests().antMatchers("/").hasRole("ADMIN").anyRequest().authenticated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
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.web.server.LocalServerPort;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-1</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../parent-boot-1</relativePath>
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -42,13 +42,14 @@
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf.extras</groupId>
|
<groupId>org.thymeleaf.extras</groupId>
|
||||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.social</groupId>
|
<groupId>org.springframework.social</groupId>
|
||||||
<artifactId>spring-social-facebook</artifactId>
|
<artifactId>spring-social-facebook</artifactId>
|
||||||
|
<version>${spring.social.facebook.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -61,6 +62,12 @@
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy-dep</artifactId>
|
||||||
|
<version>${bytebuddy.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- test -->
|
<!-- test -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -94,4 +101,9 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<bytebuddy.version>1.10.9</bytebuddy.version>
|
||||||
|
<spring.social.facebook.version>2.0.3.RELEASE</spring.social.facebook.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -3,7 +3,7 @@ package com.baeldung.config;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.baeldung.config;
|
package com.baeldung.config;
|
||||||
|
|
||||||
import com.baeldung.security.FacebookSignInAdapter;
|
|
||||||
import com.baeldung.security.FacebookConnectionSignup;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
@ -14,22 +13,27 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.social.connect.ConnectionFactoryLocator;
|
import org.springframework.social.connect.ConnectionFactoryLocator;
|
||||||
import org.springframework.social.connect.UsersConnectionRepository;
|
import org.springframework.social.connect.UsersConnectionRepository;
|
||||||
import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository;
|
import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository;
|
||||||
|
import org.springframework.social.connect.support.ConnectionFactoryRegistry;
|
||||||
import org.springframework.social.connect.web.ProviderSignInController;
|
import org.springframework.social.connect.web.ProviderSignInController;
|
||||||
|
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
|
||||||
|
|
||||||
|
import com.baeldung.security.FacebookConnectionSignup;
|
||||||
|
import com.baeldung.security.FacebookSignInAdapter;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@ComponentScan(basePackages = { "com.baeldung.security" })
|
@ComponentScan(basePackages = { "com.baeldung.security" })
|
||||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@Value("${spring.social.facebook.appSecret}")
|
||||||
|
String appSecret;
|
||||||
|
|
||||||
|
@Value("${spring.social.facebook.appId}")
|
||||||
|
String appId;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserDetailsService userDetailsService;
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ConnectionFactoryLocator connectionFactoryLocator;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UsersConnectionRepository usersConnectionRepository;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FacebookConnectionSignup facebookConnectionSignup;
|
private FacebookConnectionSignup facebookConnectionSignup;
|
||||||
|
|
||||||
|
@ -55,7 +59,19 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
@Bean
|
@Bean
|
||||||
// @Primary
|
// @Primary
|
||||||
public ProviderSignInController providerSignInController() {
|
public ProviderSignInController providerSignInController() {
|
||||||
|
ConnectionFactoryLocator connectionFactoryLocator = connectionFactoryLocator();
|
||||||
|
UsersConnectionRepository usersConnectionRepository = getUsersConnectionRepository(connectionFactoryLocator);
|
||||||
((InMemoryUsersConnectionRepository) usersConnectionRepository).setConnectionSignUp(facebookConnectionSignup);
|
((InMemoryUsersConnectionRepository) usersConnectionRepository).setConnectionSignUp(facebookConnectionSignup);
|
||||||
return new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, new FacebookSignInAdapter());
|
return new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, new FacebookSignInAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ConnectionFactoryLocator connectionFactoryLocator() {
|
||||||
|
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
|
||||||
|
registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
|
||||||
|
return new InMemoryUsersConnectionRepository(connectionFactoryLocator);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue