Merge branch 'masterEugen' into tutorials/titleCase
This commit is contained in:
commit
5de26d0df3
18
cdi/pom.xml
18
cdi/pom.xml
|
@ -14,6 +14,24 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<version>1.3</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.10.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context</artifactId>
|
<artifactId>spring-context</artifactId>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung.dependencyinjection.application;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.imageprocessors.ImageFileProcessor;
|
||||||
|
import org.jboss.weld.environment.se.Weld;
|
||||||
|
import org.jboss.weld.environment.se.WeldContainer;
|
||||||
|
|
||||||
|
public class FileApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Weld weld = new Weld();
|
||||||
|
WeldContainer container = weld.initialize();
|
||||||
|
ImageFileProcessor imageFileProcessor = container.select(ImageFileProcessor.class).get();
|
||||||
|
System.out.println(imageFileProcessor.openFile("file1.png"));
|
||||||
|
System.out.println(imageFileProcessor.writeFile("file1.png"));
|
||||||
|
System.out.println(imageFileProcessor.saveFile("file1.png"));
|
||||||
|
container.shutdown();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.dependencyinjection.factories;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.loggers.TimeLogger;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import javax.enterprise.inject.Produces;
|
||||||
|
|
||||||
|
public class TimeLoggerFactory {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
public TimeLogger getTimeLogger() {
|
||||||
|
return new TimeLogger(new SimpleDateFormat("HH:mm"), Calendar.getInstance());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.dependencyinjection.imagefileeditors;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.qualifiers.GifFileEditorQualifier;
|
||||||
|
|
||||||
|
@GifFileEditorQualifier
|
||||||
|
public class GifFileEditor implements ImageFileEditor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String openFile(String fileName) {
|
||||||
|
return "Opening GIF file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String editFile(String fileName) {
|
||||||
|
return "Editing GIF file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String writeFile(String fileName) {
|
||||||
|
return "Writing GIF file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String saveFile(String fileName) {
|
||||||
|
return "Saving GIF file " + fileName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.dependencyinjection.imagefileeditors;
|
||||||
|
|
||||||
|
public interface ImageFileEditor {
|
||||||
|
|
||||||
|
String openFile(String fileName);
|
||||||
|
|
||||||
|
String editFile(String fileName);
|
||||||
|
|
||||||
|
String writeFile(String fileName);
|
||||||
|
|
||||||
|
String saveFile(String fileName);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.dependencyinjection.imagefileeditors;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.qualifiers.JpgFileEditorQualifier;
|
||||||
|
|
||||||
|
@JpgFileEditorQualifier
|
||||||
|
public class JpgFileEditor implements ImageFileEditor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String openFile(String fileName) {
|
||||||
|
return "Opening JPG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String editFile(String fileName) {
|
||||||
|
return "Editing JPG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String writeFile(String fileName) {
|
||||||
|
return "Writing JPG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String saveFile(String fileName) {
|
||||||
|
return "Saving JPG file " + fileName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.dependencyinjection.imagefileeditors;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.qualifiers.PngFileEditorQualifier;
|
||||||
|
|
||||||
|
@PngFileEditorQualifier
|
||||||
|
public class PngFileEditor implements ImageFileEditor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String openFile(String fileName) {
|
||||||
|
return "Opening PNG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String editFile(String fileName) {
|
||||||
|
return "Editing PNG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String writeFile(String fileName) {
|
||||||
|
return "Writing PNG file " + fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String saveFile(String fileName) {
|
||||||
|
return "Saving PNG file " + fileName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.baeldung.dependencyinjection.imageprocessors;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.loggers.TimeLogger;
|
||||||
|
import com.baeldung.dependencyinjection.qualifiers.PngFileEditorQualifier;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.ImageFileEditor;
|
||||||
|
|
||||||
|
public class ImageFileProcessor {
|
||||||
|
|
||||||
|
private final ImageFileEditor imageFileEditor;
|
||||||
|
private final TimeLogger timeLogger;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ImageFileProcessor(@PngFileEditorQualifier ImageFileEditor imageFileEditor, TimeLogger timeLogger) {
|
||||||
|
this.imageFileEditor = imageFileEditor;
|
||||||
|
this.timeLogger = timeLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageFileEditor getImageFileditor() {
|
||||||
|
return imageFileEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeLogger getTimeLogger() {
|
||||||
|
return timeLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String openFile(String fileName) {
|
||||||
|
return imageFileEditor.openFile(fileName) + " at: " + timeLogger.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String editFile(String fileName) {
|
||||||
|
return imageFileEditor.editFile(fileName) + " at: " + timeLogger.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String writeFile(String fileName) {
|
||||||
|
return imageFileEditor.writeFile(fileName) + " at: " + timeLogger.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String saveFile(String fileName) {
|
||||||
|
return imageFileEditor.saveFile(fileName)+ " at: " + timeLogger.getTime();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.dependencyinjection.loggers;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
public class TimeLogger {
|
||||||
|
|
||||||
|
private final SimpleDateFormat dateFormat;
|
||||||
|
private final Calendar calendar;
|
||||||
|
|
||||||
|
public TimeLogger(SimpleDateFormat dateFormat, Calendar calendar) {
|
||||||
|
this.dateFormat = dateFormat;
|
||||||
|
this.calendar = calendar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime() {
|
||||||
|
return dateFormat.format(calendar.getTime());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.dependencyinjection.qualifiers;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
|
||||||
|
public @interface GifFileEditorQualifier {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.dependencyinjection.qualifiers;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
|
||||||
|
public @interface JpgFileEditorQualifier {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.baeldung.dependencyinjection.qualifiers;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
@Qualifier
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
|
||||||
|
public @interface PngFileEditorQualifier {}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.GifFileEditor;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class GifFileEditorUnitTest {
|
||||||
|
|
||||||
|
private static GifFileEditor gifFileEditor;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setGifFileEditorInstance() {
|
||||||
|
gifFileEditor = new GifFileEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGifFileEditorlInstance_whenCalledopenFile_thenOneAssertion() {
|
||||||
|
assertThat(gifFileEditor.openFile("file1.gif")).isEqualTo("Opening GIF file file1.gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGifFileEditorlInstance_whenCallededitFile_thenOneAssertion() {
|
||||||
|
assertThat(gifFileEditor.editFile("file1.gif")).isEqualTo("Editing GIF file file1.gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGifFileEditorInstance_whenCalledwriteFile_thenOneAssertion() {
|
||||||
|
assertThat(gifFileEditor.writeFile("file1.gif")).isEqualTo("Writing GIF file file1.gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenGifFileEditorInstance_whenCalledsaveFile_thenOneAssertion() {
|
||||||
|
assertThat(gifFileEditor.saveFile("file1.gif")).isEqualTo("Saving GIF file file1.gif");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.GifFileEditor;
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.JpgFileEditor;
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.PngFileEditor;
|
||||||
|
import com.baeldung.dependencyinjection.imageprocessors.ImageFileProcessor;
|
||||||
|
import com.baeldung.dependencyinjection.loggers.TimeLogger;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.jboss.weld.environment.se.Weld;
|
||||||
|
import org.jboss.weld.environment.se.WeldContainer;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ImageProcessorUnitTest {
|
||||||
|
|
||||||
|
private static ImageFileProcessor imageFileProcessor;
|
||||||
|
private static SimpleDateFormat dateFormat;
|
||||||
|
private static Calendar calendar;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setImageProcessorInstance() {
|
||||||
|
Weld weld = new Weld();
|
||||||
|
WeldContainer container = weld.initialize();
|
||||||
|
imageFileProcessor = container.select(ImageFileProcessor.class).get();
|
||||||
|
container.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setSimpleDateFormatInstance() {
|
||||||
|
dateFormat = new SimpleDateFormat("HH:mm");
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setCalendarInstance() {
|
||||||
|
calendar = Calendar.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImageProcessorInstance_whenInjectedPngFileEditorandTimeLoggerInstances_thenTwoAssertions() {
|
||||||
|
assertThat(imageFileProcessor.getImageFileditor()).isInstanceOf(PngFileEditor.class);
|
||||||
|
assertThat(imageFileProcessor.getTimeLogger()).isInstanceOf(TimeLogger.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImageProcessorInstance_whenCalledopenFile_thenOneAssertion() {
|
||||||
|
String currentTime = dateFormat.format(calendar.getTime());
|
||||||
|
assertThat(imageFileProcessor.openFile("file1.png")).isEqualTo("Opening PNG file file1.png at: " + currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImageProcessorInstance_whenCallededitFile_thenOneAssertion() {
|
||||||
|
String currentTime = dateFormat.format(calendar.getTime());
|
||||||
|
assertThat(imageFileProcessor.editFile("file1.png")).isEqualTo("Editing PNG file file1.png at: " + currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImageProcessorInstance_whenCalledwriteFile_thenOneAssertion() {
|
||||||
|
String currentTime = dateFormat.format(calendar.getTime());
|
||||||
|
assertThat(imageFileProcessor.writeFile("file1.png")).isEqualTo("Writing PNG file file1.png at: " + currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenImageProcessorInstance_whenCalledsaveFile_thenOneAssertion() {
|
||||||
|
String currentTime = dateFormat.format(calendar.getTime());
|
||||||
|
assertThat(imageFileProcessor.saveFile("file1.png")).isEqualTo("Saving PNG file file1.png at: " + currentTime);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.JpgFileEditor;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class JpgFileEditorUnitTest {
|
||||||
|
|
||||||
|
private static JpgFileEditor jpgFileUtil;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setJpgFileEditorInstance() {
|
||||||
|
jpgFileUtil = new JpgFileEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJpgFileEditorInstance_whenCalledopenFile_thenOneAssertion() {
|
||||||
|
assertThat(jpgFileUtil.openFile("file1.jpg")).isEqualTo("Opening JPG file file1.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJpgFileEditorlInstance_whenCallededitFile_thenOneAssertion() {
|
||||||
|
assertThat(jpgFileUtil.editFile("file1.gif")).isEqualTo("Editing JPG file file1.gif");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJpgFileEditorInstance_whenCalledwriteFile_thenOneAssertion() {
|
||||||
|
assertThat(jpgFileUtil.writeFile("file1.jpg")).isEqualTo("Writing JPG file file1.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJpgFileEditorInstance_whenCalledsaveFile_thenOneAssertion() {
|
||||||
|
assertThat(jpgFileUtil.saveFile("file1.jpg")).isEqualTo("Saving JPG file file1.jpg");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.imagefileeditors.PngFileEditor;
|
||||||
|
import com.baeldung.dependencyinjection.qualifiers.PngFileEditorQualifier;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@PngFileEditorQualifier
|
||||||
|
public class PngFileEditorUnitTest {
|
||||||
|
|
||||||
|
private static PngFileEditor pngFileEditor;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setPngFileEditorInstance() {
|
||||||
|
pngFileEditor = new PngFileEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPngFileEditorInstance_whenCalledopenFile_thenOneAssertion() {
|
||||||
|
assertThat(pngFileEditor.openFile("file1.png")).isEqualTo("Opening PNG file file1.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPngFileEditorInstance_whenCallededitFile_thenOneAssertion() {
|
||||||
|
assertThat(pngFileEditor.editFile("file1.png")).isEqualTo("Editing PNG file file1.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPngFileEditorInstance_whenCalledwriteFile_thenOneAssertion() {
|
||||||
|
assertThat(pngFileEditor.writeFile("file1.png")).isEqualTo("Writing PNG file file1.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPngFileEditorInstance_whenCalledsaveFile_thenOneAssertion() {
|
||||||
|
assertThat(pngFileEditor.saveFile("file1.png")).isEqualTo("Saving PNG file file1.png");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.factories.TimeLoggerFactory;
|
||||||
|
import com.baeldung.dependencyinjection.loggers.TimeLogger;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TimeLoggerFactoryUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTimeLoggerFactory_whenCalledgetTimeLogger_thenOneAssertion() {
|
||||||
|
TimeLoggerFactory timeLoggerFactory = new TimeLoggerFactory();
|
||||||
|
assertThat(timeLoggerFactory.getTimeLogger()).isInstanceOf(TimeLogger.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.baeldung.test.dependencyinjection;
|
||||||
|
|
||||||
|
import com.baeldung.dependencyinjection.loggers.TimeLogger;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TimeLoggerUnitTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenTimeLoggerInstance_whenCalledgetLogTime_thenOneAssertion() {
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
TimeLogger timeLogger = new TimeLogger(dateFormat, calendar);
|
||||||
|
String currentTime = dateFormat.format(calendar.getTime());
|
||||||
|
assertThat(timeLogger.getTime()).isEqualTo(currentTime);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.servlets;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static javax.servlet.RequestDispatcher.*;
|
||||||
|
|
||||||
|
@WebServlet(urlPatterns = "/errorHandler")
|
||||||
|
public class ErrorHandlerServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
|
||||||
|
throws IOException {
|
||||||
|
resp.setContentType("text/html; charset=utf-8");
|
||||||
|
try (PrintWriter writer = resp.getWriter()) {
|
||||||
|
writer.write("<html><head><title>Error description</title></head><body>");
|
||||||
|
writer.write("<h2>Error description</h2>");
|
||||||
|
writer.write("<ul>");
|
||||||
|
Arrays.asList(ERROR_STATUS_CODE, ERROR_EXCEPTION_TYPE, ERROR_MESSAGE)
|
||||||
|
.forEach(e ->
|
||||||
|
writer.write("<li>" + e + ":" + req.getAttribute(e) + " </li>")
|
||||||
|
);
|
||||||
|
writer.write("</ul>");
|
||||||
|
writer.write("</html></body>");
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception exception = (Exception) req.getAttribute(ERROR_EXCEPTION);
|
||||||
|
if (IllegalArgumentException.class.isInstance(exception)) {
|
||||||
|
getServletContext().log("Error on an application argument", exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.servlets;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.*;
|
||||||
|
import javax.servlet.http.*;
|
||||||
|
|
||||||
|
@WebServlet(urlPatterns = "/randomError")
|
||||||
|
public class RandomErrorServlet extends HttpServlet {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, final HttpServletResponse resp) {
|
||||||
|
throw new IllegalStateException("Random error");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<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_1.xsd"
|
||||||
|
version="3.1">
|
||||||
|
|
||||||
|
<error-page>
|
||||||
|
<error-code>404</error-code>
|
||||||
|
<location>/error-404.html</location> <!-- /src/main/webapp/error-404.html-->
|
||||||
|
</error-page>
|
||||||
|
|
||||||
|
<error-page>
|
||||||
|
<exception-type>java.lang.Exception</exception-type>
|
||||||
|
<location>/errorHandler</location>
|
||||||
|
</error-page>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Error page</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Error: Page not found</h2>
|
||||||
|
|
||||||
|
<a href="./">Go back home</a>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,14 @@
|
||||||
|
/bin/
|
||||||
|
|
||||||
|
#ignore gradle
|
||||||
|
.gradle/
|
||||||
|
|
||||||
|
|
||||||
|
#ignore build and generated files
|
||||||
|
build/
|
||||||
|
node/
|
||||||
|
out/
|
||||||
|
|
||||||
|
#ignore installed node modules and package lock file
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
|
||||||
|
group 'com.baeldung.ktor'
|
||||||
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.2.40'
|
||||||
|
ext.ktor_version = '0.9.2'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
|
mainClassName = 'APIServer.kt'
|
||||||
|
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||||
|
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
|
||||||
|
|
||||||
|
kotlin { experimental { coroutines "enable" } }
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
maven { url "https://dl.bintray.com/kotlin/ktor" }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile "io.ktor:ktor-server-netty:$ktor_version"
|
||||||
|
compile "ch.qos.logback:logback-classic:1.2.1"
|
||||||
|
compile "io.ktor:ktor-gson:$ktor_version"
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||||
|
|
||||||
|
}
|
||||||
|
task runServer(type: JavaExec) {
|
||||||
|
main = 'APIServer'
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-bin.zip
|
|
@ -0,0 +1,172 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
|
@ -0,0 +1,84 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -0,0 +1,11 @@
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -0,0 +1,2 @@
|
||||||
|
rootProject.name = 'KtorWithKotlin'
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
@file:JvmName("APIServer")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import io.ktor.application.call
|
||||||
|
import io.ktor.application.install
|
||||||
|
import io.ktor.features.CallLogging
|
||||||
|
import io.ktor.features.ContentNegotiation
|
||||||
|
import io.ktor.features.DefaultHeaders
|
||||||
|
import io.ktor.gson.gson
|
||||||
|
import io.ktor.http.ContentType
|
||||||
|
import io.ktor.request.path
|
||||||
|
import io.ktor.response.respond
|
||||||
|
import io.ktor.response.respondText
|
||||||
|
import io.ktor.routing.get
|
||||||
|
import io.ktor.routing.routing
|
||||||
|
import io.ktor.server.engine.embeddedServer
|
||||||
|
import io.ktor.server.netty.Netty
|
||||||
|
import org.slf4j.event.Level
|
||||||
|
|
||||||
|
data class Author(val name: String, val website: String)
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
|
||||||
|
val jsonResponse = """{
|
||||||
|
"id": 1,
|
||||||
|
"task": "Pay waterbill",
|
||||||
|
"description": "Pay water bill today",
|
||||||
|
}"""
|
||||||
|
|
||||||
|
|
||||||
|
embeddedServer(Netty, 8080) {
|
||||||
|
install(DefaultHeaders) {
|
||||||
|
header("X-Developer", "Baeldung")
|
||||||
|
}
|
||||||
|
install(CallLogging) {
|
||||||
|
level = Level.INFO
|
||||||
|
filter { call -> call.request.path().startsWith("/todo") }
|
||||||
|
filter { call -> call.request.path().startsWith("/author") }
|
||||||
|
}
|
||||||
|
install(ContentNegotiation) {
|
||||||
|
gson {
|
||||||
|
setPrettyPrinting()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
routing {
|
||||||
|
get("/todo") {
|
||||||
|
call.respondText(jsonResponse, ContentType.Application.Json)
|
||||||
|
}
|
||||||
|
get("/author") {
|
||||||
|
val author = Author("baeldung", "baeldung.com")
|
||||||
|
call.respond(author)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}.start(wait = true)
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
|
||||||
|
<web-app 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-app_3_0.xsd"
|
||||||
|
version="3.0">
|
||||||
|
<!-- path to application.conf file, required -->
|
||||||
|
<!-- note that this file is always loaded as an absolute path from the classpath -->
|
||||||
|
<context-param>
|
||||||
|
<param-name>io.ktor.ktor.config</param-name>
|
||||||
|
<param-value>application.conf</param-value>
|
||||||
|
</context-param>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<display-name>KtorServlet</display-name>
|
||||||
|
<servlet-name>KtorServlet</servlet-name>
|
||||||
|
<servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>
|
||||||
|
|
||||||
|
<!-- required! -->
|
||||||
|
<async-supported>true</async-supported>
|
||||||
|
|
||||||
|
<!-- 100mb max file upload, optional -->
|
||||||
|
<multipart-config>
|
||||||
|
<max-file-size>304857600</max-file-size>
|
||||||
|
<max-request-size>304857600</max-request-size>
|
||||||
|
<file-size-threshold>0</file-size-threshold>
|
||||||
|
</multipart-config>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>KtorServlet</servlet-name>
|
||||||
|
<url-pattern>/</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,8 @@
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Folders #
|
||||||
|
/gensrc
|
||||||
|
/target
|
||||||
|
|
||||||
|
# Packaged files #
|
||||||
|
*.jar
|
|
@ -722,6 +722,17 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup</groupId>
|
||||||
|
<artifactId>javapoet</artifactId>
|
||||||
|
<version>${javapoet.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-all</artifactId>
|
||||||
|
<version>${hamcrest-all.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -939,6 +950,8 @@
|
||||||
<xchart-version>3.5.2</xchart-version>
|
<xchart-version>3.5.2</xchart-version>
|
||||||
<commons-net.version>3.6</commons-net.version>
|
<commons-net.version>3.6</commons-net.version>
|
||||||
<mockftpserver.version>2.7.1</mockftpserver.version>
|
<mockftpserver.version>2.7.1</mockftpserver.version>
|
||||||
|
<javapoet.version>1.10.0</javapoet.version>
|
||||||
|
<hamcrest-all.version>1.3</hamcrest-all.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,183 @@
|
||||||
|
package com.baeldung.javapoet;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.CodeBlock;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class PersonGenerator {
|
||||||
|
|
||||||
|
private static final String FOUR_WHITESPACES = " ";
|
||||||
|
private static final String PERSON_PACKAGE_NAME = "com.baeldung.javapoet.test.person";
|
||||||
|
|
||||||
|
private File outputFile;
|
||||||
|
|
||||||
|
public PersonGenerator() {
|
||||||
|
outputFile = new File(getOutputPath().toUri());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPersonPackageName() {
|
||||||
|
return PERSON_PACKAGE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getOutputPath() {
|
||||||
|
return Paths.get(new File(".").getAbsolutePath() + "/gensrc");
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldSpec getDefaultNameField() {
|
||||||
|
return FieldSpec
|
||||||
|
.builder(String.class, "DEFAULT_NAME")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
||||||
|
.initializer("$S", "Alice")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodSpec getSortByLengthMethod() {
|
||||||
|
return MethodSpec
|
||||||
|
.methodBuilder("sortByLength")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
|
.addParameter(ParameterSpec
|
||||||
|
.builder(ParameterizedTypeName.get(ClassName.get(List.class), TypeName.get(String.class)), "strings")
|
||||||
|
.build())
|
||||||
|
.addStatement("$T.sort($N, $L)", Collections.class, "strings", getComparatorAnonymousClass())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodSpec getPrintNameMultipleTimesMethod() {
|
||||||
|
return MethodSpec
|
||||||
|
.methodBuilder("printNameMultipleTimes")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addCode(getPrintNameMultipleTimesLambdaImpl())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeBlock getPrintNameMultipleTimesImpl() {
|
||||||
|
return CodeBlock
|
||||||
|
.builder()
|
||||||
|
.beginControlFlow("for (int i = $L; i < $L; i++)")
|
||||||
|
.addStatement("System.out.println(name)")
|
||||||
|
.endControlFlow()
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeBlock getPrintNameMultipleTimesLambdaImpl() {
|
||||||
|
return CodeBlock
|
||||||
|
.builder()
|
||||||
|
.addStatement("$T<$T> names = new $T<>()", List.class, String.class, ArrayList.class)
|
||||||
|
.addStatement("$T.range($L, $L).forEach(i -> names.add(name))", IntStream.class, 0, 10)
|
||||||
|
.addStatement("names.forEach(System.out::println)")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSpec getGenderEnum() {
|
||||||
|
return TypeSpec
|
||||||
|
.enumBuilder("Gender")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addEnumConstant("MALE")
|
||||||
|
.addEnumConstant("FEMALE")
|
||||||
|
.addEnumConstant("UNSPECIFIED")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSpec getPersonInterface() {
|
||||||
|
return TypeSpec
|
||||||
|
.interfaceBuilder("Person")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addField(getDefaultNameField())
|
||||||
|
.addMethod(MethodSpec
|
||||||
|
.methodBuilder("getName")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.returns(String.class)
|
||||||
|
.build())
|
||||||
|
.addMethod(MethodSpec
|
||||||
|
.methodBuilder("getDefaultName")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.DEFAULT)
|
||||||
|
.returns(String.class)
|
||||||
|
.addCode(CodeBlock
|
||||||
|
.builder()
|
||||||
|
.addStatement("return DEFAULT_NAME")
|
||||||
|
.build())
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSpec getStudentClass() {
|
||||||
|
return TypeSpec
|
||||||
|
.classBuilder("Student")
|
||||||
|
.addSuperinterface(ClassName.get(PERSON_PACKAGE_NAME, "Person"))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addField(FieldSpec
|
||||||
|
.builder(String.class, "name")
|
||||||
|
.addModifiers(Modifier.PRIVATE)
|
||||||
|
.build())
|
||||||
|
.addMethod(MethodSpec
|
||||||
|
.methodBuilder("getName")
|
||||||
|
.addAnnotation(Override.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(String.class)
|
||||||
|
.addStatement("return this.name")
|
||||||
|
.build())
|
||||||
|
.addMethod(MethodSpec
|
||||||
|
.methodBuilder("setName")
|
||||||
|
.addParameter(String.class, "name")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addStatement("this.name = name")
|
||||||
|
.build())
|
||||||
|
.addMethod(getPrintNameMultipleTimesMethod())
|
||||||
|
.addMethod(getSortByLengthMethod())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSpec getComparatorAnonymousClass() {
|
||||||
|
return TypeSpec
|
||||||
|
.anonymousClassBuilder("")
|
||||||
|
.addSuperinterface(ParameterizedTypeName.get(Comparator.class, String.class))
|
||||||
|
.addMethod(MethodSpec
|
||||||
|
.methodBuilder("compare")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(Override.class)
|
||||||
|
.addParameter(String.class, "a")
|
||||||
|
.addParameter(String.class, "b")
|
||||||
|
.returns(int.class)
|
||||||
|
.addStatement("return a.length() - b.length()")
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateGenderEnum() throws IOException {
|
||||||
|
writeToOutputFile(getPersonPackageName(), getGenderEnum());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generatePersonInterface() throws IOException {
|
||||||
|
writeToOutputFile(getPersonPackageName(), getPersonInterface());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateStudentClass() throws IOException {
|
||||||
|
writeToOutputFile(getPersonPackageName(), getStudentClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeToOutputFile(String packageName, TypeSpec typeSpec) throws IOException {
|
||||||
|
JavaFile javaFile = JavaFile
|
||||||
|
.builder(packageName, typeSpec)
|
||||||
|
.indent(FOUR_WHITESPACES)
|
||||||
|
.build();
|
||||||
|
javaFile.writeTo(outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.baeldung.javapoet.test;
|
||||||
|
|
||||||
|
import com.baeldung.javapoet.PersonGenerator;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
@RunWith(JUnit4.class)
|
||||||
|
public class PersonGeneratorUnitTest {
|
||||||
|
|
||||||
|
private PersonGenerator generator;
|
||||||
|
private Path generatedFolderPath;
|
||||||
|
private Path expectedFolderPath;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
String packagePath = this
|
||||||
|
.getClass()
|
||||||
|
.getPackage()
|
||||||
|
.getName()
|
||||||
|
.replace(".", "/") + "/person";
|
||||||
|
generator = new PersonGenerator();
|
||||||
|
generatedFolderPath = generator
|
||||||
|
.getOutputPath()
|
||||||
|
.resolve(packagePath);
|
||||||
|
expectedFolderPath = Paths.get(new File(".").getAbsolutePath() + "/src/test/java/" + packagePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
FileUtils.deleteDirectory(new File(generator
|
||||||
|
.getOutputPath()
|
||||||
|
.toUri()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGenerateGenderEnum_thenGenerateGenderEnumAndWriteToFile() throws IOException {
|
||||||
|
generator.generateGenderEnum();
|
||||||
|
String fileName = "Gender.java";
|
||||||
|
assertThatFileIsGeneratedAsExpected(fileName);
|
||||||
|
deleteGeneratedFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGeneratePersonInterface_thenGeneratePersonInterfaceAndWriteToFile() throws IOException {
|
||||||
|
generator.generatePersonInterface();
|
||||||
|
String fileName = "Person.java";
|
||||||
|
assertThatFileIsGeneratedAsExpected(fileName);
|
||||||
|
deleteGeneratedFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenGenerateStudentClass_thenGenerateStudentClassAndWriteToFile() throws IOException {
|
||||||
|
generator.generateStudentClass();
|
||||||
|
String fileName = "Student.java";
|
||||||
|
assertThatFileIsGeneratedAsExpected(fileName);
|
||||||
|
deleteGeneratedFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertThatFileIsGeneratedAsExpected(String fileName) throws IOException {
|
||||||
|
String generatedFileContent = extractFileContent(generatedFolderPath.resolve(fileName));
|
||||||
|
String expectedFileContent = extractFileContent(expectedFolderPath.resolve(fileName));
|
||||||
|
|
||||||
|
assertThat("Generated file is identical to the file with the expected content", generatedFileContent, is(equalTo(expectedFileContent)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteGeneratedFile(String fileName) throws IOException {
|
||||||
|
Path generatedFilePath = generatedFolderPath.resolve(fileName);
|
||||||
|
Files.delete(generatedFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractFileContent(Path filePath) throws IOException {
|
||||||
|
byte[] fileContentAsBytes = Files.readAllBytes(filePath);
|
||||||
|
String fileContentAsString = new String(fileContentAsBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
if (!fileContentAsString.contains("\r\n")) {
|
||||||
|
// file is not in DOS format
|
||||||
|
// convert it first, so that the content comparison will be relevant
|
||||||
|
return fileContentAsString.replaceAll("\n", "\r\n");
|
||||||
|
}
|
||||||
|
return fileContentAsString;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.javapoet.test.person;
|
||||||
|
|
||||||
|
public enum Gender {
|
||||||
|
MALE,
|
||||||
|
|
||||||
|
FEMALE,
|
||||||
|
|
||||||
|
UNSPECIFIED
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.javapoet.test.person;
|
||||||
|
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
public interface Person {
|
||||||
|
String DEFAULT_NAME = "Alice";
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
default String getDefaultName() {
|
||||||
|
return DEFAULT_NAME;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.baeldung.javapoet.test.person;
|
||||||
|
|
||||||
|
import java.lang.Override;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class Student implements Person {
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printNameMultipleTimes() {
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
IntStream.range(0, 10).forEach(i -> names.add(name));
|
||||||
|
names.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sortByLength(List<String> strings) {
|
||||||
|
Collections.sort(strings, new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String a, String b) {
|
||||||
|
return a.length() - b.length();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
1
pom.xml
1
pom.xml
|
@ -248,6 +248,7 @@
|
||||||
<module>persistence-modules/liquibase</module>
|
<module>persistence-modules/liquibase</module>
|
||||||
<module>spring-boot-property-exp</module>
|
<module>spring-boot-property-exp</module>
|
||||||
<module>testing-modules/mockserver</module>
|
<module>testing-modules/mockserver</module>
|
||||||
|
<module>testing-modules/test-containers</module>
|
||||||
<module>undertow</module>
|
<module>undertow</module>
|
||||||
<module>vertx-and-rxjava</module>
|
<module>vertx-and-rxjava</module>
|
||||||
<module>saas</module>
|
<module>saas</module>
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
- [Docker Test Containers in Java Tests](TODO link to be added.)
|
|
@ -0,0 +1,119 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<!-- NOT NEEDED - JSP <groupId>com.baeldung</groupId> -->
|
||||||
|
<artifactId>test-containers</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<name>test-containers</name>
|
||||||
|
<description>Intro to Java Test Containers</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../../</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/test/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>java</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>com.baeldung.TestLauncher</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.vintage</groupId>
|
||||||
|
<artifactId>junit-vintage-engine</artifactId>
|
||||||
|
<version>${junit.vintage.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>${log4j2.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>testcontainers</artifactId>
|
||||||
|
<version>1.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>postgresql </artifactId>
|
||||||
|
<version>1.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>selenium </artifactId>
|
||||||
|
<version>1.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.seleniumhq.selenium</groupId>
|
||||||
|
<artifactId>selenium-remote-driver</artifactId>
|
||||||
|
<version>3.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<junit.jupiter.version>5.1.0</junit.jupiter.version>
|
||||||
|
<junit.platform.version>1.0.1</junit.platform.version>
|
||||||
|
<junit.vintage.version>4.12.1</junit.vintage.version>
|
||||||
|
<log4j2.version>2.8.2</log4j2.version>
|
||||||
|
<h2.version>1.4.196</h2.version>
|
||||||
|
<mockito.version>2.11.0</mockito.version>
|
||||||
|
|
||||||
|
<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
|
||||||
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
|
<spring.version>5.0.1.RELEASE</spring.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.testconainers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.testcontainers.containers.DockerComposeContainer;
|
||||||
|
|
||||||
|
public class DockerComposeContainerUnitTest {
|
||||||
|
@ClassRule
|
||||||
|
public static DockerComposeContainer compose =
|
||||||
|
new DockerComposeContainer(
|
||||||
|
new File("src/test/resources/test-compose.yml"))
|
||||||
|
.withExposedService("simpleWebServer_1", 80);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse()
|
||||||
|
throws Exception {
|
||||||
|
String address = "http://" + compose.getServiceHost("simpleWebServer_1", 80)
|
||||||
|
+ ":" + compose.getServicePort("simpleWebServer_1", 80);
|
||||||
|
String response = simpleGetRequest(address);
|
||||||
|
|
||||||
|
assertEquals(response, "Hello World!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String simpleGetRequest(String address) throws Exception {
|
||||||
|
URL url = new URL(address);
|
||||||
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod("GET");
|
||||||
|
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||||
|
String inputLine;
|
||||||
|
StringBuffer content = new StringBuffer();
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
content.append(inputLine);
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
return content.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.testconainers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.platform.commons.annotation.Testable;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
|
||||||
|
@Testable
|
||||||
|
public class GenericContainerUnitTest {
|
||||||
|
@ClassRule
|
||||||
|
public static GenericContainer simpleWebServer =
|
||||||
|
new GenericContainer("alpine:3.2")
|
||||||
|
.withExposedPorts(80)
|
||||||
|
.withCommand("/bin/sh", "-c", "while true; do echo "
|
||||||
|
+ "\"HTTP/1.1 200 OK\n\nHello World!\" | nc -l -p 80; done");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenSimpleWebServerContainer_whenGetReuqest_thenReturnsResponse()
|
||||||
|
throws Exception {
|
||||||
|
String address = "http://"
|
||||||
|
+ simpleWebServer.getContainerIpAddress()
|
||||||
|
+ ":" + simpleWebServer.getMappedPort(80);
|
||||||
|
String response = simpleGetRequest(address);
|
||||||
|
|
||||||
|
assertEquals(response, "Hello World!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String simpleGetRequest(String address) throws Exception {
|
||||||
|
URL url = new URL(address);
|
||||||
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod("GET");
|
||||||
|
|
||||||
|
BufferedReader in = new BufferedReader(
|
||||||
|
new InputStreamReader(con.getInputStream()));
|
||||||
|
String inputLine;
|
||||||
|
StringBuffer content = new StringBuffer();
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
content.append(inputLine);
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
return content.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package com.baeldung.testconainers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.platform.commons.annotation.Testable;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
|
||||||
|
@Testable
|
||||||
|
public class PostgreSqlContainerUnitTest {
|
||||||
|
@Rule
|
||||||
|
public PostgreSQLContainer postgresContainer = new PostgreSQLContainer();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSelectQueryExecuted_thenResulstsReturned() throws Exception {
|
||||||
|
ResultSet resultSet = performQuery(postgresContainer, "SELECT 1");
|
||||||
|
resultSet.next();
|
||||||
|
int result = resultSet.getInt(1);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultSet performQuery(PostgreSQLContainer postgres, String query) throws SQLException {
|
||||||
|
String jdbcUrl = postgres.getJdbcUrl();
|
||||||
|
String username = postgres.getUsername();
|
||||||
|
String password = postgres.getPassword();
|
||||||
|
Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
|
||||||
|
return conn.createStatement()
|
||||||
|
.executeQuery(query);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.baeldung.testconainers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||||
|
import org.testcontainers.DockerClientFactory;
|
||||||
|
import org.testcontainers.containers.BrowserWebDriverContainer;
|
||||||
|
import org.testcontainers.containers.GenericContainer;
|
||||||
|
|
||||||
|
public class WebDriverContainerUnitTest {
|
||||||
|
@Rule
|
||||||
|
public BrowserWebDriverContainer chrome
|
||||||
|
= new BrowserWebDriverContainer()
|
||||||
|
.withDesiredCapabilities(DesiredCapabilities.chrome());
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNavigatedToPage_thenHeadingIsInThePage() {
|
||||||
|
RemoteWebDriver driver = chrome.getWebDriver();
|
||||||
|
driver.get("https://saucelabs.com/test/guinea-pig");
|
||||||
|
String heading = driver.findElement(By.xpath("/html/body/h1"))
|
||||||
|
.getText();
|
||||||
|
assertEquals("This page is a Selenium sandbox", heading);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
simpleWebServer:
|
||||||
|
image: alpine:3.2
|
||||||
|
command: ["/bin/sh", "-c", "while true; do echo 'HTTP/1.1 200 OK\n\nHello World!' | nc -l -p 80; done"]
|
Loading…
Reference in New Issue