Skip to content

Commit

Permalink
fix(retrofit2): fix retrofit2 issues (#1875)
Browse files Browse the repository at this point in the history
* test(retrofit2): add test to demonstrate the following error when QueryMap is used without generics:

`java.lang.IllegalArgumentException: Map must include generic types (e.g., Map<String, String>)`

* fix(retrofit2): fix non-generics QueryMap which causes the following error:

`java.lang.IllegalArgumentException: Map must include generic types (e.g., Map<String, String>)`

* fix(retrofit2): fix `A @path parameter must not come after a @Query` error
  • Loading branch information
kirangodishala authored Feb 27, 2025
1 parent 381f554 commit bdf8922
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 7 deletions.
1 change: 1 addition & 0 deletions gate-core/gate-core.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
implementation "io.cloudevents:cloudevents-http-basic:2.5.0"
testImplementation "com.squareup.retrofit2:retrofit-mock"
testImplementation "com.squareup.retrofit2:converter-jackson"
testImplementation "com.github.tomakehurst:wiremock-jre8-standalone"
}

sourceSets {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Call<List<Map>> findImages(
@Query("region") String region,
@Query("account") String account,
@Query("count") Integer count,
@QueryMap Map additionalFilters);
@QueryMap Map<String, String> additionalFilters);

@Headers("Accept: application/json")
@GET("/{provider}/images/tags")
Expand All @@ -244,7 +244,7 @@ Call<List<Map>> search(
@Query("platform") String platform,
@Query("pageSize") Integer size,
@Query("page") Integer offset,
@QueryMap Map filters);
@QueryMap Map<String, String> filters);

@GET("/securityGroups")
Call<Map> getSecurityGroups();
Expand Down Expand Up @@ -303,7 +303,7 @@ Call<Map> getCloudMetricStatistics(
@QueryMap Map<String, String> filters);

@GET("/tags")
Call<List<Map>> listEntityTags(@QueryMap Map allParameters);
Call<List<Map>> listEntityTags(@QueryMap Map<String, Object> allParameters);

@GET("/tags/{id}")
Call<Map> getEntityTags(@Path("id") String id);
Expand Down Expand Up @@ -380,9 +380,9 @@ Call<List<Map>> getServerGroupEvents(

@GET("/servicebroker/{account}/services")
Call<List<Map>> listServices(
@Path(value = "account") String account,
@Query(value = "cloudProvider") String cloudProvider,
@Query(value = "region") String region,
@Path(value = "account") String account);
@Query(value = "region") String region);

@GET("/servicebroker/{account}/serviceInstance")
Call<Map> getServiceInstance(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2025 OpsMx, 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.services.internal;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.netflix.spinnaker.kork.retrofit.ErrorHandlingExecutorCallAdapterFactory;
import com.netflix.spinnaker.kork.retrofit.Retrofit2SyncCall;
import java.util.Map;
import okhttp3.OkHttpClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

public class ClouddriverServiceTest {
WireMockServer wireMockServer;
int port;
ClouddriverService clouddriverService;
String baseUrl = "http://localhost:PORT";

@BeforeEach
void setUp() {
wireMockServer = new WireMockServer(WireMockConfiguration.options().dynamicPort());
wireMockServer.start();
port = wireMockServer.port();
WireMock.configureFor("localhost", port);

baseUrl = baseUrl.replaceFirst("PORT", String.valueOf(port));

clouddriverService =
new Retrofit.Builder()
.baseUrl(baseUrl)
.client(new OkHttpClient())
.addCallAdapterFactory(ErrorHandlingExecutorCallAdapterFactory.getInstance())
.addConverterFactory(JacksonConverterFactory.create())
.build()
.create(ClouddriverService.class);
}

@AfterEach
void tearDown() {
wireMockServer.stop();
}

@Test
void testClouddriverService_withQueryMap() {
stubFor(
get(urlEqualTo("/search?q=app1&type=securityGroups&platform=aws&pageSize=500&page=1"))
.willReturn(
aResponse()
.withStatus(200)
.withBody(
"[{\"pageNumber\":1,\"pageSize\":500,\"platform\":\"aws\",\"query\":\"app1\",\"results\":[],\"totalMatches\":0}]")));

Retrofit2SyncCall.execute(
clouddriverService.search("app1", "securityGroups", "aws", 500, 1, Map.of()));

verify(
1,
getRequestedFor(
urlEqualTo("/search?q=app1&type=securityGroups&platform=aws&pageSize=500&page=1")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ImageService {
Retrofit2SyncCall.execute(clouddriverServiceSelector.select().getImageDetails(provider, account, region, imageId))
}

List<Map> search(String provider, String query, String region, String account, Integer count, Map<String, Object> additionalFilters, String selectorKey) {
List<Map> search(String provider, String query, String region, String account, Integer count, Map<String, String> additionalFilters, String selectorKey) {
Retrofit2SyncCall.execute(clouddriverServiceSelector.select().findImages(provider, query, region, account, count, additionalFilters))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class ServiceBrokerService {

public List<Map> listServices(String cloudProvider, String region, String account) {
return Retrofit2SyncCall.execute(
this.clouddriverService.listServices(cloudProvider, region, account));
this.clouddriverService.listServices(account, cloudProvider, region));
}

public Map getServiceInstance(
Expand Down

0 comments on commit bdf8922

Please sign in to comment.