Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion clustered/clustered-dist/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ distributions {
}
into ('') {
from 'src/assemble'
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [version: project.version])
}
}
}
Expand All @@ -153,4 +154,10 @@ distZip {
archiveClassifier = 'kit'
}

[distTar, distZip, installDist]*.dependsOn copyDocs, javadocJar, project(':dist').jar, project(':dist').javadocJar
tasks.register('distDir', Sync) {
description = 'Creates an expanded kit'
into("${project.buildDir}/kit")
with(distributions.main.contents)
}

[distTar, distZip, distDir, installDist]*.dependsOn copyDocs, javadocJar, project(':dist').jar, project(':dist').javadocJar
1 change: 1 addition & 0 deletions clustered/clustered-dist/src/assemble/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Contents
└─documentation -- Directory for Ehcache documentation
└─lib -- Directory containing third-party client libraries
legal -- Directory containing the licenses associated with this distribution
docker -- Directory containing Dockerfile examples to be able to build your own Terracotta images to run a clustered Ehcache


Resources
Expand Down
60 changes: 60 additions & 0 deletions clustered/clustered-dist/src/assemble/docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Building Ehcache Docker Images

* Directory `config-tool`: Dockerfile and content for the Terracotta config-tool image (used to build and configure a cluster)
* Directory `server`: Dockerfile and content for the Terracotta Server image
* Directory `voter`: Dockerfile and content for the Terracotta Voter image (used in consistency mode)

### Steps:

1. Start a shell at the root of the Ehcache kit

2. Build images:

```bash
docker build -f docker/server/Dockerfile -t ehcache-terracotta-server:@version@ .
docker build -f docker/config-tool/Dockerfile -t ehcache-terracotta-config-tool:@version@ .
docker build -f docker/voter/Dockerfile -t ehcache-terracotta-voter:@version@ .
```

### Verifying the built images

1. Create a network:

```bash
docker network create terracotta-net
```

2. Run a server interactively in consistency mode:

```bash
docker run -it --rm \
-e DEFAULT_ACTIVATE="true" \
-e DEFAULT_FAILOVER="consistency:1" \
-h ehcache-terracotta-server \
--network terracotta-net \
--name ehcache-terracotta-server \
--user 1234:0 \
ehcache-terracotta-server:@version@
```

3. Try the voter image:

```bash
docker run -it --rm \
--network terracotta-net \
--user 1234:0 \
ehcache-terracotta-voter:@version@ -connect-to ehcache-terracotta-server:9410
```

4. Try the config-tool image:

```bash
docker run -it --rm \
--network terracotta-net \
--user 1234:0 \
ehcache-terracotta-config-tool:@version@ diagnostic -connect-to ehcache-terracotta-server
```

### Automated Way

Run `./docker/buildAndTest.groovy`
107 changes: 107 additions & 0 deletions clustered/clustered-dist/src/assemble/docker/buildAndTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/bash
//usr/bin/env groovy -cp client/ehcache/ehcache-@version@.jar:client/ehcache/ehcache-clustered-@version@.jar "$0" $@; exit $?

import org.ehcache.Cache
import org.ehcache.PersistentCacheManager
import org.ehcache.clustered.client.config.builders.ClusteredResourcePoolBuilder
import org.ehcache.clustered.client.config.builders.ClusteringServiceConfigurationBuilder
import org.ehcache.config.builders.CacheConfigurationBuilder
import org.ehcache.config.builders.CacheManagerBuilder
import org.ehcache.config.builders.ResourcePoolsBuilder
import org.ehcache.config.units.MemoryUnit

Closure<?> ehcacheClientTest = { int port ->
println "Connecting Ehcache client..."
CacheManagerBuilder.newCacheManagerBuilder()
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost:${port}/my-cache-manager-name"))
.autoCreateOnReconnect(server -> server.defaultServerResource("offheap-1")))
.build(true)
.withCloseable { PersistentCacheManager cacheManager ->
Cache<Long, String> cache = cacheManager.createCache("clustered-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(
Long.class,
String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.with(ClusteredResourcePoolBuilder.clusteredDedicated("offheap-1", 2, MemoryUnit.MB)))
.build())
println "put()..."
cache.put(42L, "All you need to know!")
println "get()..."
assert cache.get(42L) == "All you need to know!"
}
}

Closure<?> run = { String cmd, Closure<?> result = null ->
println "> ${cmd}"
cmd.execute().with { process ->
if (result) {
int status = process.waitFor()
if (status != 0) throw new IllegalStateException("Command failed:\n${cmd}\nError:\n${process.err.text}")
process.text.trim().with { stdout ->
println stdout
result(stdout)
}
} else {
process.consumeProcessOutput(System.out, System.err)
int status = process.waitFor()
process.waitForProcessOutput()
if (status != 0) throw new IllegalStateException("Command failed: ${status}")
}
}
}

Deque<Closure<?>> cleanups = new ArrayDeque<>()

Runtime.runtime.addShutdownHook {
println """>
> CLEANUP...
>"""
while (cleanups) {
cleanups.pollLast().call()
}
}

println """>
> BUILDING...
>"""

run "docker build -f docker/server/Dockerfile -t ehcache-terracotta-server:@version@ ."
run "docker build -f docker/config-tool/Dockerfile -t ehcache-terracotta-config-tool:@version@ ."
run "docker build -f docker/voter/Dockerfile -t ehcache-terracotta-voter:@version@ ."

println """>
> TESTING...
>"""

run "docker network create net-${UUID.randomUUID()}", { network ->
cleanups << {
run "docker network rm ${network}"
}

run "docker run --detach --rm -p 9410:9410 -e DEFAULT_ACTIVATE=true -e DEFAULT_FAILOVER=consistency:1 -h ehcache-terracotta-server --network ${network} --user 1234:0 ehcache-terracotta-server:@version@", { server ->
cleanups << {
run "docker rm -f ${server}"
}

Thread.startDaemon {
run "docker logs --follow ${server}"
}

sleep(10_000)

run "docker run --detach --rm --network ${network} --user 1234:0 ehcache-terracotta-voter:@version@ -connect-to ehcache-terracotta-server:9410", { voter ->
cleanups << {
run "docker rm -f ${voter}"
}

Thread.startDaemon {
run "docker logs --follow ${voter}"
}

sleep(10_000)

run "docker run --rm --network ${network} --user 1234:0 ehcache-terracotta-config-tool:@version@ diagnostic -connect-to ehcache-terracotta-server"

ehcacheClientTest(9410)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM azul/zulu-openjdk-alpine:17.0.5-17.38.21

RUN apk update && apk upgrade && apk add bash
RUN mkdir /terracotta && chgrp -R 0 /terracotta && chmod -R g+rX /terracotta
RUN mkdir /terracotta/config && chgrp -R 0 /terracotta/config && chmod -R g+rX /terracotta/config
RUN mkdir /terracotta/run && chgrp -R 0 /terracotta/run && chmod -R g+rwX /terracotta/run

WORKDIR /terracotta

# This volume can be mounted with "ro" flag.
# This is where the configurations will be sourced and eventually copied elsewhere within the container.
VOLUME "/terracotta/config"

# This folder can be mounted with "rw" flag.
# This is where the default configurations will output any logs, data, etc
# If the volume is mounted, the container will support being restarted in the same state.
# If a volume is mounted, be sure to set the correct chmod permissions in the host machine.
# Also, you might need to use a special cleanup task to remove the created files in the host machine
VOLUME "/terracotta/run"

COPY tools /terracotta/tools
COPY docker/config-tool/entrypoint.sh /terracotta/tools/entrypoint.sh

ENTRYPOINT ["./tools/entrypoint.sh"]
Loading