Skip to content

Commit

Permalink
Test Geocoder with Google maps mock API if GOOGLE_GEOCODER_API_KEY is…
Browse files Browse the repository at this point in the history
… not provided fixes apache#1860
  • Loading branch information
zbendhiba committed Oct 7, 2020
1 parent d13f6cc commit a694a73
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 14 deletions.
Expand Up @@ -50,6 +50,7 @@ List<ReflectiveClassBuildItem> registerReflectiveClasses() {
items.add(new ReflectiveClassBuildItem(false, true, "com.google.maps.model.Bounds"));
items.add(new ReflectiveClassBuildItem(false, true, "com.google.maps.model.LatLng"));
items.add(new ReflectiveClassBuildItem(false, true, "com.google.maps.model.LocationType"));
items.add(new ReflectiveClassBuildItem(false, true, "com.google.maps.GeoApiContext$Builder"));
return items;
}
}
10 changes: 10 additions & 0 deletions integration-tests/geocoder/pom.xml
Expand Up @@ -57,6 +57,16 @@
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>

<!-- dependencies needed to mock Google maps API -->
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-platform-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-test-support-mock-backend</artifactId>
</dependency>


<!-- test dependencies -->
<dependency>
Expand Down
Expand Up @@ -31,45 +31,43 @@

@Path("/google")
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
public class GeocoderGoogleResource {
private static final Logger LOG = Logger.getLogger(GeocoderGoogleResource.class);

@Inject
ProducerTemplate producerTemplate;

@ConfigProperty(name = "google.api.key")
String apiKey;
@ConfigProperty(name = "google.api.key", defaultValue = "AIzaFakeKey")
String googleApiKey;

@GET
@Produces(MediaType.APPLICATION_JSON)
public GeocodingResult[] getByCurrentLocation() {
LOG.infof("Retrieve info from current location");
final GeocodingResult[] response = producerTemplate.requestBody(
"geocoder:address:current?headersOnly=false&apiKey=" + apiKey,
String.format("geocoder:address:current?apiKey=%s", googleApiKey),
"Hello World", GeocodingResult[].class);
LOG.infof("Response : %s", response);
return response;
}

@Path("address/{address}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public GeocodingResult[] getByAddress(@PathParam("address") String address) {
LOG.infof("Retrieve info from address : %s", address);
final GeocodingResult[] response = producerTemplate.requestBody(
"geocoder:address:" + address + "?apiKey=" + apiKey,
String.format("geocoder:address:%s?apiKey=%s", address, googleApiKey),
"Hello World", GeocodingResult[].class);
LOG.infof("Response: %s", response);
return response;
}

@Path("lat/{lat}/lon/{lon}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public GeocodingResult[] getByCoordinate(@PathParam("lat") String latitude, @PathParam("lon") String longitude) {
LOG.infof("Retrieve info from georgraphic coordinates latitude : %s, longitude %s", latitude, longitude);
final GeocodingResult[] response = producerTemplate.requestBody(
"geocoder:latlng:" + latitude + "," + longitude + "?apiKey=" + apiKey,
String.format("geocoder:latlng:%s,%s?apiKey=%s", latitude, longitude, googleApiKey),
"Hello World", GeocodingResult[].class);
LOG.infof("Response : %s", response);
return response;
Expand Down
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.camel.quarkus.component.geocoder.it;

import java.lang.reflect.Field;

import javax.enterprise.context.ApplicationScoped;

import com.google.maps.GeoApiContext;

@ApplicationScoped
public class MockApiService {

public GeoApiContext createGeoApiContext(String baseUri, String apiKey)
throws IllegalAccessException, InstantiationException, NoSuchFieldException {
GeoApiContext.Builder builder = createGeoApiContext(baseUri);
builder.apiKey(apiKey);
return builder.build();
}

/**
* Creates a Builder and sets a new baseUrl for mock with reflection, because it is impossible to set it differently!
*
* @param baseUrl
* @return
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchFieldException
*/
public GeoApiContext.Builder createGeoApiContext(String baseUrl)
throws IllegalAccessException, InstantiationException, NoSuchFieldException {
Class<?> clazz = GeoApiContext.Builder.class;
Object builder = clazz.newInstance();

Field f1 = builder.getClass().getDeclaredField("baseUrlOverride");
f1.setAccessible(true);
f1.set(builder, baseUrl);
return (GeoApiContext.Builder) builder;
}
}
@@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.camel.quarkus.component.geocoder.it;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;

import io.quarkus.arc.Unremovable;
import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.geocoder.GeoCoderComponent;
import org.apache.camel.quarkus.test.mock.backend.MockBackendUtils;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped
public class Routes extends RouteBuilder {

@ConfigProperty(name = "google.api.key")
String googleApiKey;
@ConfigProperty(name = "quarkus.http.test-port")
int httpTestPort;
@ConfigProperty(name = "quarkus.http.port")
int httpPort;
@Inject
MockApiService mockApiService;

private String getBaseUri() {
final boolean isNativeMode = "executable".equals(System.getProperty("org.graalvm.nativeimage.kind"));
return "AIzaFakeKey".equals(googleApiKey)
? "http://localhost:" + (isNativeMode ? httpPort : httpTestPort)
: "https://maps.googleapis.com";
}

/**
* We need to implement some conditional configuration of the {@link GeoCoderComponent} thus we create it
* programmatically and publish via CDI.
*
* @return a configured {@link GeoCoderComponent}
*/
@Produces
@ApplicationScoped
@Unremovable
@Named("geocoder")
GeoCoderComponent geocoderComponent() throws IllegalAccessException, NoSuchFieldException, InstantiationException {
final GeoCoderComponent result = new GeoCoderComponent();
result.setCamelContext(getContext());
result.setGeoApiContext(mockApiService.createGeoApiContext(getBaseUri(), googleApiKey));
return result;
}

@Override
public void configure() throws Exception {
if (MockBackendUtils.startMockBackend(true)) {
from("platform-http:///maps/api/geocode/json?httpMethodRestrict=GET")
.process(e -> load(createMockGeocodeResponse(), e));
from("platform-http:///geolocation/v1/geolocate?httpMethodRestrict=POST")
.process(e -> load(createMockGeolocateResponse(), e));
}
}

private String createMockGeolocateResponse() {
return "{\n" +
" \"location\": {\n" +
" \"lat\": 71.5388001,\n" +
" \"lng\": -66.885417\n" +
" },\n" +
" \"accuracy\": 578963\n" +
"} ";
}

private String createMockGeocodeResponse() {
return "{\n"
+ " \"results\" : [\n"
+ " {\n"
+ " \"address_components\" : [\n"
+ " {\n"
+ " \"long_name\" : \"1600\",\n"
+ " \"short_name\" : \"1600\",\n"
+ " \"types\" : [ \"street_number\" ]\n"
+ " }\n"
+ " ],\n"
+ " \"formatted_address\" : \"1600 Amphitheatre Parkway, Mountain View, "
+ "CA 94043, USA\",\n"
+ " \"geometry\" : {\n"
+ " \"location\" : {\n"
+ " \"lat\" : 37.4220033,\n"
+ " \"lng\" : -122.0839778\n"
+ " },\n"
+ " \"location_type\" : \"ROOFTOP\",\n"
+ " \"viewport\" : {\n"
+ " \"northeast\" : {\n"
+ " \"lat\" : 37.4233522802915,\n"
+ " \"lng\" : -122.0826288197085\n"
+ " },\n"
+ " \"southwest\" : {\n"
+ " \"lat\" : 37.4206543197085,\n"
+ " \"lng\" : -122.0853267802915\n"
+ " }\n"
+ " }\n"
+ " },\n"
+ " \"types\" : [ \"street_address\" ]\n"
+ " }\n"
+ " ],\n"
+ " \"status\" : \"OK\"\n"
+ "}";

}

private void load(String response, Exchange exchange) {
exchange.getMessage().setBody(response);
}

}
Expand Up @@ -19,6 +19,10 @@
################################
#### properties for Google maps services
# add your API KEY to run the examples
google.api.key={{env.GOOGLE_API_KEY}}
google.api.key=${GOOGLE_API_KEY:AIzaFakeKey}

# You may want to export CAMEL_QUARKUS_START_MOCK_BACKEND=false to avoid starting he the mock Google Maps API
# to make sure that you test against the real remote Google Maps API
camel.quarkus.start-mock-backend=true


Expand Up @@ -17,10 +17,7 @@
package org.apache.camel.quarkus.component.geocoder.it;

import io.quarkus.test.junit.NativeImageTest;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;

@NativeImageTest
@EnabledIfEnvironmentVariable(named = "GOOGLE_API_KEY", matches = ".+")
class GeocoderGoogleIT extends GeocoderGoogleTest {

}
Expand Up @@ -20,13 +20,11 @@
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;

import static org.hamcrest.Matchers.hasKey;

@QuarkusTest
@TestHTTPEndpoint(GeocoderGoogleResource.class)
@EnabledIfEnvironmentVariable(named = "GOOGLE_API_KEY", matches = ".+")
class GeocoderGoogleTest {

@Test
Expand Down

0 comments on commit a694a73

Please sign in to comment.