Skip to content

Commit

Permalink
Update SE restful web service guide and code (#364)
Browse files Browse the repository at this point in the history
Significant revisions to the guide and the augmented code
  • Loading branch information
tjquinno authored Feb 5, 2019
1 parent 5edc48e commit 1825a1c
Show file tree
Hide file tree
Showing 5 changed files with 637 additions and 779 deletions.
202 changes: 105 additions & 97 deletions examples/guides/mp-restful-webservice/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -171,74 +171,6 @@ For this example add these dependencies:
If you run your project from the IDE, the IDE typically handles the main class and places
dependent JARs on the runtime classpath for you and your pom is now ready to go.
// _include::0-65:{se-guide-adoc}[tag=runMavenOutsideIDE]
==== To run Maven outside your IDE
If you want to use Maven yourself,
outside the IDE, then add the following to your pom. (This is typical with Maven
projects and is not specific to Helidon or this example):
[source,xml]
// _include::3-4:{pom}[tag=libsCopying]
// _include::11-24:{pom}[tag=mainClassPlugin]
// _include::28-49:{pom}[tag=copyDependencies]
----
<properties>
...
<mainClass>your-fully-qualified-main-class</mainClass> <!--1-->
<libs.classpath.prefix>libs</libs.classpath.prefix>
<copied.libs.dir>${project.build.directory}/${libs.classpath.prefix}</copied.libs.dir>
...
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration> <!--2-->
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>${libs.classpath.prefix}</classpathPrefix>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin> <!--3-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${copied.libs.dir}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>runtime</includeScope>
<excludeScope>test</excludeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
----
<1> Make sure to specify your own main class path.
<2> Instructs Maven what main class to set in the JAR's manifest and what prefix to use for
copied dependency JARs.
<3> Tells Maven to package the dependency JARs in the specified directory relative to the project's JAR.
=== Create an MP config file
This file contains settings for the Helidon web server and the
application. Note that the MP Config specification says that
Expand Down Expand Up @@ -595,11 +527,11 @@ Or, to use Maven outside the IDE, build your app this way:
mvn package
and run it like this:
[source,bash]
java -jar target/your-jar-name.jar
[source,bash,subs="attributes+"]
java -jar target/{artifact-id}.jar
Once you have started your app, from another command window run these commands
to access its functions (order is important for the last two):
to access its functions:
[[curl-command-table]]
|====
|Command |Result |Function
Expand Down Expand Up @@ -630,7 +562,7 @@ a|[listing]
|====
== Add health checks
// _include::0-36:{se-guide-adoc}[tag=addHealthChecksIntro]
// _include::0-37:{se-guide-adoc}[tag=addHealthChecksIntro]
A well-behaved microservice reports on its own health.
Two common approaches for checking health, often used together, are:
Expand All @@ -654,10 +586,11 @@ for the service to operate
- health of other, dependent services - if other services on which this service
depends are themselves OK.
For this example we define our service as "alive" in a very trivial way.
We will add an app-specific liveness check.
Our greeting service does not depend on any
host resources (like disk space) or any other services. So we choose to define our
greeting service to be OK if the greeting text has been assigned
host resources (like disk space) or any other services. So for this
example we define our service as "alive" in a very trivial way:
if the greeting text has been assigned
_and is not empty_ when trimmed of leading or trailing white space. Otherwise we
consider the service to be unhealthy, in which case the service will
still respond but its answers might not be what we want.
Expand Down Expand Up @@ -791,56 +724,131 @@ passed to `CollectionsHelper.setOf`:
}
----
// _include::0-47:{se-guide-adoc}[tags=rebuildAndRerunService;tryReadiness;tryLiveness]
// _include::0-122:{se-guide-adoc}[tags=rebuildAndRerunService;tryReadiness]
=== Stop, rebuild and rerun your service
. Stop any running instance of your app.
. Rebuild the app and then run it.
=== Try the readiness check
Access the readiness check endpoint:
=== Check the server's health
Run this command:
[source,bash]
curl -i -X GET http://localhost:8080/ready
curl -X GET http://localhost:8080/health | python -m json.tool
You should see output as shown in this example:
[listing,subs=+quotes]
----
{
"checks": [
{
"name": "deadlock",
"state": "UP"
},
{
"data": {
"free": "179.37 GB",
"freeBytes": 192597303296,
"percentFree": "38.51%",
"total": "465.72 GB",
"totalBytes": 500068036608
},
"name": "diskSpace",
"state": "UP"
},
*{
"name": "greetingAlive",
"state": "UP"
}*,
{
"data": {
"free": "255.99 MB",
"freeBytes": 268422144,
"max": "4.00 GB",
"maxBytes": 4294967296,
"percentFree": "98.73%",
"total": "308.00 MB",
"totalBytes": 322961408
},
"name": "heapMemory",
"state": "UP"
}
],
"outcome": "UP"
}
----
The JSON output conveys various health indicators because the generated code
included `HealthChecks.healthChecks()` in the `HealthSupport.builder`.
The item labeled `outcome` describes the overall health of the
server based on all the other indicators. The state of all the indicators is UP.
So the `outcome` field shows UP. You should also see our app-specific liveness check in the output
(bolded above).
Our readiness check returns no payload, just the 200 status, so you won't see any data
displayed. The `-i` option shows the
200 status in the response.
=== Arrange for an unhealthy report
Recall that our simple rule for liveness is that the greeting be non-null and
non-empty. We can easily force our server to report an unhealthy state.
=== Try the liveness check
. Ping the health check endpoint
. Set the greeting to a blank.
+
--
Without changing the greeting, ping the health endpoint:
[source,bash]
curl -i -X GET http://localhost:8080/alive
curl -X PUT http://localhost:8080/greet/greeting/%20
The greeting is valid and in that case our health check code simply returns a 200
with no payload.
Our code to update the greeting accepts this and saves it as the new greeting.
--
. Set the greeting to a blank
. Ping the health check endpoint again with the same command as before.
+
--
[source,bash]
curl -X PUT http://localhost:8080/greet/greeting/%20
curl -X GET http://localhost:8080/health | python -m json.tool
Our code to update the greeting accepts this and saves it as the new greeting.
This time you should see these two parts of the output indicating that something is
wrong:
[listing]
----
{
"data": {
"greeting": "not set or is empty"
},
"name": "greetingAlive",
"state": "DOWN"
}
...
"outcome": "DOWN"
----
If you add `-i` to the `curl` command and remove the pipe, the output includes the status 503 "Service Unavailable" report:
[source,bash]
curl -i -X GET http://localhost:8080/health
[listing]
----
HTTP/1.1 503 Service Unavailable
Content-Type: application/json
Date: Tue, 5 Feb 2019 08:09:22 -0600
transfer-encoding: chunked
connection: keep-alive
...
----
--
. Ping the health check endpoint again with the same command as before
. Set the greeting back to "Hello", so that the service is healthy again.
+
--
[source,bash]
curl -i -X GET http://localhost:8080/alive
curl -X PUT http://localhost:8080/greet/greeting/Hello
--
This time you should see
[listing]
{"error":"greeting is not set or is empty"}
. Check the health again.
+
--
[source,bash]
curl -X GET http://localhost:8080/health | python -m json.tool
and with the `-i` added to the `curl` command you would see the 500 status returned.
This time the `outcome` and `greetingAlive` values will be back to `UP`.
--
== Add metrics support
// _include::0-1:{se-guide-adoc}[tag=metricsIntro]
As a simple illustration of using metrics, we revise our greeting service to count how many times
Expand Down
Loading

0 comments on commit 1825a1c

Please sign in to comment.