* Singleton injection examples and tests added

* code and tests implemented

* test refactored

* kotlin + jee

* kotlin - integration test fixed

* fixes

* arquillian-kotlin integration fixed

* formatting

* formatting

* data class enhanced
This commit is contained in:
enpy 2019-07-11 08:35:55 +02:00 committed by maibin
parent c5f32da311
commit 4518645a1f
10 changed files with 540 additions and 0 deletions

1
jee-kotlin/README.md Normal file
View File

@ -0,0 +1 @@
### Relevant Articles:

289
jee-kotlin/pom.xml Normal file
View File

@ -0,0 +1,289 @@
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>jee-kotlin</artifactId>
<name>jee-kotlin</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
<javaee-api.version>8.0</javaee-api.version>
<kotlin.version>1.3.41</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<wildfly.version>8.2.1.Final</wildfly.version>
<mvn-war-plugin.version>3.2.3</mvn-war-plugin.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
<arquillian_core.version>1.4.1.Final</arquillian_core.version>
<arquillian-drone-bom.version>2.0.1.Final</arquillian-drone-bom.version>
<arquillian-rest-client.version>1.0.0.Alpha4</arquillian-rest-client.version>
<junit.version>4.12</junit.version>
<resteasy.version>3.8.0.Final</resteasy.version>
<jackson.version>2.9.8</jackson.version>
<shrinkwrap.version>3.1.3</shrinkwrap.version>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>${arquillian_core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>${shrinkwrap.version}</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-jersey</artifactId>
<version>${arquillian-rest-client.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${mvn-war-plugin.version}</version>
<configuration>
<warSourceDirectory>webapp</warSourceDirectory>
<warName>kotlin</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian_core.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-drone-bom</artifactId>
<version>${arquillian-drone-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>wildfly-managed-arquillian</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>${wildfly.version}</version>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${wildfly.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- You need the maven dependency plugin to download locally a zip with the server,
unless you provide your own, it will download under the /target directory -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-dist</artifactId>
<version>${wildfly.version}</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<!-- Fork every test because it will launch a separate AS instance -->
<forkMode>always</forkMode>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<jboss.home>${project.basedir}/target/wildfly-${wildfly.version}</jboss.home>
<module.path>${project.basedir}/target/wildfly-${wildfly.version}/modules</module.path>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>wildfly-remote-arquillian</id>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-json-p-provider</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-remote</artifactId>
<version>2.2.0.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,22 @@
package com.baeldung.jeekotlin.entity
import com.fasterxml.jackson.annotation.JsonProperty
import javax.persistence.*
@Entity
data class Student constructor (
@SequenceGenerator(name = "student_id_seq", sequenceName = "student_id_seq", allocationSize = 1)
@GeneratedValue(generator = "student_id_seq", strategy = GenerationType.SEQUENCE)
@Id
var id: Long?,
var firstName: String,
var lastName: String
) {
constructor() : this(null, "", "")
constructor(firstName: String, lastName: String) : this(null, firstName, lastName)
}

View File

@ -0,0 +1,9 @@
package com.baeldung.jeekotlin.rest
import javax.ws.rs.ApplicationPath
import javax.ws.rs.core.Application
@ApplicationPath("/")
class ApplicationConfig : Application() {
override fun getClasses() = setOf(StudentResource::class.java)
}

View File

@ -0,0 +1,42 @@
package com.baeldung.jeekotlin.rest
import com.baeldung.jeekotlin.entity.Student
import com.baeldung.jeekotlin.service.StudentService
import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
@Path("/student")
open class StudentResource {
@Inject
private lateinit var service: StudentService
@POST
open fun create(student: Student): Response {
service.create(student)
return Response.ok().build()
}
@GET
@Path("/{id}")
open fun read(@PathParam("id") id: Long): Response {
val student = service.read(id)
return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
}
@PUT
open fun update(student: Student): Response {
service.update(student)
return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
}
@DELETE
@Path("/{id}")
open fun delete(@PathParam("id") id: Long): Response {
service.delete(id)
return Response.noContent().build()
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.jeekotlin.service
import com.baeldung.jeekotlin.entity.Student
import javax.ejb.Stateless
import javax.persistence.EntityManager
import javax.persistence.PersistenceContext
@Stateless
open class StudentService {
@PersistenceContext
private lateinit var entityManager: EntityManager
open fun create(student: Student) = entityManager.persist(student)
open fun read(id: Long): Student? = entityManager.find(Student::class.java, id)
open fun update(student: Student) = entityManager.merge(student)
open fun delete(id: Long) = entityManager.remove(read(id))
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="pu" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<class>com.enpy.entity.Student</class>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>

View File

@ -0,0 +1,108 @@
package com.baeldung.jeekotlin;
import com.baeldung.jeekotlin.entity.Student;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URISyntaxException;
import java.net.URL;
import static org.junit.Assert.assertEquals;
@RunWith(Arquillian.class)
public class StudentResourceIntegrationTest {
@Deployment
public static WebArchive createDeployment() {
JavaArchive[] kotlinRuntime = Maven.configureResolver()
.workOffline()
.withMavenCentralRepo(true)
.withClassPathResolution(true)
.loadPomFromFile("pom.xml")
.resolve("org.jetbrains.kotlin:kotlin-stdlib")
.withTransitivity()
.as(JavaArchive.class);
return ShrinkWrap.create(WebArchive.class, "kotlin.war")
.addPackages(true, Filters.exclude(".*Test*"),
"com.baeldung.jeekotlin"
)
.addAsLibraries(kotlinRuntime)
.addAsResource("META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
@RunAsClient
public void when_post__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
String student = new ObjectMapper().writeValueAsString(new Student("firstName", "lastName"));
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(student));
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_get__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student/1")
.request(MediaType.APPLICATION_JSON)
.get();
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_put__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
Student student = new Student("firstName", "lastName");
student.setId(1L);
String studentJson = new ObjectMapper().writeValueAsString(student);
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student")
.request(MediaType.APPLICATION_JSON)
.put(Entity.json(studentJson));
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_delete__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student/1")
.request()
.delete();
assertEquals(204, response.getStatus());
}
}

View File

@ -0,0 +1,22 @@
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="wildfly-managed">
<configuration>
<property name="jbossHome">target/wildfly-8.2.1.Final</property>
<property name="serverConfig">standalone.xml</property>
<property name="outputToConsole">true</property>
<property name="managementPort">9990</property>
</configuration>
</container>
<container qualifier="wildfly-remote" default="true">
<configuration>
<property name="managementAddress">127.0.0.1</property>
<property name="managementPort">9990</property>
<property name="username">admin</property>
<property name="password">pass</property>
<property name="allowConnectingToRunningServer">true</property>
</configuration>
</container>
</arquillian>