From dc844b61d4c9aa700e2489e830651fc18524c4c3 Mon Sep 17 00:00:00 2001 From: ovidiupopa07 <105648914+ovidiupopa07@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:46:45 +0200 Subject: [PATCH] fix: Fix git trigger issue caused by a misconfig of the object mapper when creating the echo retrofit service (#1756) * fix: Fix git trigger issue caused by a misconfig of the object mapper when creating the echo retrofit service Because of the misconfiguration echo was failing with GitEventHandler : Github Digest mismatch! Pipeline NOT triggered Closes https://github.com/spinnaker/spinnaker/issues/6886 * fix: Fix git trigger issue caused by a misconfig of the object mapper when creating the echo retrofit service Because of the misconfiguration echo was failing with GitEventHandler : Github Digest mismatch! Pipeline NOT triggered Closes https://github.com/spinnaker/spinnaker/issues/6886 * test: Add test verifying that the payload being sent to Echo is not ordered alphabetically Closes spinnaker/spinnaker#6886 * fix: Apply spotless checks to the test * fix: Fix failing test (cherry picked from commit 4aae98d69fdf22f141ef88da7f9b4225705702be) --- .../spinnaker/gate/config/GateConfig.groovy | 3 +- .../gate/service/EchoServiceTest.java | 107 ++++++++++++++++++ .../resources/application-echo.properties | 44 +++++++ 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 gate-web/src/test/java/com/netflix/spinnaker/gate/service/EchoServiceTest.java create mode 100644 gate-web/src/test/resources/application-echo.properties diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy index 0a2a5df143..491b384e8e 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy @@ -323,7 +323,8 @@ class GateConfig extends RedisHttpSessionConfiguration { private T buildService(String serviceName, Class type, Endpoint endpoint) { ObjectMapper objectMapper = objectMapperBuilder.build() if(serviceName.equals("echo")) { - objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, false) } serviceClientProvider.getService(type, new DefaultServiceEndpoint(serviceName, endpoint.url), objectMapper) } diff --git a/gate-web/src/test/java/com/netflix/spinnaker/gate/service/EchoServiceTest.java b/gate-web/src/test/java/com/netflix/spinnaker/gate/service/EchoServiceTest.java new file mode 100644 index 0000000000..c69fc2a994 --- /dev/null +++ b/gate-web/src/test/java/com/netflix/spinnaker/gate/service/EchoServiceTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2024 Harness, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.netflix.spinnaker.gate.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.netflix.spinnaker.gate.Main; +import com.netflix.spinnaker.gate.services.internal.EchoService; +import com.squareup.okhttp.mockwebserver.Dispatcher; +import com.squareup.okhttp.mockwebserver.MockResponse; +import com.squareup.okhttp.mockwebserver.MockWebServer; +import com.squareup.okhttp.mockwebserver.RecordedRequest; +import groovy.util.logging.Slf4j; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; + +@ActiveProfiles("echo") +@Slf4j +@DirtiesContext +@SpringBootTest(classes = {Main.class}) +@TestPropertySource("/application-echo.properties") +class EchoServiceTest { + + @Autowired EchoService echoService; + + private static MockWebServer echoServer; + private static MockWebServer clouddriverServer; + private static MockWebServer front50Server; + + @BeforeAll + static void setUp() throws IOException { + clouddriverServer = new MockWebServer(); + clouddriverServer.start(7002); + + Dispatcher clouddriverDispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + return new MockResponse().setResponseCode(200); + } + }; + clouddriverServer.setDispatcher(clouddriverDispatcher); + + front50Server = new MockWebServer(); + front50Server.start(8081); + Dispatcher front50Dispatcher = + new Dispatcher() { + @Override + public MockResponse dispatch(RecordedRequest request) { + return new MockResponse().setResponseCode(200); + } + }; + front50Server.setDispatcher(front50Dispatcher); + + echoServer = new MockWebServer(); + echoServer.start(8089); + } + + @AfterAll + static void tearDown() throws IOException { + echoServer.shutdown(); + clouddriverServer.shutdown(); + front50Server.shutdown(); + } + + @Test + void shouldNotOrderTheKeysWhenCallingEcho() throws InterruptedException { + + echoServer.enqueue(new MockResponse().setResponseCode(200)); + Map body = new HashMap<>(); + body.put("ref", "refs/heads/main"); + body.put("before", "ca7376e4b730f1f2878760abaeaed6c039fc5414"); + body.put("after", "c2420ce6e341ef0042f2e12591bdbe9eec29a032"); + body.put("id", 105648914); + + echoService.webhooks("git", "github", body); + RecordedRequest recordedRequest = echoServer.takeRequest(2, TimeUnit.SECONDS); + String requestBody = recordedRequest.getBody().readUtf8(); + assertThat(requestBody) + .isEqualTo( + "{\"ref\":\"refs/heads/main\",\"before\":\"ca7376e4b730f1f2878760abaeaed6c039fc5414\",\"after\":\"c2420ce6e341ef0042f2e12591bdbe9eec29a032\",\"id\":105648914}"); + } +} diff --git a/gate-web/src/test/resources/application-echo.properties b/gate-web/src/test/resources/application-echo.properties new file mode 100644 index 0000000000..f1ee4857ea --- /dev/null +++ b/gate-web/src/test/resources/application-echo.properties @@ -0,0 +1,44 @@ +# +# Copyright 2024 Harness, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http=//www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +spring.application.name=gate +services.clouddriver.baseUrl=http://localhost:7002 +services.deck.baseUrl=http://localhost:9000 + +services.echo.enabled=true +services.echo.baseUrl=http://localhost:8089 + +services.fiat.enabled=false + +services.fiat.baseUrl=http://localhost:8082 + +services.front50.baseUrl=http://localhost:8081 + +services.igor.enabled=false + +services.kayenta.enabled=false + + +services.orca.baseUrl=http://localhost:8083 + +services.mine.enabled=false + +services.swabbie.enabled=false +services.keel.enabled=false +services.keel.baseUrl=http://localhost:8087 + +retrofit.enabled=true +healthCheckableServices=igor