Skip to content

Commit 3c92fa4

Browse files
authored
Add health check endpoint (#1016)
* add health check endpoint * rewrite test to pekko http
1 parent 771f7b2 commit 3c92fa4

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,11 @@ ElasticMQ exposes `Queues` MBean. It contains three operations:
627627
* `NumberOfMessagesForAllQueues` - returns tabular data that contains information about number of messages per queue
628628
* `getNumberOfMessagesInQueue` - returns information about number of messages in specified queue
629629

630+
# Health check endpoint
631+
632+
When running the server in a container orchestration environment, it may be useful to have a health check endpoint.
633+
ElasticMQ provides a simple health check endpoint that can be used for this purpose. The endpoint is available at `/health`.
634+
630635
# Technology
631636

632637
* Core: [Scala](http://scala-lang.org) and [Pekko](https://pekko.apache.org/).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.elasticmq.rest.sqs
2+
import org.apache.pekko.http.scaladsl.Http
3+
import org.apache.pekko.http.scaladsl.model.{HttpRequest, HttpResponse, StatusCodes}
4+
import org.apache.pekko.http.scaladsl.testkit.ScalatestRouteTest
5+
import org.scalatest.matchers.should.Matchers
6+
7+
import scala.concurrent.duration.DurationInt
8+
import scala.concurrent.{Await, Future}
9+
10+
class HealthCheckTest extends SqsClientServerCommunication with ScalatestRouteTest with Matchers {
11+
12+
test("health check") {
13+
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = s"$ServiceEndpoint/health"))
14+
val response = Await.result(responseFuture, 10.seconds)
15+
16+
response.status shouldBe StatusCodes.OK
17+
18+
val entityFuture = response.entity.dataBytes.runFold("")(_ ++ _.utf8String)
19+
val entity = Await.result(entityFuture, 10.seconds)
20+
21+
entity shouldBe "OK"
22+
}
23+
}

rest/rest-sqs/src/main/scala/org/elasticmq/rest/sqs/SQSRestServerBuilder.scala

+12-9
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@ import org.elasticmq.actor.QueueManagerActor
1111
import org.elasticmq.metrics.QueuesMetrics
1212
import org.elasticmq.rest.sqs.Constants._
1313
import org.elasticmq.rest.sqs.XmlNsVersion.extractXmlNs
14-
import org.elasticmq.rest.sqs.directives.{
15-
AnyParamDirectives,
16-
AWSProtocolDirectives,
17-
ElasticMQDirectives,
18-
UnmatchedActionRoutes
19-
}
14+
import org.elasticmq.rest.sqs.directives.{AWSProtocolDirectives, AnyParamDirectives, ElasticMQDirectives, UnmatchedActionRoutes}
2015
import org.elasticmq.rest.sqs.model.RequestPayload
2116
import org.elasticmq.util.{Logging, NowProvider}
2217

@@ -29,10 +24,10 @@ import java.util.concurrent.atomic.AtomicReference
2924
import javax.management.ObjectName
3025
import scala.collection.immutable.TreeMap
3126
import scala.collection.mutable.ArrayBuffer
32-
import scala.concurrent.{Await, Future}
3327
import scala.concurrent.duration._
34-
import scala.util.{Failure, Success, Try}
28+
import scala.concurrent.{Await, Future}
3529
import scala.util.control.NonFatal
30+
import scala.util.{Failure, Success, Try}
3631
import scala.xml._
3732

3833
/** By default: <li> <ul>for `socketAddress`: when started, the server will bind to `localhost:9324`</ul> <ul>for
@@ -222,7 +217,13 @@ case class TheSQSRestServerBuilder(
222217

223218
val config = new ElasticMQConfig
224219

225-
val routes =
220+
val healthCheckRoute = path("health") {
221+
get {
222+
complete("OK")
223+
}
224+
}
225+
226+
val sqsRoute =
226227
extractXmlNs { (_version: XmlNsVersion) =>
227228
implicit val version: XmlNsVersion = _version
228229
extractProtocol { (_protocol: AWSProtocol) =>
@@ -242,6 +243,8 @@ case class TheSQSRestServerBuilder(
242243
}
243244
}
244245

246+
val routes = concat(healthCheckRoute, sqsRoute)
247+
245248
val appStartFuture = {
246249
// Scala 3 fix: implicit resolution conflict
247250
implicit val _implicitActorSystem: ActorSystem = implicitActorSystem

0 commit comments

Comments
 (0)