Skip to content

Commit

Permalink
feat: Native-image metadata and docs (#1264)
Browse files Browse the repository at this point in the history
  • Loading branch information
johanandren authored Feb 28, 2024
1 parent d060896 commit 7b8797c
Show file tree
Hide file tree
Showing 25 changed files with 490 additions and 16 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/native-image-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,22 @@ jobs:
jvm: temurin:1.11

- name: Gather version
# some cleanup of the sbt output to get the version sbt will use when publishing below
run: |-
echo `git describe --tags | sed -e "s/v\(.*\)-\([0-9][0-9]*\).*/\\1+\\2-/"``git rev-parse HEAD | head -c8`-SNAPSHOT > ~/.version
cat ~/.version
sbt "akka-management/version" --batch --no-colors | tail -n 1 | cut -f 2 -d ' ' | tr -d '\n' > ~/.version
echo [$(cat ~/.version)]
# useful for debugging: hexdump -c ~/.version
- name: Publish artifacts locally
run: |-
sbt "publishLocal; publishM2"
#- name: Akka Management native image test app build
# run: |-
# cd native-image-tests/grpc-scala
# sbt nativeImage -Dakka.grpc.version=`cat ~/.version`
# # run the binary, netty client backend
# target/native-image/grpc-scala
# # akka-http client backend
# target/native-image/grpc-scala akka-http-client
- name: Akka Management native image test app build
run: |-
cd native-image-tests
sbt nativeImage -Dakka.management.version=`cat ~/.version`
# run the binary to see it can bootstrap a cluster
target/native-image/native-image-tests
- name: Email on failure
if: ${{ failure() }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[
{
"name": "akka.management.cluster.bootstrap.LowestAddressJoinDecider",
"methods": [
{
"name": "<init>",
"parameterTypes": ["akka.actor.ActorSystem", "akka.management.cluster.bootstrap.ClusterBootstrapSettings"]
}
]
},
{
"name": "akka.management.cluster.bootstrap.ClusterBootstrap$",
"fields": [
{
"name": "MODULE$"
}
]
},
{
"name": "akka.management.cluster.bootstrap.ClusterBootstrap",
"methods": [
{
"name": "<init>",
"parameterTypes": ["akka.actor.ExtendedActorSystem"]
}
]
},
{
"name": "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$SeedNode",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$ClusterMember",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$SeedNodes",
"allDeclaredFields": true,
"queryAllPublicMethods": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ trait HttpBootstrapJsonProtocol extends SprayJsonSupport with DefaultJsonProtoco

override def write(obj: Address): JsValue = JsString(obj.toString)
}

// If adding more formats here, remember to also add in META-INF/native-image reflect config
implicit val SeedNodeFormat: RootJsonFormat[SeedNode] = jsonFormat1(SeedNode.apply)
implicit val ClusterMemberFormat: RootJsonFormat[ClusterMember] = jsonFormat4(ClusterMember.apply)
implicit val ClusterMembersFormat: RootJsonFormat[SeedNodes] = jsonFormat2(SeedNodes.apply)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[
{
"name": "akka.management.cluster.ClusterHttpManagementRouteProvider$",
"fields": [ {
"name": "MODULE$"
} ]
},
{
"name": "akka.management.cluster.javadsl.ClusterMembershipCheck",
"methods": [{
"name": "<init>",
"parameterTypes": ["akka.actor.ActorSystem"]
}]
},
{
"name": "akka.management.cluster.scaladsl.ClusterMembershipCheck",
"methods": [{
"name": "<init>",
"parameterTypes": ["akka.actor.ActorSystem"]
}]
},
{
"name": "akka.management.cluster.ClusterUnreachableMember",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ClusterMember",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ClusterMembers",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ClusterHttpManagementMessage",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ShardEntityTypeKeys",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ShardRegionInfo",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.management.cluster.ShardDetails",
"allDeclaredFields": true,
"queryAllPublicMethods": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ final case class ShardDetails(regions: immutable.Seq[ShardRegionInfo])
}

trait ClusterHttpManagementJsonProtocol extends SprayJsonSupport with DefaultJsonProtocol {
// If adding more formats here, remember to also add in META-INF/native-image reflect config
implicit val clusterUnreachableMemberFormat: RootJsonFormat[ClusterUnreachableMember] =
jsonFormat2(ClusterUnreachableMember.apply)
implicit val clusterMemberFormat: RootJsonFormat[ClusterMember] = jsonFormat4(ClusterMember.apply)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[
{
"name": "akka.discovery.kubernetes.KubernetesApiServiceDiscovery",
"methods": [
{
"name": "<init>",
"parameterTypes": [
"akka.actor.ActorSystem"
]
}
]
},
{
"name": "akka.discovery.kubernetes.PodList$ContainerPort",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.Container",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.PodSpec",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.ContainerStatus",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.PodStatus",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.Pod",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.discovery.kubernetes.PodList.Metadata",
"allDeclaredFields": true,
"queryAllPublicMethods": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import spray.json._
* INTERNAL API
*/
@InternalApi private[akka] object JsonFormat extends SprayJsonSupport with DefaultJsonProtocol {
// If adding more formats here, remember to also add in META-INF/native-image reflect config
implicit val containerPortFormat: JsonFormat[ContainerPort] = jsonFormat2(ContainerPort.apply)
implicit val containerFormat: JsonFormat[Container] = jsonFormat2(Container.apply)
implicit val podSpecFormat: JsonFormat[PodSpec] = jsonFormat1(PodSpec.apply)
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/paradox/cluster-jmx-management.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Built-in JMX Management

Akka has built-in JMX beans which you can use to manage the cluster, read more about them in the Akka
documentation: @extref:[Cluster Usage: JMX](akka:cluster-usage.html#cluster-jmx)
documentation: @extref:[Cluster Usage: JMX](akka:additional/operations.html#jmx)
1 change: 1 addition & 0 deletions docs/src/main/paradox/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ Various parts of Akka management can be used together for deploying Akka Cluster
- [Akka Cluster Management (JMX)](cluster-jmx-management.md)
- [Dynamic Log Levels](loglevels/index.md)
- [Akka Coordination Lease for Kubernetes](kubernetes-lease.md)
- [Native Image](native-image.md)
@@@
14 changes: 14 additions & 0 deletions docs/src/main/paradox/native-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Building Native Images

Building native images with Akka Management is supported out of the box for the following modules:

* akka-management
* akka-management-cluster-bootstrap
* akka-management-cluster-http
* akka-discovery-kubernetes-api
* akka-lease-kubernetes
* akka-rolling-update-kubernetes

Other modules can likely be used but will require figuring out and adding additional native-image metadata.

For details about building native images with Akka in general, see the @extref[Akka Documentation](akka:additional/native-image.html).
2 changes: 1 addition & 1 deletion integration-test/dns-api-mesos/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ libraryDependencies += "com.lightbend.akka.management" %% "akka-management-clust
libraryDependencies += "com.lightbend.akka.management" %% "akka-management-cluster-http" % akkaManagementVersion(
version.value)

libraryDependencies += "com.typesafe.akka" %% "akka-discovery" % "2.9.0"
libraryDependencies += "com.typesafe.akka" %% "akka-discovery" % "2.9.2"
4 changes: 2 additions & 2 deletions integration-test/kubernetes-api-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<properties>
<encoding>UTF-8</encoding>
<maven.compiler.release>11</maven.compiler.release>
<akka.version>2.9.0</akka.version>
<akka.http.version>10.6.0</akka.http.version>
<akka.version>2.9.2</akka.version>
<akka.http.version>10.6.1</akka.http.version>
<akka-management.version>1.5.0</akka-management.version>
<scala.binary.version>2.13</scala.binary.version>
</properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"name": "akka.coordination.lease.kubernetes.KubernetesLease",
"methods": [
{
"name": "<init>",
"parameterTypes": ["akka.coordination.lease.LeaseSettings", "akka.actor.ExtendedActorSystem"]
}
]
},
{
"name": "akka.coordination.lease.kubernetes.internal.LeaseCustomResource",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.coordination.lease.kubernetes.internal.Metadata",
"allDeclaredFields": true,
"queryAllPublicMethods": true
},
{
"name": "akka.coordination.lease.kubernetes.internal.Spec",
"allDeclaredFields": true,
"queryAllPublicMethods": true
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ case class Spec(owner: String, time: Long)
*/
@InternalApi
trait KubernetesJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
// If adding more formats here, remember to also add in META-INF/native-image reflect config
implicit val metadataFormat: JsonFormat[Metadata] = jsonFormat2(Metadata.apply)
implicit val specFormat: JsonFormat[Spec] = jsonFormat2(Spec.apply)
implicit val leaseCustomResourceFormat: RootJsonFormat[LeaseCustomResource] = jsonFormat4(LeaseCustomResource.apply)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"name": "akka.management.scaladsl.AkkaManagement$",
"fields": [ {
"name": "MODULE$"
} ]
},
{
"name": "akka.management.HealthCheckRoutes",
"methods": [{
"name": "<init>",
"parameterTypes": ["akka.actor.ExtendedActorSystem"]
}]
}
]
12 changes: 12 additions & 0 deletions native-image-tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
target/

.settings
.project
.classpath

.idea
*.iml

.metals
.bloop
.bsp
52 changes: 52 additions & 0 deletions native-image-tests/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name := "native-image-tests"

version := "1.0"

scalaVersion := "2.13.12"

resolvers += "Akka library repository".at("https://repo.akka.io/maven")

lazy val akkaVersion = sys.props.getOrElse("akka.version", "2.9.2")
lazy val akkaHttpVersion = sys.props.getOrElse("akka.http.version", "10.6.1")

// Note: this default isn't really used anywhere so not important to bump
lazy val akkaManagementVersion = sys.props.getOrElse("akka.management.version", "1.5.0")

// Run in a separate JVM, to make sure sbt waits until all threads have
// finished before returning.
// If you want to keep the application running while executing other
// sbt tasks, consider https://github.com/spray/sbt-revolver/
fork := true

libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor-typed" % akkaVersion,
"com.typesafe.akka" %% "akka-cluster-typed" % akkaVersion,
"com.typesafe.akka" %% "akka-cluster" % akkaVersion,
"com.typesafe.akka" %% "akka-discovery" % akkaVersion,
"com.typesafe.akka" %% "akka-persistence" % akkaVersion,
"com.typesafe.akka" %% "akka-cluster-sharding" % akkaVersion,
"com.typesafe.akka" %% "akka-remote" % akkaVersion,
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-core" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.lightbend.akka.management" %% "akka-management" % akkaManagementVersion,
"com.lightbend.akka.management" %% "akka-management-cluster-bootstrap" % akkaManagementVersion,
"com.lightbend.akka.management" %% "akka-management-cluster-http" % akkaManagementVersion,
"com.lightbend.akka.discovery" %% "akka-discovery-kubernetes-api" % akkaManagementVersion,
"com.lightbend.akka.management" %% "akka-lease-kubernetes" % akkaManagementVersion,
"com.lightbend.akka.management" %% "akka-rolling-update-kubernetes" % akkaManagementVersion,
"ch.qos.logback" % "logback-classic" % "1.2.13"
)

// useful for investigations: sbt nativeImageRunAgent

// GraalVM native image build
enablePlugins(NativeImagePlugin)
nativeImageJvm := "graalvm-community"
nativeImageVersion := "21.0.2"
nativeImageOptions := Seq(
"--no-fallback",
"--verbose",
"--initialize-at-build-time=ch.qos.logback",
"-Dakka.native-image.debug=true"
)
1 change: 1 addition & 0 deletions native-image-tests/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.8
1 change: 1 addition & 0 deletions native-image-tests/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("org.scalameta" % "sbt-native-image" % "0.3.4")
Loading

0 comments on commit 7b8797c

Please sign in to comment.