diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 002c4f7e6..76b558a2e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -111,6 +111,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: Build shell: bash diff --git a/.github/workflows/coherence-matrix.yaml b/.github/workflows/coherence-matrix.yaml index f88dbc2c8..d91b9d879 100644 --- a/.github/workflows/coherence-matrix.yaml +++ b/.github/workflows/coherence-matrix.yaml @@ -197,6 +197,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 docker pull ${{ matrix.coherenceImage }} - name: Coherence Certification Tests diff --git a/.github/workflows/compatibility-tests.yaml b/.github/workflows/compatibility-tests.yaml index b22f0af88..16bdffd66 100644 --- a/.github/workflows/compatibility-tests.yaml +++ b/.github/workflows/compatibility-tests.yaml @@ -171,6 +171,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 docker pull ${{ matrix.coherence-image }} - name: Build diff --git a/.github/workflows/doc-check.yaml b/.github/workflows/doc-check.yaml index 5d19cb913..9811f069f 100644 --- a/.github/workflows/doc-check.yaml +++ b/.github/workflows/doc-check.yaml @@ -69,10 +69,6 @@ jobs: make kind kubectl version kubectl get nodes - docker pull gcr.io/distroless/java - docker pull gcr.io/distroless/java11-debian11 - docker pull gcr.io/distroless/java17-debian11 - docker pull gcr.io/distroless/java17-debian12 - name: Documentation Link Check shell: bash diff --git a/.github/workflows/istio-tests.yaml b/.github/workflows/istio-tests.yaml index 7e8e38183..64d373f96 100644 --- a/.github/workflows/istio-tests.yaml +++ b/.github/workflows/istio-tests.yaml @@ -112,6 +112,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: Build shell: bash diff --git a/.github/workflows/k3d-tests.yaml b/.github/workflows/k3d-tests.yaml index 47efb8dea..20bce6d94 100644 --- a/.github/workflows/k3d-tests.yaml +++ b/.github/workflows/k3d-tests.yaml @@ -106,6 +106,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: K3d Tests shell: bash diff --git a/.github/workflows/k8s-matrix.yaml b/.github/workflows/k8s-matrix.yaml index 3f3576613..c67500c07 100644 --- a/.github/workflows/k8s-matrix.yaml +++ b/.github/workflows/k8s-matrix.yaml @@ -147,6 +147,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: Certification Tests shell: bash diff --git a/.github/workflows/minikube-matrix.yaml b/.github/workflows/minikube-matrix.yaml index 8643aa2d3..223882ed4 100644 --- a/.github/workflows/minikube-matrix.yaml +++ b/.github/workflows/minikube-matrix.yaml @@ -129,6 +129,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 ./hack/k8s-certification.sh - uses: actions/upload-artifact@v4 diff --git a/.github/workflows/prometheus-tests.yaml b/.github/workflows/prometheus-tests.yaml index 11249b685..c0bf2b9dc 100644 --- a/.github/workflows/prometheus-tests.yaml +++ b/.github/workflows/prometheus-tests.yaml @@ -105,6 +105,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: E2E Prometheus Tests shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9e00301d5..ecce390d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 make get-tanzu - name: Release diff --git a/.github/workflows/tanzu-tests.yaml b/.github/workflows/tanzu-tests.yaml index 7433e4c71..5b633ae99 100644 --- a/.github/workflows/tanzu-tests.yaml +++ b/.github/workflows/tanzu-tests.yaml @@ -112,6 +112,7 @@ jobs: docker pull gcr.io/distroless/java11-debian11 docker pull gcr.io/distroless/java17-debian11 docker pull gcr.io/distroless/java17-debian12 + docker pull gcr.io/distroless/java21-debian12 - name: Build shell: bash diff --git a/Makefile b/Makefile index 8d3e90bdc..ae08d7c9a 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ KUBERNETES_DOC_VERSION=v1.30 # The Coherence version to build against - must be a Java 8 compatible version COHERENCE_VERSION ?= 21.12.5 COHERENCE_VERSION_LTS ?= 14.1.2-0-1 +COHERENCE_CE_LATEST ?= 24.09.2 # The default Coherence image the Operator will run if no image is specified COHERENCE_IMAGE_REGISTRY ?= ghcr.io/oracle COHERENCE_IMAGE_NAME ?= coherence-ce @@ -49,8 +50,9 @@ COHERENCE_IMAGE ?= $(COHERENCE_IMAGE_REGISTRY)/$(COHERENCE_IMAGE_NAME): COHERENCE_GROUP_ID ?= com.oracle.coherence.ce # The Java version that tests will be compiled to. # This should match the version required by the COHERENCE_IMAGE version -BUILD_JAVA_VERSION ?= 17 -COHERENCE_TEST_BASE_IMAGE ?= gcr.io/distroless/java17-debian12 +BUILD_JAVA_VERSION ?= 17 +COHERENCE_TEST_BASE_IMAGE_17 ?= gcr.io/distroless/java17-debian12 +COHERENCE_TEST_BASE_IMAGE_21 ?= gcr.io/distroless/java21-debian12 # This is the Coherence image that will be used in tests. # Changing this variable will allow test builds to be run against different Coherence versions @@ -95,7 +97,7 @@ OPERATOR_SDK_VERSION := v1.9.0 # Options to append to the Maven command # ---------------------------------------------------------------------------------------------------------------------- MAVEN_OPTIONS ?= -Dmaven.wagon.httpconnectionManager.ttlSeconds=25 -Dmaven.wagon.http.retryHandler.count=3 -MAVEN_BUILD_OPTS :=$(USE_MAVEN_SETTINGS) -Drevision=$(MVN_VERSION) -Dcoherence.version=$(COHERENCE_VERSION) -Dcoherence.version=$(COHERENCE_VERSION_LTS) -Dcoherence.groupId=$(COHERENCE_GROUP_ID) -Dcoherence.test.base.image=$(COHERENCE_TEST_BASE_IMAGE) -Dbuild.java.version=$(BUILD_JAVA_VERSION) $(MAVEN_OPTIONS) +MAVEN_BUILD_OPTS :=$(USE_MAVEN_SETTINGS) -Drevision=$(MVN_VERSION) -Dcoherence.version=$(COHERENCE_VERSION) -Dcoherence.version=$(COHERENCE_VERSION_LTS) -Dcoherence.groupId=$(COHERENCE_GROUP_ID) -Dcoherence.test.base.image=$(COHERENCE_TEST_BASE_IMAGE_17) -Dcoherence.test.base.image.21=$(COHERENCE_TEST_BASE_IMAGE_21) -Dbuild.java.version=$(BUILD_JAVA_VERSION) $(MAVEN_OPTIONS) # ---------------------------------------------------------------------------------------------------------------------- # Operator image names @@ -126,13 +128,18 @@ OPERATOR_REPO_IMAGE := $(OPERATOR_REPO_PREFIX):$(VERSION) # ---------------------------------------------------------------------------------------------------------------------- # The test application images used in integration tests # ---------------------------------------------------------------------------------------------------------------------- -TEST_APPLICATION_IMAGE := $(RELEASE_IMAGE_PREFIX)operator-test:1.0.0 -TEST_COMPATIBILITY_IMAGE := $(RELEASE_IMAGE_PREFIX)operator-test-compatibility:1.0.0 -TEST_APPLICATION_IMAGE_CLIENT := $(RELEASE_IMAGE_PREFIX)operator-test-client:1.0.0 -TEST_APPLICATION_IMAGE_HELIDON := $(RELEASE_IMAGE_PREFIX)operator-test-helidon:1.0.0 -TEST_APPLICATION_IMAGE_SPRING := $(RELEASE_IMAGE_PREFIX)operator-test-spring:1.0.0 -TEST_APPLICATION_IMAGE_SPRING_FAT := $(RELEASE_IMAGE_PREFIX)operator-test-spring-fat:1.0.0 -TEST_APPLICATION_IMAGE_SPRING_CNBP := $(RELEASE_IMAGE_PREFIX)operator-test-spring-cnbp:1.0.0 +TEST_APPLICATION_IMAGE := $(RELEASE_IMAGE_PREFIX)operator-test:1.0.0 +TEST_COMPATIBILITY_IMAGE := $(RELEASE_IMAGE_PREFIX)operator-test-compatibility:1.0.0 +TEST_APPLICATION_IMAGE_CLIENT := $(RELEASE_IMAGE_PREFIX)operator-test-client:1.0.0 +TEST_APPLICATION_IMAGE_HELIDON := $(RELEASE_IMAGE_PREFIX)operator-test-helidon:1.0.0 +TEST_APPLICATION_IMAGE_HELIDON_3 := $(RELEASE_IMAGE_PREFIX)operator-test-helidon-3:1.0.0 +TEST_APPLICATION_IMAGE_HELIDON_2 := $(RELEASE_IMAGE_PREFIX)operator-test-helidon-2:1.0.0 +TEST_APPLICATION_IMAGE_SPRING := $(RELEASE_IMAGE_PREFIX)operator-test-spring:1.0.0 +TEST_APPLICATION_IMAGE_SPRING_FAT := $(RELEASE_IMAGE_PREFIX)operator-test-spring-fat:1.0.0 +TEST_APPLICATION_IMAGE_SPRING_CNBP := $(RELEASE_IMAGE_PREFIX)operator-test-spring-cnbp:1.0.0 +TEST_APPLICATION_IMAGE_SPRING_2 := $(RELEASE_IMAGE_PREFIX)operator-test-spring-2:1.0.0 +TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(RELEASE_IMAGE_PREFIX)operator-test-spring-fat-2:1.0.0 +TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(RELEASE_IMAGE_PREFIX)operator-test-spring-cnbp-2:1.0.0 # ---------------------------------------------------------------------------------------------------------------------- # Operator Lifecycle Manager properties @@ -288,20 +295,25 @@ OPERATOR_SDK = $(OPERATOR_SDK_HOME)/operator-sdk # ---------------------------------------------------------------------------------------------------------------------- # The ttl.sh images used in integration tests # ---------------------------------------------------------------------------------------------------------------------- -TTL_REGISTRY := ttl.sh -TTL_TIMEOUT := 1h -TTL_UUID_FILE := $(BUILD_OUTPUT)/ttl-uuid.txt -TTL_UUID := $(shell if [ -f $(TTL_UUID_FILE) ]; then cat $(TTL_UUID_FILE); else uuidgen | tr A-Z a-z > $(TTL_UUID_FILE) && cat $(TTL_UUID_FILE); fi) -TTL_OPERATOR_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME):$(TTL_TIMEOUT) -TTL_PACKAGE_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME)-package:$(TTL_TIMEOUT) -TTL_REPO_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME)-repo:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test:$(TTL_TIMEOUT) -TTL_COMPATIBILITY_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-compatibility:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE_CLIENT := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-client:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE_HELIDON := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-helidon:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE_SPRING := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE_SPRING_FAT := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-fat:$(TTL_TIMEOUT) -TTL_APPLICATION_IMAGE_SPRING_CNBP := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-cnbp:$(TTL_TIMEOUT) +TTL_REGISTRY := ttl.sh +TTL_TIMEOUT := 1h +TTL_UUID_FILE := $(BUILD_OUTPUT)/ttl-uuid.txt +TTL_UUID := $(shell if [ -f $(TTL_UUID_FILE) ]; then cat $(TTL_UUID_FILE); else uuidgen | tr A-Z a-z > $(TTL_UUID_FILE) && cat $(TTL_UUID_FILE); fi) +TTL_OPERATOR_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME):$(TTL_TIMEOUT) +TTL_PACKAGE_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME)-package:$(TTL_TIMEOUT) +TTL_REPO_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/$(OPERATOR_IMAGE_NAME)-repo:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test:$(TTL_TIMEOUT) +TTL_COMPATIBILITY_IMAGE := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-compatibility:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_CLIENT := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-client:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_HELIDON := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-helidon:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_HELIDON_3 := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-helidon-3:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_HELIDON_2 := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-helidon-2:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING_FAT := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-fat:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING_CNBP := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-cnbp:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING_2 := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-2:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING_FAT_2 := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-fat-2:$(TTL_TIMEOUT) +TTL_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TTL_REGISTRY)/coherence/$(TTL_UUID)/operator-test-spring-cnbp-2:$(TTL_TIMEOUT) # ---------------------------------------------------------------------------------------------------------------------- # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) @@ -312,6 +324,8 @@ else GOBIN=$(shell go env GOBIN) endif +GO_VERSION := $(shell go env GOVERSION) + # ---------------------------------------------------------------------------------------------------------------------- # Setting SHELL to bash allows bash commands to be executed by recipes. # This is a requirement for 'setup-envtest.sh' in the test target. @@ -472,12 +486,14 @@ $(BUILD_TARGETS)/build-operator: $(BUILD_BIN)/runner $(BUILD_TARGETS)/java $(BUI --build-arg BASE_IMAGE=$(OPERATOR_BASE_IMAGE) \ --build-arg coherence_image=$(COHERENCE_IMAGE) \ --build-arg operator_image=$(OPERATOR_IMAGE) \ + --build-arg release=$(GITCOMMIT) \ --build-arg target=amd64 \ . -t $(OPERATOR_IMAGE)-amd64 docker build --platform linux/arm64 --no-cache --build-arg version=$(VERSION) \ --build-arg BASE_IMAGE=$(OPERATOR_BASE_IMAGE) \ --build-arg coherence_image=$(COHERENCE_IMAGE) \ --build-arg operator_image=$(OPERATOR_IMAGE) \ + --build-arg release=$(GITCOMMIT) \ --build-arg target=arm64 \ . -t $(OPERATOR_IMAGE)-arm64 docker tag $(OPERATOR_IMAGE)-$(IMAGE_ARCH) $(OPERATOR_IMAGE) @@ -496,21 +512,32 @@ build-operator-with-tools: $(BUILD_BIN)/runner $(BUILD_TARGETS)/java ## Build th . -t $(OPERATOR_IMAGE) .PHONY: build-operator-debug -build-operator-debug: $(BUILD_BIN)/linux/amd64/runner-debug $(BUILD_TARGETS)/java ## Build the Coherence Operator image with the Delve debugger - docker build --no-cache --build-arg version=$(VERSION) \ - --build-arg BASE_IMAGE=$(OPERATOR_IMAGE_DELVE) \ +build-operator-debug: $(BUILD_TARGETS)/delve-image $(BUILD_BIN)/runner-debug $(BUILD_TARGETS)/java ## Build the Coherence Operator image with the Delve debugger + docker build --platform linux/$(IMAGE_ARCH) --no-cache --build-arg version=$(VERSION) \ --build-arg coherence_image=$(COHERENCE_IMAGE) \ --build-arg operator_image=$(OPERATOR_IMAGE) \ - --build-arg target=amd64 \ + --build-arg target=$(IMAGE_ARCH) \ -f debug/Dockerfile \ . -t $(OPERATOR_IMAGE_DEBUG) -build-delve-image: ## Build the Coherence Operator Delve debugger base image - docker build -f debug/Base.Dockerfile -t $(OPERATOR_IMAGE_DELVE) debug +.PHONY: build-delve-image +build-delve-image: $(BUILD_TARGETS)/delve-image ## Build the Coherence Operator Delve debugger base image -$(BUILD_BIN)/linux/amd64/runner-debug: $(BUILD_PROPS) $(GOS) $(BUILD_TARGETS)/generate $(BUILD_TARGETS)/manifests - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -gcflags "-N -l" -ldflags "$(LDFLAGS)" -a -o $(BUILD_BIN)/linux/amd64/runner-debug ./runner - chmod +x $(BUILD_BIN)/linux/amd64/runner-debug +$(BUILD_TARGETS)/delve-image: + GV=$(GO_VERSION) && GVS="$${GV#go}" && \ + docker build --build-arg BASE_IMAGE=golang:$${GVS} -f debug/Base.Dockerfile -t $(OPERATOR_IMAGE_DELVE) debug + touch $(BUILD_TARGETS)/delve-image + +$(BUILD_BIN)/runner-debug: $(BUILD_PROPS) $(GOS) $(BUILD_TARGETS)/generate $(BUILD_TARGETS)/manifests + mkdir -p $(BUILD_BIN_AMD64) || true + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -gcflags "-N -l" -ldflags "$(LDFLAGS)" -a -o $(BUILD_BIN_AMD64)/runner-debug ./runner + mkdir -p $(BUILD_BIN_ARM64)/linux || true + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -gcflags "-N -l" -ldflags "$(LDFLAGS)" -a -o $(BUILD_BIN_ARM64)/runner-debug ./runner +ifeq (x86_64, $(UNAME_M)) + cp -f $(BUILD_BIN_AMD64)/runner-debug $(BUILD_BIN)/runner-debug +else + cp -f $(BUILD_BIN_ARM64)/runner-debug $(BUILD_BIN)/runner-debug +endif # ---------------------------------------------------------------------------------------------------------------------- # Build the Operator images without the test images @@ -523,14 +550,42 @@ build-operator-images: $(BUILD_TARGETS)/build-operator ## Build all operator ima # ---------------------------------------------------------------------------------------------------------------------- .PHONY: build-test-images build-test-images: $(BUILD_TARGETS)/java build-client-image build-basic-test-image ## Build all of the test images - ./mvnw -B -f java/operator-test-helidon package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON) $(MAVEN_BUILD_OPTS) +# Helidon 4 + ./mvnw -B -f java/operator-test-helidon package jib:dockerBuild -DskipTests \ + -Dcoherence.ce.version=$(COHERENCE_CE_LATEST) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON) \ + $(MAVEN_BUILD_OPTS) +# Helidon 3 + ./mvnw -B -f java/operator-test-helidon-3 package jib:dockerBuild -DskipTests \ + -Dcoherence.ce.version=$(COHERENCE_CE_LATEST) \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON_3) \ + $(MAVEN_BUILD_OPTS) +# Helidon 2 + ./mvnw -B -f java/operator-test-helidon-2 package jib:dockerBuild -DskipTests \ + -Djib.to.image=$(TEST_APPLICATION_IMAGE_HELIDON_2) \ + $(MAVEN_BUILD_OPTS) +# Spring Boot 3.x JIB ./mvnw -B -f java/operator-test-spring package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING) $(MAVEN_BUILD_OPTS) +# Spring Boot 3.x CNBP ./mvnw -B -f java/operator-test-spring package spring-boot:build-image -DskipTests -Dcnbp-image-name=$(TEST_APPLICATION_IMAGE_SPRING_CNBP) $(MAVEN_BUILD_OPTS) +# Spring Boot 3.x fat jar docker build -f java/operator-test-spring/target/FatJar.Dockerfile -t $(TEST_APPLICATION_IMAGE_SPRING_FAT) java/operator-test-spring/target +# Spring Boot 3.x exploded fat jar rm -rf java/operator-test-spring/target/spring || true && mkdir java/operator-test-spring/target/spring cp java/operator-test-spring/target/operator-test-spring-$(MVN_VERSION).jar java/operator-test-spring/target/spring/operator-test-spring-$(MVN_VERSION).jar cd java/operator-test-spring/target/spring && jar -xvf operator-test-spring-$(MVN_VERSION).jar && rm -f operator-test-spring-$(MVN_VERSION).jar docker build -f java/operator-test-spring/target/Dir.Dockerfile -t $(TEST_APPLICATION_IMAGE_SPRING) java/operator-test-spring/target +# Spring Boot 2.x JIB + ./mvnw -B -f java/operator-test-spring-2 package jib:dockerBuild -DskipTests -Djib.to.image=$(TEST_APPLICATION_IMAGE_SPRING_2) $(MAVEN_BUILD_OPTS) +# Spring Boot 2.x CNBP + ./mvnw -B -f java/operator-test-spring-2 package spring-boot:build-image -DskipTests -Dcnbp-image-name=$(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) $(MAVEN_BUILD_OPTS) +# Spring Boot 2.x fat jar + docker build -f java/operator-test-spring-2/target/FatJar.Dockerfile -t $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) java/operator-test-spring-2/target +# Spring Boot 2.x exploded fat jar + rm -rf java/operator-test-spring-2/target/spring || true && mkdir java/operator-test-spring-2/target/spring + cp java/operator-test-spring-2/target/operator-test-spring-2-$(MVN_VERSION).jar java/operator-test-spring-2/target/spring/operator-test-spring-2-$(MVN_VERSION).jar + cd java/operator-test-spring-2/target/spring && jar -xvf operator-test-spring-2-$(MVN_VERSION).jar && rm -f operator-test-spring-2-$(MVN_VERSION).jar + docker build -f java/operator-test-spring-2/target/Dir.Dockerfile -t $(TEST_APPLICATION_IMAGE_SPRING_2) java/operator-test-spring-2/target # ---------------------------------------------------------------------------------------------------------------------- # Build the basic Operator Test image @@ -564,11 +619,15 @@ ensure-sdk: build-runner: $(BUILD_BIN)/runner ## Build the Coherence Operator runner binary $(BUILD_BIN)/runner: $(BUILD_PROPS) $(GOS) $(BUILD_TARGETS)/generate $(BUILD_TARGETS)/manifests - CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -trimpath -ldflags "$(LDFLAGS)" -o $(BUILD_BIN)/runner ./runner mkdir -p $(BUILD_BIN_AMD64) || true - cp -f $(BUILD_BIN)/runner $(BUILD_BIN_AMD64)/runner + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -trimpath -ldflags "$(LDFLAGS)" -o $(BUILD_BIN_AMD64)/runner ./runner mkdir -p $(BUILD_BIN_ARM64)/linux || true CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GO111MODULE=on go build -trimpath -ldflags "$(LDFLAGS)" -a -o $(BUILD_BIN_ARM64)/runner ./runner +ifeq (x86_64, $(UNAME_M)) + cp -f $(BUILD_BIN_AMD64)/runner $(BUILD_BIN)/runner +else + cp -f $(BUILD_BIN_ARM64)/runner $(BUILD_BIN)/runner +endif # ---------------------------------------------------------------------------------------------------------------------- # Build the Java artifacts @@ -956,9 +1015,14 @@ e2e-local-test: export BUILD_OUTPUT := $(BUILD_OUTPUT) e2e-local-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) e2e-local-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT) e2e-local-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +e2e-local-test: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +e2e-local-test: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +e2e-local-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) e2e-local-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE) e2e-local-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS) e2e-local-test: export COH_SKIP_SITE := true @@ -1010,9 +1074,14 @@ run-e2e-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE) run-e2e-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) run-e2e-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT) run-e2e-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +run-e2e-test: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +run-e2e-test: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +run-e2e-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) run-e2e-test: gotestsum ## Run the Operator 'remote' end-to-end functional tests using an ALREADY DEPLOYED Operator $(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-test.xml \ -- $(GO_TEST_FLAGS_E2E) ./test/e2e/remote/... @@ -1032,9 +1101,14 @@ e2e-k3d-test: export BUILD_OUTPUT := $(BUILD_OUTPUT) e2e-k3d-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) e2e-k3d-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT) e2e-k3d-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +e2e-k3d-test: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +e2e-k3d-test: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +e2e-k3d-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) e2e-k3d-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE) e2e-k3d-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS) e2e-k3d-test: export COH_SKIP_SITE := true @@ -1116,9 +1190,14 @@ run-prometheus-test: export CGO_ENABLED = 0 run-prometheus-test: export OPERATOR_NAMESPACE := $(OPERATOR_NAMESPACE) run-prometheus-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) run-prometheus-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +run-prometheus-test: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +run-prometheus-test: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +run-prometheus-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) run-prometheus-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE) run-prometheus-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS) run-prometheus-test: export TEST_IMAGE_PULL_POLICY := $(IMAGE_PULL_POLICY) @@ -1149,9 +1228,14 @@ just-compatibility-test: export BUILD_OUTPUT := $(BUILD_OUTPUT) just-compatibility-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) just-compatibility-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT) just-compatibility-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +just-compatibility-test: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +just-compatibility-test: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) just-compatibility-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE) just-compatibility-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS) just-compatibility-test: export TEST_SSL_SECRET := $(TEST_SSL_SECRET) @@ -1204,9 +1288,14 @@ run-certification: export BUILD_OUTPUT := $(BUILD_OUTPUT) run-certification: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE) run-certification: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT) run-certification: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON) +run-certification: export TEST_APPLICATION_IMAGE_HELIDON_3 := $(TEST_APPLICATION_IMAGE_HELIDON_3) +run-certification: export TEST_APPLICATION_IMAGE_HELIDON_2 := $(TEST_APPLICATION_IMAGE_HELIDON_2) run-certification: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING) run-certification: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT) run-certification: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP) +run-certification: export TEST_APPLICATION_IMAGE_SPRING_2 := $(TEST_APPLICATION_IMAGE_SPRING_2) +run-certification: export TEST_APPLICATION_IMAGE_SPRING_FAT_2 := $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) +run-certification: export TEST_APPLICATION_IMAGE_SPRING_CNBP_2 := $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) run-certification: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE) run-certification: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS) run-certification: export TEST_SSL_SECRET := $(TEST_SSL_SECRET) @@ -1719,9 +1808,14 @@ kind-load: kind-load-operator kind-load-coherence ## Load all images into the K kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE) || true kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_CLIENT) || true kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_HELIDON) || true + kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_HELIDON_3) || true + kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_HELIDON_2) || true kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING) || true kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING_FAT) || true kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING_CNBP) || true + kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING_2) || true + kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) || true + kind load docker-image --name $(KIND_CLUSTER) $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) || true .PHONY: kind-load-coherence kind-load-coherence: ## Load the Coherence image into the KinD cluster @@ -2125,9 +2219,14 @@ push-test-images: docker push $(TEST_APPLICATION_IMAGE) docker push $(TEST_APPLICATION_IMAGE_CLIENT) docker push $(TEST_APPLICATION_IMAGE_HELIDON) + docker push $(TEST_APPLICATION_IMAGE_HELIDON_3) + docker push $(TEST_APPLICATION_IMAGE_HELIDON_2) docker push $(TEST_APPLICATION_IMAGE_SPRING) docker push $(TEST_APPLICATION_IMAGE_SPRING_FAT) docker push $(TEST_APPLICATION_IMAGE_SPRING_CNBP) + docker push $(TEST_APPLICATION_IMAGE_SPRING_2) + docker push $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) + docker push $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) # ---------------------------------------------------------------------------------------------------------------------- # Push the Operator Test images to ttl.sh @@ -2140,12 +2239,22 @@ push-ttl-test-images: docker push $(TTL_APPLICATION_IMAGE_CLIENT) docker tag $(TEST_APPLICATION_IMAGE_HELIDON) $(TTL_APPLICATION_IMAGE_HELIDON) docker push $(TTL_APPLICATION_IMAGE_HELIDON) + docker tag $(TEST_APPLICATION_IMAGE_HELIDON_3) $(TTL_APPLICATION_IMAGE_HELIDON_3) + docker push $(TTL_APPLICATION_IMAGE_HELIDON_3) + docker tag $(TEST_APPLICATION_IMAGE_HELIDON_2) $(TTL_APPLICATION_IMAGE_HELIDON_2) + docker push $(TTL_APPLICATION_IMAGE_HELIDON_2) docker tag $(TEST_APPLICATION_IMAGE_SPRING) $(TTL_APPLICATION_IMAGE_SPRING) docker push $(TTL_APPLICATION_IMAGE_SPRING) docker tag $(TEST_APPLICATION_IMAGE_SPRING_FAT) $(TTL_APPLICATION_IMAGE_SPRING_FAT) docker push $(TTL_APPLICATION_IMAGE_SPRING_FAT) docker tag $(TEST_APPLICATION_IMAGE_SPRING_CNBP) $(TTL_APPLICATION_IMAGE_SPRING_CNBP) docker push $(TTL_APPLICATION_IMAGE_SPRING_CNBP) + docker tag $(TEST_APPLICATION_IMAGE_SPRING_2) $(TTL_APPLICATION_IMAGE_SPRING_2) + docker push $(TTL_APPLICATION_IMAGE_SPRING_2) + docker tag $(TEST_APPLICATION_IMAGE_SPRING_FAT_2) $(TTL_APPLICATION_IMAGE_SPRING_FAT_2) + docker push $(TTL_APPLICATION_IMAGE_SPRING_FAT_2) + docker tag $(TEST_APPLICATION_IMAGE_SPRING_CNBP_2) $(TTL_APPLICATION_IMAGE_SPRING_CNBP_2) + docker push $(TTL_APPLICATION_IMAGE_SPRING_CNBP_2) # ---------------------------------------------------------------------------------------------------------------------- # Build the Operator Test images diff --git a/debug/Base.Dockerfile b/debug/Base.Dockerfile index 491dc99ff..41355893e 100644 --- a/debug/Base.Dockerfile +++ b/debug/Base.Dockerfile @@ -3,11 +3,12 @@ # Licensed under the Universal Permissive License v 1.0 as shown at # http://oss.oracle.com/licenses/upl. # -FROM golang:1.16 +ARG BASE_IMAGE +FROM $BASE_IMAGE ENV GOPATH /go ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH -RUN go get github.com/go-delve/delve/cmd/dlv +RUN go install github.com/go-delve/delve/cmd/dlv@latest ENTRYPOINT ["dlv"] diff --git a/debug/Dockerfile b/debug/Dockerfile index 54b8e3f74..38b214fb3 100644 --- a/debug/Dockerfile +++ b/debug/Dockerfile @@ -3,8 +3,7 @@ # Licensed under the Universal Permissive License v 1.0 as shown at # http://oss.oracle.com/licenses/upl. # -ARG BASE_IMAGE=ghcr.io/oracle/coherence-operator:delve -FROM $BASE_IMAGE +FROM ghcr.io/oracle/coherence-operator:delve ARG target ARG version @@ -19,8 +18,8 @@ ENV COHERENCE_IMAGE=$coherence_image \ WORKDIR / -COPY bin/linux/$target/runner /files/runner +COPY bin/linux/$target/runner-debug /files/runner COPY java/coherence-operator/target/docker/lib/*.jar /files/lib/ COPY java/coherence-operator/target/docker/logging/logging.properties /files/logging/logging.properties -ENTRYPOINT ["dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/manager", "--"] +ENTRYPOINT ["dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/files/runner", "--"] diff --git a/docs/applications/070_spring.adoc b/docs/applications/070_spring.adoc index 6c5366bcf..1323e736d 100644 --- a/docs/applications/070_spring.adoc +++ b/docs/applications/070_spring.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2020, Oracle and/or its affiliates. + Copyright (c) 2020, 2025, Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. @@ -67,8 +67,11 @@ like the diagram below; where you can see the `/spring` directory contains the S └─⊕ var ---- -This type of image can be run by the Coherence Operator by specifying an application type of `spring` in the -`spec.application.type` field and by setting the working directory to the exploded directory, for example: +*Spring Boot 2.x or 3.x* +This type of image can be run by the Coherence Operator by specifying an application type of `spring` +for Spring Boot 2.x applications or `spring3` for SpringBoot 3.x applications. +The application type is set in the `spec.application.type` field and by setting the working directory +to the exploded directory, for example: [source,yaml] ---- @@ -83,15 +86,39 @@ spec: workingDir: /spring # <2> ---- -<1> The `type` field set to `spring` tells the Operator that this is a Spring Boot application. +<1> The `type` field set to `spring` tells the Operator that this is a Spring Boot 2.x application. +<2> The working directory has been set to the directory containing the exploded Spring Boot application. + +[source,yaml] +---- +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: test +spec: + image: my-spring-app:1.0.0 + application: + type: spring3 # <1> + workingDir: /spring # <2> +---- + +<1> The `type` field set to `spring3` tells the Operator that this is a Spring Boot 3.x application. <2> The working directory has been set to the directory containing the exploded Spring Boot application. When the Operator starts the application it will then run a command equivalent to: + +*Spring Boot 2.x* [source,bash] ---- cd /spring && java org.springframework.boot.loader.PropertiesLauncher ---- +*Spring Boot 3.x* +[source,bash] +---- +cd /spring && java org.springframework.boot.loader.launch.PropertiesLauncher +---- + === Using a Spring Boot Fat Jar @@ -127,16 +154,23 @@ spec: <2> The location of the Spring Boot jar has been set. When the Operator starts the application it will then run a command equivalent to: + +*Spring Boot 2.x* [source,bash] ---- java -cp /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.PropertiesLauncher ---- +*Spring Boot 3.x* +[source,bash] +---- +java -cp /app/libs/catalogue-1.0.0.jar org.springframework.boot.loader.launch.PropertiesLauncher +---- + NOTE: The Operator does not run the fat jar using the `java -jar` command because it needs to add various other JVM arguments and append to the classpath, so it has to run the `org.springframework.boot.loader.PropertiesLauncher` class as opposed to the `org.springframework.boot.loader.JarLauncher` that `java -jar` would run. - === Using Could Native Buildpacks If the Spring Boot Maven or Gradle plugin has been used to produce an image using @@ -188,16 +222,24 @@ spec: type: spring # <1> ---- -<1> The application type has been set to `spring` so that the operator knows that this is a Spring Boot application, -and the fact that the image is a Buildpacks image will be auto-discovered. +<1> The application type has been set to `spring` (for Spring Boot 2.x) or `spring3` (for Spring Boot 3.x) so that the +operator knows that this is a Spring Boot application, and the fact that the image is a Buildpacks image will be auto-discovered. When the Operator starts the application it will then run the buildpacks launcher with a command equivalent to this: + +*Spring Boot 2.x* [source,bash] ---- /cnb/lifecycle/launcher java @jvm-args-file org.springframework.boot.loader.PropertiesLauncher ---- +*Spring Boot 3.x* +[source,bash] +---- +/cnb/lifecycle/launcher java @jvm-args-file org.springframework.boot.loader.launch.PropertiesLauncher +---- + ==== Buildpacks Detection If for some reason buildpacks auto-detection does not work properly the `Coherence` diff --git a/hack/go-version.sh b/hack/go-version.sh new file mode 100644 index 000000000..c71fc0288 --- /dev/null +++ b/hack/go-version.sh @@ -0,0 +1,7 @@ +# +# Copyright (c) 2020, 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +go version | read _ _ v _; echo "${v#go}" \ No newline at end of file diff --git a/java/operator-compatibility/pom.xml b/java/operator-compatibility/pom.xml index 11e034c5b..dceb2a092 100644 --- a/java/operator-compatibility/pom.xml +++ b/java/operator-compatibility/pom.xml @@ -1,7 +1,7 @@ + + Copyright (c) 2019, 2025, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +--> com.oracle.coherence.k8s.testing.Main + + + + ${coherence.groupId} + coherence-bom + ${coherence.version} + pom + import + + + + ${coherence.groupId} @@ -34,7 +48,6 @@ ${coherence.groupId} coherence-java-client - ${coherence.version} diff --git a/java/operator-test-helidon-2/pom.xml b/java/operator-test-helidon-2/pom.xml new file mode 100644 index 000000000..34cd98a61 --- /dev/null +++ b/java/operator-test-helidon-2/pom.xml @@ -0,0 +1,98 @@ + + + + + 4.0.0 + + + com.oracle.coherence.kubernetes + operator-parent + ${revision} + ../pom.xml + + + operator-test-helidon-2 + + Oracle Coherence Kubernetes Operator Test (Helidon 2.x) + operator-test-helidon-2 + + + 2.6.5 + 2.1.3 + + + + + + ${coherence.groupId} + coherence-bom + ${coherence.version} + pom + import + + + + io.helidon + helidon-dependencies + ${version.lib.helidon} + pom + import + + + + + + + ${coherence.groupId} + coherence + ${coherence.version} + + + ${coherence.groupId} + coherence-cdi-server + ${coherence.version} + + + + io.helidon.microprofile.bundles + helidon-microprofile + + + org.jboss + jandex + runtime + true + + + jakarta.activation + jakarta.activation-api + ${version.lib.activation-api} + runtime + + + + + + + com.google.cloud.tools + jib-maven-plugin + ${version.plugin.jib} + + + io.helidon.microprofile.cdi.Main + + + packaged + + + + + diff --git a/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java b/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java new file mode 100644 index 000000000..66cf79fb3 --- /dev/null +++ b/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +package com.oracle.coherence.k8s.testing; + +import java.util.Collections; + +import javax.enterprise.context.ApplicationScoped; +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonBuilderFactory; +import javax.json.JsonObject; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import com.tangosol.net.CacheFactory; +import com.tangosol.net.Cluster; +import com.tangosol.net.DistributedCacheService; +import com.tangosol.net.NamedCache; +import com.tangosol.net.partition.SimplePartitionKey; + +/** + * A simple JAX-RS service that is deployed into a Coherence cluster + * and can be used to perform various tests. + * + * @author jk 2021.03.12 + */ +@Path("/") +@ApplicationScoped +public class RestServer { + + private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); + + /** + * @return always returns {@code "ok"} + */ + @GET + @Path("ready") + @Produces(MediaType.TEXT_PLAIN) + public String ready() { + return "ok"; + } + + /** + * Returns the JVM environment variables. + * + * @return the JVM environment variables + */ + @GET + @Path("env") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject env() { + JsonArrayBuilder arrayBuilder = JSON.createArrayBuilder(); + System.getenv() + .entrySet() + .stream() + .map(e -> String.format("{\"%s\":\"%s\"}", e.getKey(), e.getValue())) + .forEach(arrayBuilder::add); + + return JSON.createObjectBuilder() + .add("env", arrayBuilder) + .build(); + } + + /** + * Returns the JVM system properties. + * + * @return the JVM system properties + */ + @GET + @Path("props") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject props() { + JsonArrayBuilder arrayBuilder = JSON.createArrayBuilder(); + System.getProperties() + .entrySet() + .stream() + .map(e -> String.format("{\"%s\":\"%s\"}", e.getKey(), e.getValue())) + .forEach(arrayBuilder::add); + + return JSON.createObjectBuilder() + .add("env", arrayBuilder) + .build(); + } + + /** + * Suspend the canary cache service. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("suspend") + @Produces(MediaType.TEXT_PLAIN) + public String suspend() { + Cluster cluster = CacheFactory.ensureCluster(); + cluster.suspendService("PartitionedCache"); + return "ok"; + } + + /** + * Resume the canary cache service. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("resume") + @Produces(MediaType.TEXT_PLAIN) + public String resume() { + Cluster cluster = CacheFactory.ensureCluster(); + cluster.resumeService("PartitionedCache"); + return "ok"; + } + + /** + * Initialise the canary cache. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("canaryStart") + @Produces(MediaType.TEXT_PLAIN) + public String canaryStart() { + NamedCache cache = CacheFactory.getCache("canary"); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + + for (int i = 0; i < nPart; i++) { + SimplePartitionKey key = SimplePartitionKey.getPartitionKey(i); + cache.put(key, "data"); + } + return "ok"; + } + + /** + * Check the canary cache. + * + * @return the number of entries in the canary cache + */ + @GET + @Path("canaryCheck") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject canaryCheck() { + NamedCache cache = CacheFactory.getCache("canary"); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + int nSize = cache.size(); + + if (nSize == nPart) { + return JSON.createObjectBuilder() + .add("entries", nSize) + .build(); + } + else { + throw new IllegalStateException("Data loss " + nSize + " of " + nPart + " partitions"); + } + } + + /** + * Clear the canary cache. + * + * @return always returns {@code "ok"} + */ + @POST + @Path("canaryClear") + @Produces(MediaType.TEXT_PLAIN) + public String canaryClear() { + NamedCache cache = CacheFactory.getCache("canary"); + cache.clear(); + return "ok"; + } +} diff --git a/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/package-info.java b/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/package-info.java new file mode 100644 index 000000000..e150d78d5 --- /dev/null +++ b/java/operator-test-helidon-2/src/main/java/com/oracle/coherence/k8s/testing/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +/** + * Classes to support testing Coherence in Kubernetes. + */ +package com.oracle.coherence.k8s.testing; diff --git a/java/operator-test-helidon-2/src/main/resources/META-INF/beans.xml b/java/operator-test-helidon-2/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2b63907c8 --- /dev/null +++ b/java/operator-test-helidon-2/src/main/resources/META-INF/beans.xml @@ -0,0 +1,13 @@ + + + + diff --git a/java/operator-test-helidon-2/src/main/resources/META-INF/microprofile-config.properties b/java/operator-test-helidon-2/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 000000000..9b8ea5d7d --- /dev/null +++ b/java/operator-test-helidon-2/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,15 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# Application properties. This is the default greeting +app.greeting=Hello + +# Microprofile server properties +server.port=8080 +server.host=0.0.0.0 + +# Turn on support for REST.request SimpleTimers for all JAX-RS endpoints +metrics.rest-request.enabled=true diff --git a/java/operator-test-helidon-2/src/main/resources/logging.properties b/java/operator-test-helidon-2/src/main/resources/logging.properties new file mode 100644 index 000000000..7e7b8ebd4 --- /dev/null +++ b/java/operator-test-helidon-2/src/main/resources/logging.properties @@ -0,0 +1,24 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# Example Logging Configuration File +# For more information see $JAVA_HOME/jre/lib/logging.properties + +# Send messages to the console +handlers=io.helidon.common.HelidonConsoleHandler + +# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread +java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n + +# Global logging level. Can be overridden by specific loggers +.level=INFO + +# Component specific log levels +#io.helidon.webserver.level=INFO +#io.helidon.config.level=INFO +#io.helidon.security.level=INFO +#io.helidon.common.level=INFO +#io.netty.level=INFO diff --git a/java/operator-test-helidon-2/src/main/resources/test-cache-config.xml b/java/operator-test-helidon-2/src/main/resources/test-cache-config.xml new file mode 100644 index 000000000..c7e0f28fb --- /dev/null +++ b/java/operator-test-helidon-2/src/main/resources/test-cache-config.xml @@ -0,0 +1,60 @@ + + + + + + pof + + + + + * + distributed-scheme + + + canary + canary-scheme + + + + + + distributed-scheme + PartitionedCache + true + + + + true + + + + canary-scheme + CanaryService + true + + + + true + + + + Proxy + + + +
+ + + + + true + + + diff --git a/java/operator-test-helidon-3/pom.xml b/java/operator-test-helidon-3/pom.xml new file mode 100644 index 000000000..5a95864fc --- /dev/null +++ b/java/operator-test-helidon-3/pom.xml @@ -0,0 +1,96 @@ + + + + + 4.0.0 + + + com.oracle.coherence.kubernetes + operator-parent + ${revision} + ../pom.xml + + + operator-test-helidon-3 + + Oracle Coherence Kubernetes Operator Test (Helidon 3.x) + operator-test-helidon-3 + + + 3.2.11 + 1.2.2 + + + + + + ${coherence.groupId} + coherence-bom + ${coherence.ce.version} + pom + import + + + + io.helidon + helidon-dependencies + ${version.lib.helidon} + pom + import + + + + + + + ${coherence.groupId} + coherence + + + ${coherence.groupId} + coherence-cdi-server + + + + io.helidon.microprofile.bundles + helidon-microprofile + + + org.jboss + jandex + runtime + true + + + jakarta.activation + jakarta.activation-api + ${version.lib.activation-api} + runtime + + + + + + + com.google.cloud.tools + jib-maven-plugin + ${version.plugin.jib} + + + io.helidon.microprofile.cdi.Main + + + packaged + + + + + diff --git a/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java b/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java new file mode 100644 index 000000000..2b73867a7 --- /dev/null +++ b/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/RestServer.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +package com.oracle.coherence.k8s.testing; + +import java.util.Collections; + +import com.tangosol.net.CacheFactory; +import com.tangosol.net.Cluster; +import com.tangosol.net.DistributedCacheService; +import com.tangosol.net.NamedCache; +import com.tangosol.net.partition.SimplePartitionKey; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.json.Json; +import jakarta.json.JsonArrayBuilder; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonObject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +/** + * A simple JAX-RS service that is deployed into a Coherence cluster + * and can be used to perform various tests. + * + * @author jk 2021.03.12 + */ +@Path("/") +@ApplicationScoped +public class RestServer { + + private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap()); + + /** + * @return always returns {@code "ok"} + */ + @GET + @Path("ready") + @Produces(MediaType.TEXT_PLAIN) + public String ready() { + return "ok"; + } + + /** + * Returns the JVM environment variables. + * + * @return the JVM environment variables + */ + @GET + @Path("env") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject env() { + JsonArrayBuilder arrayBuilder = JSON.createArrayBuilder(); + System.getenv() + .entrySet() + .stream() + .map(e -> String.format("{\"%s\":\"%s\"}", e.getKey(), e.getValue())) + .forEach(arrayBuilder::add); + + return JSON.createObjectBuilder() + .add("env", arrayBuilder) + .build(); + } + + /** + * Returns the JVM system properties. + * + * @return the JVM system properties + */ + @GET + @Path("props") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject props() { + JsonArrayBuilder arrayBuilder = JSON.createArrayBuilder(); + System.getProperties() + .entrySet() + .stream() + .map(e -> String.format("{\"%s\":\"%s\"}", e.getKey(), e.getValue())) + .forEach(arrayBuilder::add); + + return JSON.createObjectBuilder() + .add("env", arrayBuilder) + .build(); + } + + /** + * Suspend the canary cache service. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("suspend") + @Produces(MediaType.TEXT_PLAIN) + public String suspend() { + Cluster cluster = CacheFactory.ensureCluster(); + cluster.suspendService("PartitionedCache"); + return "ok"; + } + + /** + * Resume the canary cache service. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("resume") + @Produces(MediaType.TEXT_PLAIN) + public String resume() { + Cluster cluster = CacheFactory.ensureCluster(); + cluster.resumeService("PartitionedCache"); + return "ok"; + } + + /** + * Initialise the canary cache. + * + * @return always returns {@code "ok"} + */ + @PUT + @Path("canaryStart") + @Produces(MediaType.TEXT_PLAIN) + public String canaryStart() { + NamedCache cache = CacheFactory.getCache("canary"); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + + for (int i = 0; i < nPart; i++) { + SimplePartitionKey key = SimplePartitionKey.getPartitionKey(i); + cache.put(key, "data"); + } + return "ok"; + } + + /** + * Check the canary cache. + * + * @return the number of entries in the canary cache + */ + @GET + @Path("canaryCheck") + @Produces(MediaType.APPLICATION_JSON) + public JsonObject canaryCheck() { + NamedCache cache = CacheFactory.getCache("canary"); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + int nSize = cache.size(); + + if (nSize == nPart) { + return JSON.createObjectBuilder() + .add("entries", nSize) + .build(); + } + else { + throw new IllegalStateException("Data loss " + nSize + " of " + nPart + " partitions"); + } + } + + /** + * Clear the canary cache. + * + * @return always returns {@code "ok"} + */ + @POST + @Path("canaryClear") + @Produces(MediaType.TEXT_PLAIN) + public String canaryClear() { + NamedCache cache = CacheFactory.getCache("canary"); + cache.clear(); + return "ok"; + } +} diff --git a/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/package-info.java b/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/package-info.java new file mode 100644 index 000000000..e150d78d5 --- /dev/null +++ b/java/operator-test-helidon-3/src/main/java/com/oracle/coherence/k8s/testing/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +/** + * Classes to support testing Coherence in Kubernetes. + */ +package com.oracle.coherence.k8s.testing; diff --git a/java/operator-test-helidon-3/src/main/resources/META-INF/beans.xml b/java/operator-test-helidon-3/src/main/resources/META-INF/beans.xml new file mode 100644 index 000000000..2b63907c8 --- /dev/null +++ b/java/operator-test-helidon-3/src/main/resources/META-INF/beans.xml @@ -0,0 +1,13 @@ + + + + diff --git a/java/operator-test-helidon-3/src/main/resources/META-INF/microprofile-config.properties b/java/operator-test-helidon-3/src/main/resources/META-INF/microprofile-config.properties new file mode 100644 index 000000000..9b8ea5d7d --- /dev/null +++ b/java/operator-test-helidon-3/src/main/resources/META-INF/microprofile-config.properties @@ -0,0 +1,15 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# Application properties. This is the default greeting +app.greeting=Hello + +# Microprofile server properties +server.port=8080 +server.host=0.0.0.0 + +# Turn on support for REST.request SimpleTimers for all JAX-RS endpoints +metrics.rest-request.enabled=true diff --git a/java/operator-test-helidon-3/src/main/resources/logging.properties b/java/operator-test-helidon-3/src/main/resources/logging.properties new file mode 100644 index 000000000..7e7b8ebd4 --- /dev/null +++ b/java/operator-test-helidon-3/src/main/resources/logging.properties @@ -0,0 +1,24 @@ +# +# Copyright (c) 2025, Oracle and/or its affiliates. +# Licensed under the Universal Permissive License v 1.0 as shown at +# http://oss.oracle.com/licenses/upl. +# + +# Example Logging Configuration File +# For more information see $JAVA_HOME/jre/lib/logging.properties + +# Send messages to the console +handlers=io.helidon.common.HelidonConsoleHandler + +# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread +java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n + +# Global logging level. Can be overridden by specific loggers +.level=INFO + +# Component specific log levels +#io.helidon.webserver.level=INFO +#io.helidon.config.level=INFO +#io.helidon.security.level=INFO +#io.helidon.common.level=INFO +#io.netty.level=INFO diff --git a/java/operator-test-helidon-3/src/main/resources/test-cache-config.xml b/java/operator-test-helidon-3/src/main/resources/test-cache-config.xml new file mode 100644 index 000000000..c7e0f28fb --- /dev/null +++ b/java/operator-test-helidon-3/src/main/resources/test-cache-config.xml @@ -0,0 +1,60 @@ + + + + + + pof + + + + + * + distributed-scheme + + + canary + canary-scheme + + + + + + distributed-scheme + PartitionedCache + true + + + + true + + + + canary-scheme + CanaryService + true + + + + true + + + + Proxy + + + +
+ + + + + true + + + diff --git a/java/operator-test-helidon/pom.xml b/java/operator-test-helidon/pom.xml index 6887cfb1c..50a2d775f 100644 --- a/java/operator-test-helidon/pom.xml +++ b/java/operator-test-helidon/pom.xml @@ -1,7 +1,7 @@ + + + 4.0.0 + + + com.oracle.coherence.kubernetes + operator-parent + ${revision} + ../pom.xml + + + operator-test-spring-2 + + Oracle Coherence Kubernetes Operator Test (Spring v2.x) + operator-test-spring-2 + + + ${project.artifactId}-cnbp:${project.version} + + 2.7.18 + + + + + + ${coherence.groupId} + coherence-bom + ${coherence.version} + pom + import + + + + + + + ${coherence.groupId} + coherence + + + org.springframework.boot + spring-boot-starter-web + ${version.lib.spring} + + + org.springframework.boot + spring-boot-starter-logging + + + + + + + + + src/main/docker + ${project.build.directory} + true + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + + repackage + + + + spring-dir + + repackage + + + DIR + ${project.build.directory}/spring + + + + + + ${cnbp-image-name} + + 17.* + + + + + + + com.google.cloud.tools + jib-maven-plugin + ${version.plugin.jib} + + true + + + + + diff --git a/java/operator-test-spring-2/src/main/docker/Dir.Dockerfile b/java/operator-test-spring-2/src/main/docker/Dir.Dockerfile new file mode 100644 index 000000000..63865baed --- /dev/null +++ b/java/operator-test-spring-2/src/main/docker/Dir.Dockerfile @@ -0,0 +1,7 @@ +FROM gcr.io/distroless/java17-debian12 + +ADD spring /spring + +WORKDIR /spring + +ENTRYPOINT ["java", "org.springframework.boot.loader.PropertiesLauncher"] \ No newline at end of file diff --git a/java/operator-test-spring-2/src/main/docker/FatJar.Dockerfile b/java/operator-test-spring-2/src/main/docker/FatJar.Dockerfile new file mode 100644 index 000000000..57cebbca7 --- /dev/null +++ b/java/operator-test-spring-2/src/main/docker/FatJar.Dockerfile @@ -0,0 +1,5 @@ +FROM gcr.io/distroless/java17-debian12 + +ADD ${project.artifactId}-${project.version}.jar /app/libs/${project.artifactId}-${project.version}.jar + +ENTRYPOINT ["java", "-jar", "/app/libs/${project.artifactId}-${project.version}.jar"] \ No newline at end of file diff --git a/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/ApplicationController.java b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/ApplicationController.java new file mode 100644 index 000000000..bf76ab15b --- /dev/null +++ b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/ApplicationController.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +package com.oracle.coherence.k8s.testing.spring; + +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import com.tangosol.net.DistributedCacheService; +import com.tangosol.net.NamedCache; +import com.tangosol.net.Session; +import com.tangosol.net.partition.SimplePartitionKey; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +/** + * A test Spring controller. + * + * @author Jonathan Knight 2020.09.15 + */ +@RestController +public class ApplicationController { + + /** + * The name of the canary cache. + */ + public static final String CACHE_NAME_CANARY = "canary"; + + @Autowired + private Session session; + + @Autowired + @Qualifier("commandLineArguments") + private String[] commandLineArguments; + + /** + * Obtain the program arguments. + * + * @return the program arguments + */ + @RequestMapping("/args") + public String[] args() { + return commandLineArguments; + } + + /** + * Perform the canary test. + * + * @return the test results. + */ + @RequestMapping("/canaryCheck") + public String canaryCheck() { + NamedCache cache = session.getCache(CACHE_NAME_CANARY); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + int nSize = cache.size(); + + if (nSize != nPart) { + throw new CanaryFailure(nSize, nPart); + } + return "OK " + nSize + " entries"; + } + + /** + * Clear the canary cache. + * + * @return the request response + */ + @RequestMapping("/canaryClear") + public String canaryClear() { + NamedCache cache = session.getCache(CACHE_NAME_CANARY); + cache.truncate(); + return "OK"; + } + + /** + * Initialise the canary cache. + * + * @return the request response + */ + @RequestMapping("/canaryStart") + public String canaryStart() { + NamedCache cache = session.getCache(CACHE_NAME_CANARY); + DistributedCacheService service = (DistributedCacheService) cache.getCacheService(); + int nPart = service.getPartitionCount(); + + for (int i = 0; i < nPart; i++) { + SimplePartitionKey key = SimplePartitionKey.getPartitionKey(i); + cache.put(key, "data"); + } + + return "OK"; + } + + /** + * Obtain the environment variables. + * + * @return the environment variables + */ + @RequestMapping("/env") + public Map env() { + return new TreeMap<>(System.getenv()); + } + + /** + * Obtain the Spring Boot message. + * + * @return the Spring Boot message + */ + @RequestMapping("/") + public String index() { + return "Greetings from Spring Boot!"; + } + + /** + * Obtain the system properties. + * + * @return the system properties + */ + @RequestMapping("/props") + public Map props() { + Map map = new TreeMap<>(); + Properties props = System.getProperties(); + for (String name : props.stringPropertyNames()) { + map.put(name, props.getProperty(name)); + } + return map; + } + + /** + * A canary test failure exception. + */ + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + public static class CanaryFailure + extends RuntimeException { + /** + * Create a canary test failure exception. + * + * @param actual the actual cache size + * @param expected the expected cache size + */ + public CanaryFailure(int actual, int expected) { + super("Canary check failed. Expected " + expected + " entries but there are only " + actual); + } + } +} diff --git a/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java new file mode 100644 index 000000000..c2450ba8b --- /dev/null +++ b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +package com.oracle.coherence.k8s.testing.spring; + +import java.util.Arrays; +import java.util.logging.Logger; + +import com.tangosol.net.Coherence; +import com.tangosol.net.DefaultCacheServer; +import com.tangosol.net.Session; + +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; + +/** + * The test Spring storage application. + * + * @author Jonathan Knight 2020.09.10 + */ +@SpringBootApplication +public class StorageApplication { + private static final Logger LOGGER = Logger.getLogger(StorageApplication.class.getName()); + + private static String[] arguments; + + /** + * Run the application. + * + * @param args the application arguments + */ + public static void main(String[] args) { + arguments = args; + SpringApplication.run(StorageApplication.class, args); + } + + /** + * Obtain the application arguments. + * + * @return the application arguments + */ + @Bean(name = "commandLineArguments") + public String[] commandLineArguments() { + return arguments; + } + + /** + * Obtain the Coherence {@link DefaultCacheServer} starter. + * + * @return the Coherence {@link DefaultCacheServer} starter + */ + @Bean + @Order(1) + public ApplicationRunner runCoherence() { + return (args) -> { + LOGGER.info("Starting Coherence with args " + Arrays.toString(args.getSourceArgs())); + Coherence.main(args.getSourceArgs()); + }; + } + + /** + * Obtain a Coherence {@link Session}. + * + * @return a Coherence {@link Session} + */ + @Bean + public Session createCoherenceSession() { + return Session.create(); + } +} diff --git a/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/package-info.java b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/package-info.java new file mode 100644 index 000000000..b47e74f11 --- /dev/null +++ b/java/operator-test-spring-2/src/main/java/com/oracle/coherence/k8s/testing/spring/package-info.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. + * Licensed under the Universal Permissive License v 1.0 as shown at + * http://oss.oracle.com/licenses/upl. + */ + +/** + * A test Spring application. + * + * @author Jonathan Knight 2020.09.20 + */ +package com.oracle.coherence.k8s.testing.spring; diff --git a/java/operator-test-spring/pom.xml b/java/operator-test-spring/pom.xml index 251644a27..31f3176b2 100644 --- a/java/operator-test-spring/pom.xml +++ b/java/operator-test-spring/pom.xml @@ -1,9 +1,11 @@ + + Copyright (c) 2019, 2025, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +--> operator-test-spring - Oracle Coherence Kubernetes Operator Test (Spring) + Oracle Coherence Kubernetes Operator Test (Spring v3.x) operator-test-spring ${project.artifactId}-cnbp:${project.version} + gcr.io/distroless/java21-debian12 + + + + ${coherence.groupId} + coherence-bom + ${coherence.ce.version} + pom + import + + + + ${coherence.groupId} coherence - ${coherence.version} org.springframework.boot spring-boot-starter-web + ${version.lib.spring} org.springframework.boot @@ -78,9 +93,6 @@ ${cnbp-image-name} - - 17.* - @@ -90,6 +102,9 @@ jib-maven-plugin ${version.plugin.jib} + + docker://${coherence.test.base.image.21} + true diff --git a/java/operator-test-spring/src/main/docker/Dir.Dockerfile b/java/operator-test-spring/src/main/docker/Dir.Dockerfile index 1da8065a0..676cde819 100644 --- a/java/operator-test-spring/src/main/docker/Dir.Dockerfile +++ b/java/operator-test-spring/src/main/docker/Dir.Dockerfile @@ -2,4 +2,6 @@ FROM gcr.io/distroless/java17-debian12 ADD spring /spring -ENTRYPOINT ["java", "org.springframework.boot.loader.PropertiesLauncher"] \ No newline at end of file +WORKDIR /spring + +ENTRYPOINT ["java", "org.springframework.boot.loader.launch.PropertiesLauncher"] \ No newline at end of file diff --git a/java/operator-test-spring/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java b/java/operator-test-spring/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java index c70d5343b..c2450ba8b 100644 --- a/java/operator-test-spring/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java +++ b/java/operator-test-spring/src/main/java/com/oracle/coherence/k8s/testing/spring/StorageApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.logging.Logger; +import com.tangosol.net.Coherence; import com.tangosol.net.DefaultCacheServer; import com.tangosol.net.Session; @@ -58,8 +59,8 @@ public String[] commandLineArguments() { @Order(1) public ApplicationRunner runCoherence() { return (args) -> { - LOGGER.info("Starting DefaultCacheServer with args " + Arrays.toString(args.getSourceArgs())); - DefaultCacheServer.main(args.getSourceArgs()); + LOGGER.info("Starting Coherence with args " + Arrays.toString(args.getSourceArgs())); + Coherence.main(args.getSourceArgs()); }; } diff --git a/java/operator-test/pom.xml b/java/operator-test/pom.xml index 15c8a106a..7f7615319 100644 --- a/java/operator-test/pom.xml +++ b/java/operator-test/pom.xml @@ -1,9 +1,11 @@ + + Copyright (c) 2019, 2025, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +--> Oracle Coherence Kubernetes Operator Test operator-test + + + + ${coherence.groupId} + coherence-bom + ${coherence.version} + pom + import + + + + ${coherence.groupId} coherence - ${coherence.version} ${coherence.groupId} coherence-grpc-proxy - ${coherence.version} ${coherence.groupId} coherence-management - ${coherence.version} diff --git a/java/pom.xml b/java/pom.xml index e6452506f..0be363740 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -1,10 +1,11 @@ - + + Copyright (c) 2019, 2025, Oracle and/or its affiliates. + Licensed under the Universal Permissive License v 1.0 as shown at + http://oss.oracle.com/licenses/upl. + +--> operator-compatibility operator-test operator-test-helidon + operator-test-helidon-3 + operator-test-helidon-2 operator-test-spring + operator-test-spring-2 operator-test-client @@ -43,9 +47,11 @@ 21.12.5 14.1.2-0-0 + 24.09.2 com.oracle.coherence.ce gcr.io/distroless/java17-debian12 + gcr.io/distroless/java21-debian12 ghcr.io/oracle/coherence-ce:${coherence.version} ghcr.io/oracle/${project.artifactId}:${project.version} @@ -53,19 +59,17 @@ ../build/_output/certs - 1.2.2 2.0.2 5.1.6 8.18 0.3.1 2.1 1.3 - 2.6.5 4.13.1 5.7.2 3.10.0 3.25.5 - 2.7.18 + 3.4.2 1.8.4 2.8.9 @@ -101,14 +105,6 @@ - - ${coherence.groupId} - coherence-bom - ${coherence.version} - pom - import - - com.google.protobuf protobuf-bom @@ -122,25 +118,6 @@ spring-boot ${version.lib.spring} - - org.springframework.boot - spring-boot-starter-web - ${version.lib.spring} - - - - - io.helidon - helidon-dependencies - ${version.lib.helidon} - pom - import - - - jakarta.activation - jakarta.activation-api - ${version.lib.activation-api} - diff --git a/pkg/runner/cmd_console.go b/pkg/runner/cmd_console.go index 37d1ad13c..1ae7827bc 100644 --- a/pkg/runner/cmd_console.go +++ b/pkg/runner/cmd_console.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -9,7 +9,8 @@ package runner import ( v1 "github.com/oracle/coherence-operator/api/v1" "github.com/spf13/cobra" - "os" + "github.com/spf13/viper" + "strings" ) const ( @@ -18,26 +19,36 @@ const ( ) // consoleCommand creates the cobra sub-command to run a Coherence CacheFactory console. -func consoleCommand() *cobra.Command { +func consoleCommand(v *viper.Viper) *cobra.Command { return &cobra.Command{ Use: CommandConsole, Short: "Start a Coherence interactive console", Long: "Starts a Coherence interactive console", RunE: func(cmd *cobra.Command, args []string) error { - return run(cmd, console) + return run(cmd, func(details *RunDetails, _ *cobra.Command) { + console(details, args, v) + }) }, } } // Configure the runner to run a Coherence CacheFactory console -func console(details *RunDetails, _ *cobra.Command) { +func console(details *RunDetails, args []string, v *viper.Viper) { + app := strings.ToLower(v.GetString(v1.EnvVarAppType)) + if app == AppTypeSpring2 { + details.AppType = AppTypeSpring2 + details.MainClass = SpringBootMain2 + details.addArg("-Dloader.main=" + ConsoleMain) + } else { + details.AppType = AppTypeJava + details.MainClass = ConsoleMain + } details.Command = CommandConsole - details.AppType = AppTypeJava - details.MainClass = "com.tangosol.net.CacheFactory" details.addArg("-Dcoherence.distributed.localstorage=false") details.setenv(v1.EnvVarCohRole, "console") details.unsetenv(v1.EnvVarJvmMemoryHeap) - if len(os.Args) > 2 { - details.MainArgs = os.Args[2:] - } + details.unsetenv(v1.EnvVarCoherenceLocalPortAdjust) + details.unsetenv(v1.EnvVarCohMgmtPrefix + v1.EnvVarCohEnabledSuffix) + details.unsetenv(v1.EnvVarCohMetricsPrefix + v1.EnvVarCohEnabledSuffix) + details.MainArgs = args } diff --git a/pkg/runner/cmd_jshell.go b/pkg/runner/cmd_jshell.go index 46b5e48e5..9c32b5560 100644 --- a/pkg/runner/cmd_jshell.go +++ b/pkg/runner/cmd_jshell.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -41,4 +41,7 @@ func jShell(details *RunDetails, _ *cobra.Command) { details.addArg("-Dcoherence.distributed.localstorage=false") details.setenv(v1.EnvVarCohRole, "jshell") details.unsetenv(v1.EnvVarJvmMemoryHeap) + details.unsetenv(v1.EnvVarCoherenceLocalPortAdjust) + details.unsetenv(v1.EnvVarCohMgmtPrefix + v1.EnvVarCohEnabledSuffix) + details.unsetenv(v1.EnvVarCohMetricsPrefix + v1.EnvVarCohEnabledSuffix) } diff --git a/pkg/runner/cmd_query_plus.go b/pkg/runner/cmd_query_plus.go index 135f3117e..2efa8d6b4 100644 --- a/pkg/runner/cmd_query_plus.go +++ b/pkg/runner/cmd_query_plus.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -41,4 +41,7 @@ func queryPlus(details *RunDetails, _ *cobra.Command) { details.addArg("-Dcoherence.distributed.localstorage=false") details.setenv(v1.EnvVarCohRole, "queryPlus") details.unsetenv(v1.EnvVarJvmMemoryHeap) + details.unsetenv(v1.EnvVarCoherenceLocalPortAdjust) + details.unsetenv(v1.EnvVarCohMgmtPrefix + v1.EnvVarCohEnabledSuffix) + details.unsetenv(v1.EnvVarCohMetricsPrefix + v1.EnvVarCohEnabledSuffix) } diff --git a/pkg/runner/cmd_server.go b/pkg/runner/cmd_server.go index b00a48d3f..b4fb196f8 100644 --- a/pkg/runner/cmd_server.go +++ b/pkg/runner/cmd_server.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -55,19 +55,29 @@ func server(details *RunDetails, _ *cobra.Command) { mc = mainCls found = true } + isSpring := details.IsSpringBoot() switch { - case found && details.AppType != AppTypeSpring: + case found && !isSpring: // we have a main class specified, and we're not a Spring Boot app details.MainArgs = []string{mc} - case found && details.AppType == AppTypeSpring: - // we have a main class and the app is Spring Boot + case found && details.AppType == AppTypeSpring2: + // we have a main class and the app is Spring Boot 2.x // the main is PropertiesLauncher, - details.MainClass = SpringBootMain + details.MainClass = SpringBootMain2 // the specified main class is set as a Spring loader property details.addArg("-Dloader.main=" + mc) - case !found && details.AppType == AppTypeSpring: - // the app type is Spring Boot so main is PropertiesLauncher - details.MainClass = SpringBootMain + case found && details.AppType == AppTypeSpring3: + // we have a main class and the app is Spring Boot 3.x + // the main is PropertiesLauncher, + details.MainClass = SpringBootMain3 + // the specified main class is set as a Spring loader property + details.addArg("-Dloader.main=" + mc) + case !found && details.AppType == AppTypeSpring2: + // the app type is Spring Boot 2.x so main is PropertiesLauncher + details.MainClass = SpringBootMain2 + case !found && details.AppType == AppTypeSpring3: + // the app type is Spring Boot 3.x so main is PropertiesLauncher + details.MainClass = SpringBootMain3 case !found && details.AppType == AppTypeCoherence: // the app type is Coherence so main is DefaultMain details.MainArgs = []string{DefaultMain} diff --git a/pkg/runner/cmd_sleep.go b/pkg/runner/cmd_sleep.go index 72f77d1ae..b5ced347e 100644 --- a/pkg/runner/cmd_sleep.go +++ b/pkg/runner/cmd_sleep.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -9,7 +9,6 @@ package runner import ( v1 "github.com/oracle/coherence-operator/api/v1" "github.com/spf13/cobra" - "os" ) const ( @@ -25,18 +24,18 @@ func sleepCommand() *cobra.Command { Long: "Sleep for a number of seconds", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { - return run(cmd, sleep) + return run(cmd, func(details *RunDetails, _ *cobra.Command) { + sleep(details, args) + }) }, } } -func sleep(details *RunDetails, _ *cobra.Command) { +func sleep(details *RunDetails, args []string) { details.Command = CommandSleep details.AppType = AppTypeJava details.MainClass = "com.oracle.coherence.k8s.Sleep" - if len(os.Args) > 2 { - details.MainArgs = os.Args[2:] - } + details.MainArgs = args details.UseOperatorHealth = true details.addArg("-Dcoherence.distributed.localstorage=false") details.setenv(v1.EnvVarCohRole, "sleep") diff --git a/pkg/runner/run_details.go b/pkg/runner/run_details.go index 70e97e401..7ed640725 100644 --- a/pkg/runner/run_details.go +++ b/pkg/runner/run_details.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -56,6 +56,14 @@ type RunDetails struct { env *viper.Viper } +// IsSpringBoot returns true if this is a Spring Boot application +func (in *RunDetails) IsSpringBoot() bool { + if in.env == nil { + return false + } + return in.AppType == AppTypeSpring2 || in.AppType == AppTypeSpring3 +} + // Getenv returns the value for the specified environment variable, or empty string if not set. func (in *RunDetails) Getenv(name string) string { if in.env == nil { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 03b714664..392aba4c1 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -39,8 +39,12 @@ const ( HelidonMain = "io.helidon.microprofile.cdi.Main" // ServerMain is the default server main class name. ServerMain = "com.oracle.coherence.k8s.Main" - // SpringBootMain is the default Spring Boot main class name. - SpringBootMain = "org.springframework.boot.loader.PropertiesLauncher" + // SpringBootMain2 is the default Spring Boot 2.x main class name. + SpringBootMain2 = "org.springframework.boot.loader.PropertiesLauncher" + // SpringBootMain3 is the default Spring Boot 3.x main class name. + SpringBootMain3 = "org.springframework.boot.loader.launch.PropertiesLauncher" + // ConsoleMain is the Coherence console main class + ConsoleMain = "com.tangosol.net.CacheFactory" // AppTypeNone is the argument to specify no application type. AppTypeNone = "" @@ -50,8 +54,10 @@ const ( AppTypeCoherence = "coherence" // AppTypeHelidon is the argument to specify a Helidon application. AppTypeHelidon = "helidon" - // AppTypeSpring is the argument to specify a Spring application. - AppTypeSpring = "spring" + // AppTypeSpring2 is the argument to specify an exploded Spring Boot 2.x application. + AppTypeSpring2 = "spring" + // AppTypeSpring3 is the argument to specify an exploded Spring Boot 3.x application. + AppTypeSpring3 = "spring3" // AppTypeOperator is the argument to specify running an Operator command. AppTypeOperator = "operator" @@ -117,7 +123,7 @@ func NewRootCommand(env map[string]string, v *viper.Viper) *cobra.Command { rootCmd.AddCommand(initCommand(env)) rootCmd.AddCommand(serverCommand()) - rootCmd.AddCommand(consoleCommand()) + rootCmd.AddCommand(consoleCommand(v)) rootCmd.AddCommand(queryPlusCommand()) rootCmd.AddCommand(statusCommand()) rootCmd.AddCommand(readyCommand()) @@ -319,7 +325,7 @@ func createCommand(details *RunDetails) (string, *exec.Cmd, error) { // Configure the classpath to support images created with the JIB Maven plugin // This is enabled by default unless the image is a buildpacks image, or we // are running a Spring Boot application. - if !details.isBuildPacks() && details.AppType != AppTypeSpring && details.isEnvTrueOrBlank(v1.EnvVarJvmClasspathJib) { + if !details.isBuildPacks() && !details.IsSpringBoot() && details.isEnvTrueOrBlank(v1.EnvVarJvmClasspathJib) { appDir := details.getenvOrDefault(v1.EnvVarCohAppDir, "/app") cpFile := filepath.Join(appDir, "jib-classpath-file") fi, e := os.Stat(cpFile) @@ -599,7 +605,7 @@ func createCommand(details *RunDetails) (string, *exec.Cmd, error) { case details.AppType == AppTypeNone || details.AppType == AppTypeJava: app = "Java" cmd, err = createJavaCommand(details.getJavaExecutable(), details) - case details.AppType == AppTypeSpring: + case details.IsSpringBoot(): app = "SpringBoot" cmd, err = createSpringBootCommand(details.getJavaExecutable(), details) case details.AppType == AppTypeHelidon: @@ -646,7 +652,10 @@ func readFirstLineFromFile(path string) (string, error) { func createSpringBootCommand(javaCmd string, details *RunDetails) (*exec.Cmd, error) { if details.isBuildPacks() { - return _createBuildPackCommand(details, SpringBootMain, details.getSpringBootArgs()) + if details.AppType == AppTypeSpring2 { + return _createBuildPackCommand(details, SpringBootMain2, details.getSpringBootArgs()) + } + return _createBuildPackCommand(details, SpringBootMain3, details.getSpringBootArgs()) } args := details.getSpringBootCommand() return _createJavaCommand(javaCmd, details, args) @@ -931,32 +940,40 @@ func checkCoherenceVersion(v string, details *RunDetails) bool { } // Get the classpath to use (we need Coherence jar) - cp := details.UtilsDir + "/lib/coherence-operator.jar" + ":" + details.getClasspath() + cp := details.getClasspath() var exe string var cmd *exec.Cmd var args []string if details.isBuildPacks() { - // This is a buildpacks image so use the Buildpacks launcher to run Java + // This is a build-packs image so use the Build-packs launcher to run Java exe = getBuildpackLauncher() - args = []string{"java"} + args = []string{exe} } else { // this should be a normal image with Java available exe = details.getJavaExecutable() } - if details.AppType == AppTypeSpring { + if details.IsSpringBoot() { // This is a Spring Boot App so Coherence jar is embedded in the Spring Boot application + cp := strings.ReplaceAll(cp, ":", ",") args = append(args, "-Dloader.path="+cp, "-Dcoherence.operator.springboot.listener=false", - "-Dloader.main=com.oracle.coherence.k8s.CoherenceVersion", - "org.springframework.boot.loader.PropertiesLauncher", v) + "-Dloader.main=com.oracle.coherence.k8s.CoherenceVersion") if jar, _ := details.lookupEnv(v1.EnvVarSpringBootFatJar); jar != "" { // This is a fat jar Spring boot app so put the fat jar on the classpath args = append(args, "-cp", jar) } + + if details.AppType == AppTypeSpring2 { + // we are running SpringBoot 2.x + args = append(args, SpringBootMain2, v) + } else { + // we are running SpringBoot 3.x + args = append(args, SpringBootMain3, v) + } } else { // We can use normal Java args = append(args, "-cp", cp, diff --git a/pkg/runner/runner_spring_test.go b/pkg/runner/runner_spring_test.go index 95e8fdabb..58832eb63 100644 --- a/pkg/runner/runner_spring_test.go +++ b/pkg/runner/runner_spring_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -24,7 +24,7 @@ func TestSpringBootApplication(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{ CoherenceResourceSpec: coh.CoherenceResourceSpec{ Application: &coh.ApplicationSpec{ - Type: ptr.To(AppTypeSpring), + Type: ptr.To(AppTypeSpring2), }, }, }, @@ -34,7 +34,37 @@ func TestSpringBootApplication(t *testing.T) { env := EnvVarsFromDeployment(d) expectedCommand := GetJavaCommand() - expectedArgs := GetMinimalExpectedSpringBootArgs() + expectedArgs := GetMinimalExpectedSpringBootArgs(SpringBootMain2) + + e, err := ExecuteWithArgsAndNewViper(env, args) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(e).NotTo(BeNil()) + g.Expect(e.OsCmd).NotTo(BeNil()) + + g.Expect(e.OsCmd.Dir).To(Equal(TestAppDir)) + g.Expect(e.OsCmd.Path).To(Equal(expectedCommand)) + g.Expect(e.OsCmd.Args).To(ConsistOf(expectedArgs)) +} + +func TestSpringBoot3Application(t *testing.T) { + g := NewGomegaWithT(t) + + d := &coh.Coherence{ + ObjectMeta: metav1.ObjectMeta{Name: "test"}, + Spec: coh.CoherenceStatefulSetResourceSpec{ + CoherenceResourceSpec: coh.CoherenceResourceSpec{ + Application: &coh.ApplicationSpec{ + Type: ptr.To(AppTypeSpring3), + }, + }, + }, + } + + args := []string{"server", "--dry-run"} + env := EnvVarsFromDeployment(d) + + expectedCommand := GetJavaCommand() + expectedArgs := GetMinimalExpectedSpringBootArgs(SpringBootMain3) e, err := ExecuteWithArgsAndNewViper(env, args) g.Expect(err).NotTo(HaveOccurred()) @@ -55,7 +85,39 @@ func TestSpringBootFatJarApplication(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{ CoherenceResourceSpec: coh.CoherenceResourceSpec{ Application: &coh.ApplicationSpec{ - Type: ptr.To(AppTypeSpring), + Type: ptr.To(AppTypeSpring2), + SpringBootFatJar: &jar, + }, + }, + }, + } + + args := []string{"server", "--dry-run"} + env := EnvVarsFromDeployment(d) + + expectedCommand := GetJavaCommand() + expectedArgs := GetMinimalExpectedSpringBootFatJarArgs(jar, SpringBootMain2) + + e, err := ExecuteWithArgsAndNewViper(env, args) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(e).NotTo(BeNil()) + g.Expect(e.OsCmd).NotTo(BeNil()) + + g.Expect(e.OsCmd.Dir).To(Equal(TestAppDir)) + g.Expect(e.OsCmd.Path).To(Equal(expectedCommand)) + g.Expect(e.OsCmd.Args).To(ConsistOf(expectedArgs)) +} + +func TestSpringBoot3FatJarApplication(t *testing.T) { + g := NewGomegaWithT(t) + + jar := "/apps/lib/foo.jar" + d := &coh.Coherence{ + ObjectMeta: metav1.ObjectMeta{Name: "test"}, + Spec: coh.CoherenceStatefulSetResourceSpec{ + CoherenceResourceSpec: coh.CoherenceResourceSpec{ + Application: &coh.ApplicationSpec{ + Type: ptr.To(AppTypeSpring3), SpringBootFatJar: &jar, }, }, @@ -66,7 +128,71 @@ func TestSpringBootFatJarApplication(t *testing.T) { env := EnvVarsFromDeployment(d) expectedCommand := GetJavaCommand() - expectedArgs := GetMinimalExpectedSpringBootFatJarArgs(jar) + expectedArgs := GetMinimalExpectedSpringBootFatJarArgs(jar, SpringBootMain3) + + e, err := ExecuteWithArgsAndNewViper(env, args) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(e).NotTo(BeNil()) + g.Expect(e.OsCmd).NotTo(BeNil()) + + g.Expect(e.OsCmd.Dir).To(Equal(TestAppDir)) + g.Expect(e.OsCmd.Path).To(Equal(expectedCommand)) + g.Expect(e.OsCmd.Args).To(ConsistOf(expectedArgs)) +} + +func TestSpringBootFatJarConsole(t *testing.T) { + g := NewGomegaWithT(t) + + jar := "/apps/lib/foo.jar" + d := &coh.Coherence{ + ObjectMeta: metav1.ObjectMeta{Name: "test"}, + Spec: coh.CoherenceStatefulSetResourceSpec{ + CoherenceResourceSpec: coh.CoherenceResourceSpec{ + Application: &coh.ApplicationSpec{ + Type: ptr.To(AppTypeSpring2), + SpringBootFatJar: &jar, + }, + }, + }, + } + + args := []string{"console", "--dry-run"} + env := EnvVarsFromDeployment(d) + + expectedCommand := GetJavaCommand() + expectedArgs := GetMinimalExpectedSpringBootFatJarArgsForRole(jar, ConsoleMain, "") + + e, err := ExecuteWithArgsAndNewViper(env, args) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(e).NotTo(BeNil()) + g.Expect(e.OsCmd).NotTo(BeNil()) + + g.Expect(e.OsCmd.Dir).To(Equal(TestAppDir)) + g.Expect(e.OsCmd.Path).To(Equal(expectedCommand)) + g.Expect(e.OsCmd.Args).To(ConsistOf(expectedArgs)) +} + +func TestSpringBootFatJarConsoleWithArgs(t *testing.T) { + g := NewGomegaWithT(t) + + jar := "/apps/lib/foo.jar" + d := &coh.Coherence{ + ObjectMeta: metav1.ObjectMeta{Name: "test"}, + Spec: coh.CoherenceStatefulSetResourceSpec{ + CoherenceResourceSpec: coh.CoherenceResourceSpec{ + Application: &coh.ApplicationSpec{ + Type: ptr.To(AppTypeSpring2), + SpringBootFatJar: &jar, + }, + }, + }, + } + + args := []string{"console", "--dry-run", "--", "foo", "bar"} + env := EnvVarsFromDeployment(d) + + expectedCommand := GetJavaCommand() + expectedArgs := append(GetMinimalExpectedSpringBootFatJarArgsForRole(jar, ConsoleMain, ""), "foo", "bar") e, err := ExecuteWithArgsAndNewViper(env, args) g.Expect(err).NotTo(HaveOccurred()) @@ -87,7 +213,7 @@ func TestSpringBootFatJarApplicationWithCustomMain(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{ CoherenceResourceSpec: coh.CoherenceResourceSpec{ Application: &coh.ApplicationSpec{ - Type: ptr.To(AppTypeSpring), + Type: ptr.To(AppTypeSpring2), SpringBootFatJar: &jar, Main: ptr.To("foo.Bar"), }, @@ -99,7 +225,7 @@ func TestSpringBootFatJarApplicationWithCustomMain(t *testing.T) { env := EnvVarsFromDeployment(d) expectedCommand := GetJavaCommand() - expectedArgs := append(GetMinimalExpectedSpringBootFatJarArgs(jar), "-Dloader.main=foo.Bar") + expectedArgs := append(GetMinimalExpectedSpringBootFatJarArgs(jar, SpringBootMain2), "-Dloader.main=foo.Bar") e, err := ExecuteWithArgsAndNewViper(env, args) g.Expect(err).NotTo(HaveOccurred()) @@ -119,7 +245,7 @@ func TestSpringBootBuildpacks(t *testing.T) { Spec: coh.CoherenceStatefulSetResourceSpec{ CoherenceResourceSpec: coh.CoherenceResourceSpec{ Application: &coh.ApplicationSpec{ - Type: ptr.To(AppTypeSpring), + Type: ptr.To(AppTypeSpring2), CloudNativeBuildPack: &coh.CloudNativeBuildPackSpec{ Enabled: ptr.To(true), }, @@ -144,7 +270,7 @@ func TestSpringBootBuildpacks(t *testing.T) { g.Expect(len(e.OsCmd.Args)).To(Equal(4)) g.Expect(e.OsCmd.Args[0]).To(Equal(coh.DefaultCnbpLauncher)) g.Expect(e.OsCmd.Args[1]).To(Equal("java")) - g.Expect(e.OsCmd.Args[3]).To(Equal(SpringBootMain)) + g.Expect(e.OsCmd.Args[3]).To(Equal(SpringBootMain2)) g.Expect(e.OsCmd.Args[2]).To(HavePrefix("@")) fileName := e.OsCmd.Args[2][1:] @@ -156,16 +282,20 @@ func TestSpringBootBuildpacks(t *testing.T) { g.Expect(actualOpts).To(ConsistOf(expectedOpts)) } -func GetMinimalExpectedSpringBootArgs() []string { +func GetMinimalExpectedSpringBootArgs(main string) []string { args := []string{ GetJavaArg(), "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", } - args = append(AppendCommonExpectedArgs(args), SpringBootMain) + args = append(AppendCommonExpectedArgs(args), main) return args } -func GetMinimalExpectedSpringBootFatJarArgs(jar string) []string { +func GetMinimalExpectedSpringBootFatJarArgs(jar, main string) []string { + return GetMinimalExpectedSpringBootFatJarArgsWithMain(jar, main, "") +} + +func GetMinimalExpectedSpringBootFatJarArgsWithMain(jar, springMain, main string) []string { args := []string{ GetJavaArg(), "-cp", @@ -173,5 +303,25 @@ func GetMinimalExpectedSpringBootFatJarArgs(jar string) []string { "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", } - return append(AppendCommonExpectedArgs(args), SpringBootMain) + if main != "" { + args = append(args, "-Dloader.main="+main) + } + + return append(AppendCommonExpectedArgs(args), springMain) +} + +func GetMinimalExpectedSpringBootFatJarArgsForRole(jar, main, role string) []string { + args := []string{ + GetJavaArg(), + "-cp", + jar, + "-Dloader.path=/coherence-operator/utils/lib/coherence-operator.jar,/coherence-operator/utils/config", + "-Dcoherence.distributed.localstorage=false", + } + + if main != "" { + args = append(args, "-Dloader.main="+main) + } + + return append(AppendCommonExpectedNonServerArgs(args, role), SpringBootMain2) } diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 225ee294b..9f50fa727 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -122,6 +122,14 @@ func GetMinimalExpectedArgs() []string { "$DEFAULT$") } +func GetMinimalExpectedArgsWithoutCP() []string { + args := make([]string, 0) + args = append(args, GetJavaArg()) + return append(AppendCommonExpectedArgs(args), + "com.oracle.coherence.k8s.Main", + "$DEFAULT$") +} + func GetMinimalExpectedArgsWithoutAppClasspath() []string { args := []string{ GetJavaArg(), @@ -135,11 +143,18 @@ func GetMinimalExpectedArgsWithoutAppClasspath() []string { } func AppendCommonExpectedArgs(args []string) []string { - return append(args, - "-Dcoherence.role=test", + return append(AppendCommonExpectedNonServerArgs(args, "test"), "-XshowSettings:all", "-XX:+PrintCommandLineFlags", "-XX:+PrintFlagsFinal", + ) +} + +func AppendCommonExpectedNonServerArgs(args []string, role string) []string { + if role != "" { + args = append(args, "-Dcoherence.role="+role) + } + return append(args, "-Dcoherence.wka=test-wka..svc", "-Dcoherence.cluster=test", "-Dcoherence.k8s.operator.health.port=6676", diff --git a/test/e2e/local/helidon-cluster-2.yaml b/test/e2e/local/helidon-cluster-2.yaml new file mode 100644 index 000000000..4cad9511f --- /dev/null +++ b/test/e2e/local/helidon-cluster-2.yaml @@ -0,0 +1,15 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: helidon-test +spec: + replicas: 3 + image: ${TEST_APPLICATION_IMAGE_HELIDON_2} + application: + type: helidon + jvm: + args: + - -Dcoherence.log=jdk + ports: + - name: web + port: 8080 diff --git a/test/e2e/local/helidon-cluster-3.yaml b/test/e2e/local/helidon-cluster-3.yaml new file mode 100644 index 000000000..f2d65b6bd --- /dev/null +++ b/test/e2e/local/helidon-cluster-3.yaml @@ -0,0 +1,15 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: helidon-test +spec: + replicas: 3 + image: ${TEST_APPLICATION_IMAGE_HELIDON_3} + application: + type: helidon + jvm: + args: + - -Dcoherence.log=jdk + ports: + - name: web + port: 8080 diff --git a/test/e2e/local/helidon_test.go b/test/e2e/local/helidon_test.go index d66bddcdc..dc9cf3276 100644 --- a/test/e2e/local/helidon_test.go +++ b/test/e2e/local/helidon_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -22,6 +22,18 @@ func TestHelidonCdiCluster(t *testing.T) { AssertHelidonEndpoint(t, pods) } +func TestHelidonThreeCdiCluster(t *testing.T) { + testContext.CleanupAfterTest(t) + _, pods := helper.AssertDeployments(testContext, t, "helidon-cluster-3.yaml") + AssertHelidonEndpoint(t, pods) +} + +func TestHelidonTwoCdiCluster(t *testing.T) { + testContext.CleanupAfterTest(t) + _, pods := helper.AssertDeployments(testContext, t, "helidon-cluster-2.yaml") + AssertHelidonEndpoint(t, pods) +} + // Assert that we can hit the Helidon web-app endpoint func AssertHelidonEndpoint(t *testing.T, pods []corev1.Pod) { g := NewGomegaWithT(t) diff --git a/test/e2e/local/spring-buildpack-cluster-2.yaml b/test/e2e/local/spring-buildpack-cluster-2.yaml new file mode 100644 index 000000000..e549f8c61 --- /dev/null +++ b/test/e2e/local/spring-buildpack-cluster-2.yaml @@ -0,0 +1,15 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: spring-test +spec: + replicas: 3 + image: ${TEST_APPLICATION_IMAGE_SPRING_CNBP_2} + application: + type: spring + jvm: + args: + - -Dcoherence.log=jdk + ports: + - name: web + port: 8080 \ No newline at end of file diff --git a/test/e2e/local/spring-buildpack-cluster.yaml b/test/e2e/local/spring-buildpack-cluster.yaml index 00bf86516..b7f04a9f3 100644 --- a/test/e2e/local/spring-buildpack-cluster.yaml +++ b/test/e2e/local/spring-buildpack-cluster.yaml @@ -6,7 +6,7 @@ spec: replicas: 3 image: ${TEST_APPLICATION_IMAGE_SPRING_CNBP} application: - type: spring + type: spring3 jvm: args: - -Dcoherence.log=jdk diff --git a/test/e2e/local/spring-cluster-2.yaml b/test/e2e/local/spring-cluster-2.yaml new file mode 100644 index 000000000..932a64cde --- /dev/null +++ b/test/e2e/local/spring-cluster-2.yaml @@ -0,0 +1,16 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: spring-test +spec: + replicas: 3 + image: ${TEST_APPLICATION_IMAGE_SPRING_2} + application: + type: spring + workingDir: /spring + jvm: + args: + - -Dcoherence.log=jdk + ports: + - name: web + port: 8080 \ No newline at end of file diff --git a/test/e2e/local/spring-cluster.yaml b/test/e2e/local/spring-cluster.yaml index 81c3299bb..7f666c85f 100644 --- a/test/e2e/local/spring-cluster.yaml +++ b/test/e2e/local/spring-cluster.yaml @@ -6,7 +6,7 @@ spec: replicas: 3 image: ${TEST_APPLICATION_IMAGE_SPRING} application: - type: spring + type: spring3 workingDir: /spring jvm: args: diff --git a/test/e2e/local/spring-fat-jar-cluster-2.yaml b/test/e2e/local/spring-fat-jar-cluster-2.yaml new file mode 100644 index 000000000..8bbd02b5e --- /dev/null +++ b/test/e2e/local/spring-fat-jar-cluster-2.yaml @@ -0,0 +1,16 @@ +apiVersion: coherence.oracle.com/v1 +kind: Coherence +metadata: + name: spring-fat-test +spec: + replicas: 3 + image: ${TEST_APPLICATION_IMAGE_SPRING_FAT_2} + application: + type: spring + springBootFatJar: /app/libs/operator-test-spring-2-${MVN_VERSION}.jar + jvm: + args: + - -Dcoherence.log=jdk + ports: + - name: web + port: 8080 \ No newline at end of file diff --git a/test/e2e/local/spring-fat-jar-cluster.yaml b/test/e2e/local/spring-fat-jar-cluster.yaml index 2a1b7ae67..2928a0f9e 100644 --- a/test/e2e/local/spring-fat-jar-cluster.yaml +++ b/test/e2e/local/spring-fat-jar-cluster.yaml @@ -6,7 +6,7 @@ spec: replicas: 3 image: ${TEST_APPLICATION_IMAGE_SPRING_FAT} application: - type: spring + type: spring3 springBootFatJar: /app/libs/operator-test-spring-${MVN_VERSION}.jar jvm: args: diff --git a/test/e2e/local/spring_test.go b/test/e2e/local/spring_test.go index b7c2321f4..cca95fe64 100644 --- a/test/e2e/local/spring_test.go +++ b/test/e2e/local/spring_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. * Licensed under the Universal Permissive License v 1.0 as shown at * http://oss.oracle.com/licenses/upl. */ @@ -27,9 +27,27 @@ func TestStartSpringFatJarCluster(t *testing.T) { AssertSpringEndpoint(t, pods) } -func TestStartSpringBuildpacksCluster(t *testing.T) { +//func TestStartSpringBuildpacksCluster(t *testing.T) { +// testContext.CleanupAfterTest(t) +// _, pods := helper.AssertDeployments(testContext, t, "spring-buildpack-cluster.yaml") +// AssertSpringEndpoint(t, pods) +//} + +func TestStartSpringTwoCluster(t *testing.T) { + testContext.CleanupAfterTest(t) + _, pods := helper.AssertDeployments(testContext, t, "spring-cluster-2.yaml") + AssertSpringEndpoint(t, pods) +} + +func TestStartSpringTwoFatJarCluster(t *testing.T) { + testContext.CleanupAfterTest(t) + _, pods := helper.AssertDeployments(testContext, t, "spring-fat-jar-cluster-2.yaml") + AssertSpringEndpoint(t, pods) +} + +func TestStartSpringTwoBuildpacksCluster(t *testing.T) { testContext.CleanupAfterTest(t) - _, pods := helper.AssertDeployments(testContext, t, "spring-buildpack-cluster.yaml") + _, pods := helper.AssertDeployments(testContext, t, "spring-buildpack-cluster-2.yaml") AssertSpringEndpoint(t, pods) }