Skip to content

Commit c9430ee

Browse files
pzmrzyknative-prow-robot
authored andcommitted
Create Hello World program with Kotlin (#381)
* Create Hello World program with Kotlin * Modify Readme by addressing Grant's comments * Update to gradle official image * Update dockerfile by addressing ivan's comment * Read port from env by addressing samodell's comment * Update Readme by addressing samodell's comment * svc->service
1 parent 70455a3 commit c9430ee

File tree

6 files changed

+294
-1
lines changed

6 files changed

+294
-1
lines changed

serving/samples/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ to learn more about Knative Serving resources.
66

77
| Name | Description | Languages |
88
| ---- | ----------- |:---------:|
9-
| Hello World | A quick introduction that highlights how to deploy an app using Knative Serving. | [C#](helloworld-csharp/README.md), [Clojure](helloworld-clojure/README.md), [Go](helloworld-go/README.md), [Java](helloworld-java/README.md), [Node.js](helloworld-nodejs/README.md), [PHP](helloworld-php/README.md), [Python](helloworld-python/README.md), [Ruby](helloworld-ruby/README.md), [Rust](helloworld-rust/README.md) |
9+
| Hello World | A quick introduction that highlights how to deploy an app using Knative Serving. | [C#](helloworld-csharp/README.md), [Clojure](helloworld-clojure/README.md), [Go](helloworld-go/README.md), [Java](helloworld-java/README.md), [Kotlin](helloworld-kotlin/README.md), [Node.js](helloworld-nodejs/README.md), [PHP](helloworld-php/README.md), [Python](helloworld-python/README.md), [Ruby](helloworld-ruby/README.md), [Rust](helloworld-rust/README.md) |
1010
| Advanced Deployment | Simple blue/green-like application deployment pattern illustrating the process of updating a live application without dropping any traffic. | [YAML](blue-green-deployment.md) |
1111
| Autoscale | A demonstration of the autoscaling capabilities of Knative. | [Go](autoscale-go/README.md) |
1212
| Private Repo Build | An example of deploying a Knative Serving Service using a Github deploy-key and a DockerHub image pull secret. | [Go](build-private-repo-go/README.md) |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM gradle
2+
3+
ADD build.gradle ./build.gradle
4+
ADD src ./src
5+
RUN gradle clean build
6+
ENTRYPOINT ["java","-jar","-Djava.security.egd=file:/dev/./urandom","/home/gradle/build/libs/gradle.jar"]
7+
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Hello World - Kotlin sample
2+
3+
A simple web app written in Kotlin using [Ktor](https://ktor.io/) that you can use for testing.
4+
It reads in an env variable `TARGET` and prints "Hello ${TARGET}". If
5+
TARGET is not specified, it will use "World" as the TARGET.
6+
7+
## Prerequisites
8+
9+
* A Kubernetes cluster with Knative installed. Follow the
10+
[installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need
11+
to create one.
12+
* [Docker](https://www.docker.com) installed and running on your local machine,
13+
and a Docker Hub account configured (we'll use it for a container registry).
14+
15+
## Steps to recreate the sample code
16+
17+
While you can clone all of the code from this directory, hello world apps are
18+
generally more useful if you build them step-by-step.
19+
The following instructions recreate the source files from this folder.
20+
21+
1. Create a new directory and cd into it:
22+
23+
```shell
24+
mkdir hello
25+
cd hello
26+
```
27+
2. Create a file named `Main.kt` at `src/main/kotlin/com/example/hello` and copy the code block below into it:
28+
29+
```shell
30+
mkdir -p src/main/kotlin/com/example/hello
31+
```
32+
33+
```kotlin
34+
package com.example.hello
35+
36+
import io.ktor.application.*
37+
import io.ktor.http.*
38+
import io.ktor.response.*
39+
import io.ktor.routing.*
40+
import io.ktor.server.engine.*
41+
import io.ktor.server.netty.*
42+
43+
fun main(args: Array<String>) {
44+
val target = System.getenv("TARGET") ?: "World"
45+
val port = System.getenv("PORT") ?: "8080"
46+
embeddedServer(Netty, port.toInt()) {
47+
routing {
48+
get("/") {
49+
call.respondText("Hello $target", ContentType.Text.Html)
50+
}
51+
}
52+
}.start(wait = true)
53+
}
54+
```
55+
3. Switch back to `hello` directory
56+
57+
4. Create a new file, `build.gradle` and copy the following setting
58+
59+
```groovy
60+
buildscript {
61+
ext.kotlin_version = '1.2.61'
62+
ext.ktor_version = '0.9.4'
63+
64+
repositories {
65+
mavenCentral()
66+
}
67+
dependencies {
68+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
69+
}
70+
}
71+
72+
apply plugin: 'java'
73+
apply plugin: 'kotlin'
74+
apply plugin: 'application'
75+
76+
sourceCompatibility = 1.8
77+
compileKotlin {
78+
kotlinOptions.jvmTarget = "1.8"
79+
}
80+
81+
compileTestKotlin {
82+
kotlinOptions.jvmTarget = "1.8"
83+
}
84+
85+
repositories {
86+
jcenter()
87+
maven { url "https://dl.bintray.com/kotlin/ktor" }
88+
}
89+
90+
mainClassName = 'com.example.hello.MainKt'
91+
92+
jar {
93+
manifest {
94+
attributes 'Main-Class': mainClassName
95+
}
96+
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
97+
}
98+
99+
dependencies {
100+
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
101+
compile "io.ktor:ktor-server-netty:$ktor_version"
102+
testCompile group: 'junit', name: 'junit', version: '4.12'
103+
}
104+
```
105+
106+
5. Create a file named `Dockerfile` and copy the code block below into it.
107+
108+
```docker
109+
FROM gradle
110+
111+
ADD build.gradle ./build.gradle
112+
ADD src ./src
113+
RUN gradle clean build
114+
ENTRYPOINT ["java","-jar","-Djava.security.egd=file:/dev/./urandom","/home/gradle/build/libs/gradle.jar"]
115+
```
116+
117+
6. Create a new file, `service.yaml` and copy the following service definition
118+
into the file. Make sure to replace `{username}` with your Docker Hub username.
119+
120+
```yaml
121+
apiVersion: serving.knative.dev/v1alpha1
122+
kind: Service
123+
metadata:
124+
name: helloworld-kotlin
125+
namespace: default
126+
spec:
127+
runLatest:
128+
configuration:
129+
revisionTemplate:
130+
spec:
131+
container:
132+
image: docker.io/{username}/helloworld-kotlin
133+
env:
134+
- name: TARGET
135+
value: "Kotlin Sample v1"
136+
```
137+
138+
## Build and deploy this sample
139+
140+
Once you have recreated the sample code files (or used the files in the sample
141+
folder) you're ready to build and deploy the sample app.
142+
143+
1. Use Docker to build the sample code into a container. To build and push with
144+
Docker Hub, run these commands replacing `{username}` with your
145+
Docker Hub username:
146+
147+
```shell
148+
# Build the container on your local machine
149+
docker build -t {username}/helloworld-kotlin .
150+
151+
# Push the container to docker registry
152+
docker push {username}/helloworld-kotlin
153+
```
154+
155+
2. After the build has completed and the container is pushed to docker hub, you
156+
can deploy the app into your cluster. Ensure that the container image value
157+
in `service.yaml` matches the container you built in
158+
the previous step. Apply the configuration using `kubectl`:
159+
160+
```shell
161+
kubectl apply -f service.yaml
162+
```
163+
164+
3. Now that your service is created, Knative will perform the following steps:
165+
* Create a new immutable revision for this version of the app.
166+
* Network programming to create a route, ingress, service, and load balance for your app.
167+
* Automatically scale your pods up and down (including to zero active pods).
168+
169+
4. To find the IP address for your service, use
170+
`kubectl get service knative-ingressgateway -n istio-system` to get the ingress IP for your
171+
cluster. If your cluster is new, it may take sometime for the service to get assigned
172+
an external IP address.
173+
174+
```shell
175+
kubectl get service knative-ingressgateway -n istio-system
176+
```
177+
```shell
178+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
179+
knative-ingressgateway LoadBalancer 10.23.247.74 35.203.155.229 80:32380/TCP,443:32390/TCP,32400:32400/TCP 2d
180+
```
181+
182+
5. To find the URL for your service, use
183+
```shell
184+
kubectl get services.serving.knative.dev helloworld-kotlin -o=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
185+
```
186+
```shell
187+
NAME DOMAIN
188+
helloworld-kotlin helloworld-kotlin.default.example.com
189+
```
190+
191+
6. Now you can make a request to your app to see the result. Replace `{IP_ADDRESS}`
192+
with the address you see returned in the previous step.
193+
194+
```shell
195+
curl -H "Host: helloworld-kotlin.default.example.com" http://{IP_ADDRESS}
196+
```
197+
```shell
198+
Hello Kotlin Sample v1
199+
```
200+
201+
## Remove the sample app deployment
202+
203+
To remove the sample app from your cluster, delete the service record:
204+
205+
```shell
206+
kubectl delete -f service.yaml
207+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
buildscript {
2+
ext.kotlin_version = '1.2.61'
3+
ext.ktor_version = '0.9.4'
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
dependencies {
9+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
10+
}
11+
}
12+
13+
apply plugin: 'java'
14+
apply plugin: 'kotlin'
15+
apply plugin: 'application'
16+
17+
sourceCompatibility = 1.8
18+
compileKotlin {
19+
kotlinOptions.jvmTarget = "1.8"
20+
}
21+
compileTestKotlin {
22+
kotlinOptions.jvmTarget = "1.8"
23+
}
24+
25+
repositories {
26+
jcenter()
27+
maven { url "https://dl.bintray.com/kotlin/ktor" }
28+
}
29+
30+
mainClassName = 'com.example.hello.MainKt'
31+
32+
jar {
33+
manifest {
34+
attributes 'Main-Class': mainClassName
35+
36+
}
37+
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
38+
}
39+
40+
dependencies {
41+
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
42+
compile "io.ktor:ktor-server-netty:$ktor_version"
43+
testCompile group: 'junit', name: 'junit', version: '4.12'
44+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: serving.knative.dev/v1alpha1
2+
kind: Service
3+
metadata:
4+
name: helloworld-kotlin
5+
namespace: default
6+
spec:
7+
runLatest:
8+
configuration:
9+
revisionTemplate:
10+
spec:
11+
container:
12+
image: docker.io/{username}/helloworld-kotlin
13+
env:
14+
- name: TARGET
15+
value: "Kotlin Sample v1"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.example.hello
2+
3+
import io.ktor.application.*
4+
import io.ktor.http.*
5+
import io.ktor.response.*
6+
import io.ktor.routing.*
7+
import io.ktor.server.engine.*
8+
import io.ktor.server.netty.*
9+
10+
fun main(args: Array<String>) {
11+
val target = System.getenv("TARGET") ?: "World"
12+
val port = System.getenv("PORT") ?: "8080"
13+
embeddedServer(Netty, port.toInt()) {
14+
routing {
15+
get("/") {
16+
call.respondText("Hello $target", ContentType.Text.Html)
17+
}
18+
}
19+
}.start(wait = true)
20+
}

0 commit comments

Comments
 (0)