Skip to content
This repository has been archived by the owner on Jul 27, 2023. It is now read-only.

Commit

Permalink
Add Kotlin Template to Spring Boot Stack (#107)
Browse files Browse the repository at this point in the history
* Add Kotlin support

* Test Kotlin endpoint
  • Loading branch information
BarDweller authored and neeraj-laad committed Jul 25, 2019
1 parent 6cd54fd commit 9f7f052
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 6 deletions.
11 changes: 10 additions & 1 deletion incubator/java-spring-boot2/image/Dockerfile-stack
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@ LABEL maintainer="IBM Java Engineering at IBM Cloud"

# Ensure up to date / patched OS
RUN apt-get -qq update \
&& apt-get -qq install -y curl wget xmlstarlet \
&& apt-get -qq install -y curl wget xmlstarlet unzip \
&& DEBIAN_FRONTEND=noninteractive apt-get -qq upgrade -y \
&& apt-get -qq clean \
&& rm -rf /tmp/* /var/lib/apt/lists/*

# Kotlin support
COPY ./project/stack.properties /project/stack.properties
RUN cd /usr/lib && \
KVER=$(cat /project/stack.properties | grep kotlin.version | sed 's/kotlin.version=//') && \
wget -q https://github.com/JetBrains/kotlin/releases/download/v$KVER/kotlin-compiler-$KVER.zip && \
unzip kotlin-compiler-*.zip && \
rm kotlin-compiler-*.zip && \
rm -f kotlinc/bin/*.bat

COPY ./project /project
COPY ./mvn-stack-settings.xml /usr/share/maven/conf/settings.xml
COPY ./mvn-stack-settings.xml /project/.mvn-stack-settings.xml
Expand Down
11 changes: 10 additions & 1 deletion incubator/java-spring-boot2/image/project/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ LABEL maintainer="IBM Java Engineering at IBM Cloud"

# Ensure up to date / patched OS
RUN apt-get -qq update \
&& apt-get -qq install -y curl wget xmlstarlet \
&& apt-get -qq install -y curl wget xmlstarlet unzip \
&& DEBIAN_FRONTEND=noninteractive apt-get -qq upgrade -y \
&& apt-get -qq clean \
&& rm -rf /tmp/* /var/lib/apt/lists/* \
&& mkdir -p /mvn/repository

# Kotlin support
COPY ./stack.properties /project/stack.properties
RUN cd /usr/lib && \
KVER=$(cat /project/stack.properties | grep kotlin.version | sed 's/kotlin.version=//') && \
wget -q https://github.com/JetBrains/kotlin/releases/download/v$KVER/kotlin-compiler-$KVER.zip && \
unzip kotlin-compiler-*.zip && \
rm kotlin-compiler-*.zip && \
rm -f kotlinc/bin/*.bat

#setup project folder for java build step
COPY . /project
COPY ./.mvn-stack-settings.xml /usr/share/maven/conf/settings.xml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>dev.appsody</groupId>
<artifactId>spring-boot2-stack</artifactId>
<version>0.3.1</version>
<version>0.3.2</version>
<packaging>pom</packaging>

<name>Appsody Spring Boot2 stack</name>
Expand Down Expand Up @@ -42,6 +42,8 @@
<opentracing-spring-jaeger-web-starter.version>2.0.0</opentracing-spring-jaeger-web-starter.version>

<java.version>1.8</java.version>
<kotlin.version>1.3.40</kotlin.version> <!-- matches ver in stack.properties -->

<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
1 change: 1 addition & 0 deletions incubator/java-spring-boot2/image/project/stack.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
kotlin.version=1.3.40
4 changes: 2 additions & 2 deletions incubator/java-spring-boot2/stack.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Spring Boot®
version: 0.3.1
version: 0.3.2
description: Spring Boot using OpenJ9 and Maven
license: Apache-2.0
maintainers:
- name: Erin Schnabel
email: schnabel@us.ibm.com
github-id: ebullient
default-template: default
default-template: default
2 changes: 1 addition & 1 deletion incubator/java-spring-boot2/templates/default/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent><!--required parent POM-->
<groupId>dev.appsody</groupId>
<artifactId>spring-boot2-stack</artifactId>
<version>0.3.1</version>
<version>0.3.2</version>
<relativePath/>
</parent>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stack: appsody/java-spring-boot2:0.3
27 changes: 27 additions & 0 deletions incubator/java-spring-boot2/templates/kotlin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/target/*

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
/build/

### VS Code ###
.vscode/
136 changes: 136 additions & 0 deletions incubator/java-spring-boot2/templates/kotlin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?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>

<parent><!--required parent POM-->
<groupId>dev.appsody</groupId>
<artifactId>spring-boot2-stack</artifactId>
<version>0.3.2</version>
<relativePath/>
</parent>

<groupId>dev.appsody</groupId>
<artifactId>application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<!-- versions will come from the parent pom (and included bom):
mvn dependency:tree
mvn dependency:display-ancestors
mvn help:effective-pom | grep '\.version>'
-->

<dependencies>
<!-- From parent:
org.springframework.boot:spring-boot-starter
org.springframework.boot:spring-boot-starter-actuator
org.springframework.boot:spring-boot-starter-test
-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

@SpringBootApplication
public class Main {

public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}

// Simple custom liveness check
@Endpoint(id = "liveness")
@Component
public class Liveness {
@ReadOperation
public String testLiveness() {
return "{\"status\":\"UP\"}";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package application

import org.springframework.web.bind.annotation.RestController
import org.springframework.ui.Model
import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping

@RestController
class Hello {

@GetMapping("/hello")
fun hello(): String {
return "Hello, Appsody!"
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#enable the actuator endpoints for health, metrics, and prometheus.
management.endpoints.web.exposure.include=health,metrics,prometheus,liveness
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello from Appsody!</title>
</head>
<body>
<h3>Hello from Appsody!</h3>
<p>Next steps with Spring Boot 2:
<ul>
<li><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/">Spring Boot Reference Guide</a></li>
<li><a target="_blank" rel="noopener" href="https://spring.io/guides">Spring Guides</a></li>
<li><a target="_blank" rel="noopener" href="/actuator">Spring Boot Actuator endpoints</a>:
<ul>
<li><a target="_blank" rel="noopener" href="/actuator/health">Health</a></li>
<li><a target="_blank" rel="noopener" href="/actuator/liveness">Appsody Liveness</a></li>
<li><a target="_blank" rel="noopener" href="/actuator/metrics">Metrics</a></li>
<li><a target="_blank" rel="noopener" href="/actuator/prometheus">Prometheus</a></li>
</ul>
</li>
</ul>
</p>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package application;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainTests {

@Autowired
private TestRestTemplate restTemplate;

@Test
public void testHealthEndpoint() {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/actuator/health", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
}

@Test
public void testKotlinEndpoint() {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/hello", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("Hello, Appsody!");
}

@Test
public void testLivenessEndpoint() {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/actuator/liveness", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\"");
}

@Test
@SuppressWarnings("unchecked")
public void testMetricsEndpoint() {
testLivenessEndpoint(); // access a page

@SuppressWarnings("rawtypes")
ResponseEntity<Map> entity = this.restTemplate.getForEntity("/actuator/metrics", Map.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);

Map<String, Object> body = entity.getBody();
assertThat(body).containsKey("names");
assertThat((List<String>) body.get("names")).contains("jvm.buffer.count");
}

@Test
public void testPrometheusEndpoint() {
testLivenessEndpoint(); // access a page

ResponseEntity<String> entity = this.restTemplate.getForEntity("/actuator/prometheus", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("# TYPE jvm_buffer_count_buffers gauge");
}
}

0 comments on commit 9f7f052

Please sign in to comment.