This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 4e58ebded8f Google Spreadsheets tests refactoring (#8788) 4e58ebded8f is described below commit 4e58ebded8f09cbcb4f3bfb089692f6a1ca74109 Author: Vladimir V. Bychkov <git...@bychkov.name> AuthorDate: Wed Nov 30 19:14:15 2022 +0100 Google Spreadsheets tests refactoring (#8788) --- camel-dependencies/pom.xml | 1 - .../camel-google/camel-google-sheets/pom.xml | 76 ----- .../sheets/BatchGoogleSheetsClientFactory.java | 7 +- .../sheets/AbstractGoogleSheetsTestSupport.java | 131 ++------ .../sheets/MockGoogleSheetsClientFactory.java | 60 ++++ .../google/sheets/SheetsSpreadsheetsIT.java | 208 ++++++------ .../google/sheets/SheetsSpreadsheetsValuesIT.java | 358 ++++++++++---------- .../sheets/server/GoogleSheetsApiTestServer.java | 353 -------------------- .../server/GoogleSheetsApiTestServerAssert.java | 365 --------------------- .../server/GoogleSheetsApiTestServerRule.java | 99 ------ .../AbstractGoogleSheetsStreamTestSupport.java | 43 +-- .../SheetsStreamConsumerIntegrationTest.java | 252 +++++++------- .../src/test/resources/googleapis.jks | Bin 2695 -> 0 bytes .../src/test/resources/test-options.properties | 30 -- parent/pom.xml | 1 - 15 files changed, 530 insertions(+), 1454 deletions(-) diff --git a/camel-dependencies/pom.xml b/camel-dependencies/pom.xml index 34a8969cf4b..b5732bbbda1 100644 --- a/camel-dependencies/pom.xml +++ b/camel-dependencies/pom.xml @@ -117,7 +117,6 @@ <cglib-version>3.2.12</cglib-version> <checkstyle.failOnViolation>false</checkstyle.failOnViolation> <chunk-templates-version>3.6.2</chunk-templates-version> - <citrus-version>2.8.0</citrus-version> <classgraph-version>4.8.151</classgraph-version> <cmis-version>1.1.0</cmis-version> <cobertura-maven-plugin-version>2.7</cobertura-maven-plugin-version> diff --git a/components/camel-google/camel-google-sheets/pom.xml b/components/camel-google/camel-google-sheets/pom.xml index bb4d1e395de..0622f8b34f5 100644 --- a/components/camel-google/camel-google-sheets/pom.xml +++ b/components/camel-google/camel-google-sheets/pom.xml @@ -38,54 +38,8 @@ <componentPackage>org.apache.camel.component.google.sheets</componentPackage> <outPackage>org.apache.camel.component.google.sheets.internal</outPackage> <camel.osgi.private.pkg>org.apache.camel.component.google.sheets.internal</camel.osgi.private.pkg> - <spring-security-oauth2-version>2.3.6.RELEASE</spring-security-oauth2-version> </properties> - <dependencyManagement> - <dependencies> - <!-- Test dependencies --> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-webmvc</artifactId> - <version>${spring-version}</version> - </dependency> - <dependency> - <groupId>org.springframework.security</groupId> - <artifactId>spring-security-web</artifactId> - <version>${spring-security-version}</version> - </dependency> - <dependency> - <groupId>org.springframework.security.oauth</groupId> - <artifactId>spring-security-oauth2</artifactId> - <version>${spring-security-oauth2-version}</version> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-core</artifactId> - <version>${citrus-version}</version> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>com.google.code.findbugs</groupId> - <artifactId>jsr305</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-java-dsl</artifactId> - <version>${citrus-version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-http</artifactId> - <version>${citrus-version}</version> - <scope>test</scope> - </dependency> - </dependencies> - </dependencyManagement> - <dependencies> <dependency> <groupId>org.apache.camel</groupId> @@ -152,41 +106,11 @@ <artifactId>camel-mock</artifactId> <scope>test</scope> </dependency> - <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> - <scope>test</scope> - </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <scope>test</scope> </dependency> - <dependency> - <groupId>org.springframework.security</groupId> - <artifactId>spring-security-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.springframework.security.oauth</groupId> - <artifactId>spring-security-oauth2</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-core</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-java-dsl</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>com.consol.citrus</groupId> - <artifactId>citrus-http</artifactId> - <scope>test</scope> - </dependency> </dependencies> <build> diff --git a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java index bfd585bdf8e..231933037a1 100644 --- a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java +++ b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java @@ -23,6 +23,7 @@ import com.google.api.client.auth.oauth2.Credential; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.sheets.v4.Sheets; import org.apache.camel.CamelContext; @@ -33,7 +34,7 @@ import org.apache.camel.util.ObjectHelper; public class BatchGoogleSheetsClientFactory implements GoogleSheetsClientFactory { private final HttpTransport transport; - private final JacksonFactory jsonFactory; + private final JsonFactory jsonFactory; public BatchGoogleSheetsClientFactory() { this(new NetHttpTransport(), new JacksonFactory()); @@ -43,9 +44,9 @@ public class BatchGoogleSheetsClientFactory implements GoogleSheetsClientFactory this(httpTransport, new JacksonFactory()); } - public BatchGoogleSheetsClientFactory(HttpTransport httpTransport, JacksonFactory jacksonFactory) { + public BatchGoogleSheetsClientFactory(HttpTransport httpTransport, JsonFactory jsonFactory) { this.transport = httpTransport; - this.jsonFactory = jacksonFactory; + this.jsonFactory = jsonFactory; } @Override diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/AbstractGoogleSheetsTestSupport.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/AbstractGoogleSheetsTestSupport.java index 52e9c006946..9662dcaa752 100644 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/AbstractGoogleSheetsTestSupport.java +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/AbstractGoogleSheetsTestSupport.java @@ -16,76 +16,42 @@ */ package org.apache.camel.component.google.sheets; -import java.io.IOException; import java.security.SecureRandom; -import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import java.util.Properties; +import java.util.UUID; import com.google.api.services.sheets.v4.model.Sheet; import com.google.api.services.sheets.v4.model.SheetProperties; import com.google.api.services.sheets.v4.model.Spreadsheet; import com.google.api.services.sheets.v4.model.SpreadsheetProperties; -import com.google.api.services.sheets.v4.model.ValueRange; import org.apache.camel.CamelContext; import org.apache.camel.CamelExecutionException; -import org.apache.camel.RuntimeCamelException; -import org.apache.camel.component.google.sheets.internal.GoogleSheetsConstants; -import org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServer; -import org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerRule; -import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.Component; import org.apache.camel.test.junit5.CamelTestSupport; import org.junit.jupiter.api.TestInstance; -import org.junit.jupiter.api.extension.RegisterExtension; /** * Abstract base class for GoogleSheets Integration tests generated by Camel API component maven plugin. */ @TestInstance(TestInstance.Lifecycle.PER_METHOD) -public class AbstractGoogleSheetsTestSupport extends CamelTestSupport { +public abstract class AbstractGoogleSheetsTestSupport extends CamelTestSupport { protected static final String TEST_SHEET = "TestData"; - private static final String TEST_OPTIONS_PROPERTIES = "/test-options.properties"; - - @RegisterExtension - protected GoogleSheetsApiTestServerRule googleSheetsApiTestServerRule - = new GoogleSheetsApiTestServerRule(TEST_OPTIONS_PROPERTIES); + protected static final String TEST_RANGE = TEST_SHEET + "!A1:B2"; private Spreadsheet spreadsheet; - private static Properties loadProperties() { - // read GoogleMail component configuration from TEST_OPTIONS_PROPERTIES - final Properties properties = new Properties(); - try { - properties.load(AbstractGoogleSheetsTestSupport.class.getResourceAsStream(TEST_OPTIONS_PROPERTIES)); - } catch (Exception e) { - throw new RuntimeCamelException( - String.format("%s could not be loaded: %s", TEST_OPTIONS_PROPERTIES, e.getMessage()), e); - } - return properties; - } - - // Used by JUnit to determine whether or not to run the integration tests - @SuppressWarnings("unused") - private static boolean hasCredentials() { - Properties properties = loadProperties(); - - return !properties.getProperty("clientId", "").isEmpty() - && !properties.getProperty("clientSecret", "").isEmpty() - && !properties.getProperty("accessToken", "").isEmpty() - || !properties.getProperty("serviceAccountKey", "").isEmpty(); - } - /** * Create test spreadsheet that is used throughout all tests. */ private void createTestSpreadsheet() { Spreadsheet spreadsheet = new Spreadsheet(); + spreadsheet.setFactory(MockGoogleSheetsClientFactory.JSON_FACTORY); + spreadsheet.setSpreadsheetId(UUID.randomUUID().toString()); + SpreadsheetProperties spreadsheetProperties = new SpreadsheetProperties(); spreadsheetProperties.setTitle("camel-sheets-" + new SecureRandom().nextInt(Integer.MAX_VALUE)); - spreadsheet.setProperties(spreadsheetProperties); Sheet sheet = new Sheet(); @@ -95,30 +61,7 @@ public class AbstractGoogleSheetsTestSupport extends CamelTestSupport { spreadsheet.setSheets(Collections.singletonList(sheet)); - this.spreadsheet = requestBody("google-sheets://spreadsheets/create?inBody=content", spreadsheet); - } - - /** - * Add some initial test data to test spreadsheet. - */ - private void createTestData() { - if (spreadsheet == null) { - createTestSpreadsheet(); - } - - ValueRange valueRange = new ValueRange(); - valueRange.setValues(Arrays.asList(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"))); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", spreadsheet.getSpreadsheetId()); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_SHEET + "!A1:B2"); - - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "valueInputOption", "USER_ENTERED"); - - requestBodyAndHeaders("google-sheets://data/update?inBody=values", valueRange, headers); + this.spreadsheet = spreadsheet; } @Override @@ -126,46 +69,28 @@ public class AbstractGoogleSheetsTestSupport extends CamelTestSupport { final CamelContext context = super.createCamelContext(); - final Properties properties = loadProperties(); - - Map<String, Object> options = new HashMap<>(); - for (Map.Entry<Object, Object> entry : properties.entrySet()) { - options.put(entry.getKey().toString(), entry.getValue()); - } - - final GoogleSheetsConfiguration configuration = new GoogleSheetsConfiguration(); - PropertyBindingSupport.bindProperties(context, configuration, options); - - // add GoogleSheetsComponent to Camel context and use localhost url - final GoogleSheetsComponent component = new GoogleSheetsComponent(context); - component.setConfiguration(configuration); - context.addComponent("google-sheets", component); + Component component = getComponent(context); + context.addComponent(getComponentName(), component); return context; } - /** - * Read component configuration from TEST_OPTIONS_PROPERTIES. - * - * @return Map of component options. - * @throws IOException when TEST_OPTIONS_PROPERTIES could not be loaded. - */ - protected Map<String, Object> getTestOptions() throws IOException { - final Properties properties = new Properties(); - try { - properties.load(getClass().getResourceAsStream(TEST_OPTIONS_PROPERTIES)); - } catch (Exception e) { - throw new IOException(String.format("%s could not be loaded: %s", TEST_OPTIONS_PROPERTIES, e.getMessage()), e); - } + protected Component getComponent(CamelContext context) throws Exception { + GoogleSheetsConfiguration configuration = new GoogleSheetsConfiguration(); + configuration.setServiceAccountKey("mock"); - Map<String, Object> options = new HashMap<>(); - for (Map.Entry<Object, Object> entry : properties.entrySet()) { - options.put(entry.getKey().toString(), entry.getValue()); - } + GoogleSheetsComponent component = new GoogleSheetsComponent(context); + component.setConfiguration(configuration); + component.setClientFactory(getClientFactory()); + return component; + } - return options; + protected String getComponentName() { + return "google-sheets"; } + protected abstract GoogleSheetsClientFactory getClientFactory() throws Exception; + @SuppressWarnings("unchecked") protected <T> T requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) throws CamelExecutionException { @@ -184,16 +109,4 @@ public class AbstractGoogleSheetsTestSupport extends CamelTestSupport { return spreadsheet; } - public Spreadsheet applyTestData(Spreadsheet spreadsheet) { - createTestData(); - return spreadsheet; - } - - public void setSpreadsheet(Spreadsheet sheet) { - this.spreadsheet = sheet; - } - - public GoogleSheetsApiTestServer getGoogleApiTestServer() { - return googleSheetsApiTestServerRule.getGoogleApiTestServer(); - } } diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/MockGoogleSheetsClientFactory.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/MockGoogleSheetsClientFactory.java new file mode 100644 index 00000000000..f300ecd56fd --- /dev/null +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/MockGoogleSheetsClientFactory.java @@ -0,0 +1,60 @@ +/* + * 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.component.google.sheets; + +import java.util.Collection; + +import com.google.api.client.auth.oauth2.Credential; +import com.google.api.client.googleapis.testing.auth.oauth2.MockGoogleCredential; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.client.testing.http.MockHttpTransport; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; +import com.google.api.services.sheets.v4.Sheets; +import org.apache.camel.CamelContext; + +public class MockGoogleSheetsClientFactory implements GoogleSheetsClientFactory { + + public static final JsonFactory JSON_FACTORY = new JacksonFactory(); + + private final HttpTransport transport; + + public MockGoogleSheetsClientFactory(MockLowLevelHttpResponse lowLevelHttpResponse) { + transport = new MockHttpTransport.Builder().setLowLevelHttpResponse(lowLevelHttpResponse).build(); + } + + @Override + public Sheets makeClient( + CamelContext camelContext, String serviceAccountKey, Collection<String> scopes, + String applicationName, String delegate) { + return makeClient(); + } + + @Override + public Sheets makeClient( + String clientId, String clientSecret, Collection<String> scopes, String applicationName, + String refreshToken, String accessToken) { + return makeClient(); + } + + private Sheets makeClient() { + Credential credential = new MockGoogleCredential.Builder().build(); + return new Sheets.Builder(transport, JSON_FACTORY, credential).setApplicationName("mock").build(); + } + +} diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsIT.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsIT.java index 78dc59eb5cf..ed2f8cbb9cb 100644 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsIT.java +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsIT.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest; import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetResponse; import com.google.api.services.sheets.v4.model.Request; @@ -32,121 +33,134 @@ import org.apache.camel.component.google.sheets.internal.GoogleSheetsApiCollecti import org.apache.camel.component.google.sheets.internal.GoogleSheetsConstants; import org.apache.camel.component.google.sheets.internal.SheetsSpreadsheetsApiMethod; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerAssert.assertThatGoogleApi; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; /** * Test class for {@link com.google.api.services.sheets.v4.Sheets.Spreadsheets} APIs. */ -@EnabledIf(value = "org.apache.camel.component.google.sheets.AbstractGoogleSheetsTestSupport#hasCredentials", - disabledReason = "Google Sheets credentials were not provided") -public class SheetsSpreadsheetsIT extends AbstractGoogleSheetsTestSupport { +public class SheetsSpreadsheetsIT { private static final Logger LOG = LoggerFactory.getLogger(SheetsSpreadsheetsIT.class); private static final String PATH_PREFIX = GoogleSheetsApiCollection.getCollection().getApiName(SheetsSpreadsheetsApiMethod.class).getName(); - @Test - public void testCreate() { - String title = "camel-sheets-" + new SecureRandom().nextInt(Integer.MAX_VALUE); - Spreadsheet sheetToCreate = new Spreadsheet(); - SpreadsheetProperties sheetProperties = new SpreadsheetProperties(); - sheetProperties.setTitle(title); - - sheetToCreate.setProperties(sheetProperties); - - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasTitle(title) - .andReturnRandomSpreadsheet(); - - final Spreadsheet result = requestBody("direct://CREATE", sheetToCreate); - - assertNotNull(result, "create result is null"); - assertEquals(title, result.getProperties().getTitle()); - - LOG.debug("create: " + result); + public static class CreateTest extends AbstractGoogleSheetsTestSupport { + private String title = "camel-sheets-" + new SecureRandom().nextInt(Integer.MAX_VALUE); + + @Test + public void test() { + Spreadsheet sheetToCreate = new Spreadsheet(); + SpreadsheetProperties sheetProperties = new SpreadsheetProperties(); + sheetProperties.setTitle(title); + + sheetToCreate.setProperties(sheetProperties); + + final Spreadsheet result = requestBody("direct://CREATE", sheetToCreate); + + assertNotNull(result, "create result is null"); + assertEquals(title, result.getProperties().getTitle()); + + LOG.debug("create: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse().setContent("{\"properties\":{\"title\":\"" + title + "\"}}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://CREATE") + .to("google-sheets://" + PATH_PREFIX + "/create?inBody=content"); + } + }; + } } - @Test - public void testGet() throws Exception { - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnRandomSpreadsheet(); - - Spreadsheet testSheet = getSpreadsheet(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .getSpreadsheetRequest(testSheet.getSpreadsheetId()) - .andReturnSpreadsheet(testSheet); - - // using String message body for single parameter "spreadsheetId" - final Spreadsheet result = requestBody("direct://GET", testSheet.getSpreadsheetId()); - - assertNotNull(result, "get result is null"); - assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); - - LOG.debug("get: " + result); + public static class GetTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + + @Test + public void test() throws Exception { + final Spreadsheet result = requestBody("direct://GET", testSheet.getSpreadsheetId()); + + assertNotNull(result, "get result is null"); + assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); + + LOG.debug("get: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory(new MockLowLevelHttpResponse().setContent(testSheet.toPrettyString())); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://GET") + .to("google-sheets://" + PATH_PREFIX + "/get?inBody=spreadsheetId"); + } + }; + } } - @Test - public void testBatchUpdate() { - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnRandomSpreadsheet(); - - Spreadsheet testSheet = getSpreadsheet(); - String updateTitle = "updated-" + testSheet.getProperties().getTitle(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .batchUpdateSpreadsheetRequest(testSheet.getSpreadsheetId()) - .updateTitle(updateTitle) - .andReturnUpdated(); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); - // parameter type is com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "batchUpdateSpreadsheetRequest", new BatchUpdateSpreadsheetRequest() - .setIncludeSpreadsheetInResponse(true) - .setRequests(Collections - .singletonList(new Request().setUpdateSpreadsheetProperties(new UpdateSpreadsheetPropertiesRequest() - .setProperties(new SpreadsheetProperties().setTitle(updateTitle)) - .setFields("title"))))); - - final BatchUpdateSpreadsheetResponse result = requestBodyAndHeaders("direct://BATCHUPDATE", null, headers); - - assertNotNull(result, "batchUpdate result is null"); - assertEquals(updateTitle, result.getUpdatedSpreadsheet().getProperties().getTitle()); - - LOG.debug("batchUpdate: " + result); + public static class BatchUpdateTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + private String updateTitle = "updated-" + testSheet.getProperties().getTitle(); + + @Test + public void test() { + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); + // parameter type is com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "batchUpdateSpreadsheetRequest", + new BatchUpdateSpreadsheetRequest() + .setIncludeSpreadsheetInResponse(true) + .setRequests(Collections + .singletonList(new Request() + .setUpdateSpreadsheetProperties(new UpdateSpreadsheetPropertiesRequest() + .setProperties(new SpreadsheetProperties().setTitle(updateTitle)) + .setFields("title"))))); + + final BatchUpdateSpreadsheetResponse result = requestBodyAndHeaders("direct://BATCHUPDATE", null, headers); + + assertNotNull(result, "batchUpdate result is null"); + assertEquals(updateTitle, result.getUpdatedSpreadsheet().getProperties().getTitle()); + + LOG.debug("batchUpdate: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent("{\"spreadsheetId\":\"" + testSheet.getSpreadsheetId() + + "\",\"updatedSpreadsheet\":{\"properties\":{\"title\":\"" + updateTitle + + "\"},\"spreadsheetId\":\"" + testSheet.getSpreadsheetId() + "\"}}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://BATCHUPDATE") + .to("google-sheets://" + PATH_PREFIX + "/batchUpdate"); + } + }; + } } - @Override - protected RouteBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - // test route for batchUpdate - from("direct://BATCHUPDATE") - .to("google-sheets://" + PATH_PREFIX + "/batchUpdate"); - - // test route for create - from("direct://CREATE") - .to("google-sheets://" + PATH_PREFIX + "/create?inBody=content"); - - // test route for get - from("direct://GET") - .to("google-sheets://" + PATH_PREFIX + "/get?inBody=spreadsheetId"); - - } - }; - } } diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsValuesIT.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsValuesIT.java index f6a10e8ffe0..7c283c4b489 100644 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsValuesIT.java +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/SheetsSpreadsheetsValuesIT.java @@ -17,12 +17,14 @@ package org.apache.camel.component.google.sheets; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; +import java.util.Optional; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; import com.google.api.services.sheets.v4.model.AppendValuesResponse; import com.google.api.services.sheets.v4.model.ClearValuesRequest; import com.google.api.services.sheets.v4.model.ClearValuesResponse; @@ -35,11 +37,9 @@ import org.apache.camel.component.google.sheets.internal.GoogleSheetsConstants; import org.apache.camel.component.google.sheets.internal.SheetsSpreadsheetsValuesApiMethod; import org.apache.camel.util.ObjectHelper; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerAssert.assertThatGoogleApi; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -47,181 +47,209 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** * Test class for {@link com.google.api.services.sheets.v4.Sheets.Spreadsheets.Values} APIs. */ -@EnabledIf(value = "org.apache.camel.component.google.sheets.AbstractGoogleSheetsTestSupport#hasCredentials", - disabledReason = "Google Sheets credentials were not provided") -public class SheetsSpreadsheetsValuesIT extends AbstractGoogleSheetsTestSupport { +public class SheetsSpreadsheetsValuesIT { private static final Logger LOG = LoggerFactory.getLogger(SheetsSpreadsheetsValuesIT.class); private static final String PATH_PREFIX = GoogleSheetsApiCollection.getCollection().getApiName(SheetsSpreadsheetsValuesApiMethod.class).getName(); - @Test - public void testGet() throws Exception { - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnRandomSpreadsheet(); - - Spreadsheet testSheet = getSpreadsheet(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .getValuesRequest(testSheet.getSpreadsheetId(), TEST_SHEET + "!A1:B2") - .andReturnValues(Collections.emptyList()); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_SHEET + "!A1:B2"); - - final ValueRange result = requestBodyAndHeaders("direct://GET", null, headers); - - assertNotNull(result, "get result is null"); - assertEquals(TEST_SHEET + "!A1:B2", result.getRange()); - assertTrue(ObjectHelper.isEmpty(result.getValues()), "expected empty value range but found entries"); - - LOG.debug("get: " + result); + public static class GetTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + + @Test + public void test() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_RANGE); + + final ValueRange result = requestBodyAndHeaders("direct://GET", null, headers); + + assertNotNull(result, "get result is null"); + assertEquals(TEST_RANGE, result.getRange()); + assertTrue(ObjectHelper.isEmpty(result.getValues()), "expected empty value range but found entries"); + + LOG.debug("get: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent("{" + "\"range\": \"" + TEST_RANGE + "\"," + "\"majorDimension\": \"ROWS\"" + "}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://GET") + .to("google-sheets://" + PATH_PREFIX + "/get"); + } + }; + } } - @Test - public void testUpdate() throws Exception { - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnRandomSpreadsheet(); - - Spreadsheet testSheet = getSpreadsheet(); - - List<List<Object>> data = Arrays.asList( + public static class UpdateTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + private String range = "TEST_SHEET!A1:B2"; + private List<List<Object>> data = Arrays.asList( Arrays.asList("A1", "B1"), Arrays.asList("A2", "B2")); - assertThatGoogleApi(getGoogleApiTestServer()) - .updateValuesRequest(testSheet.getSpreadsheetId(), TEST_SHEET + "!A1:B2", data) - .andReturnUpdateResponse(); - - ValueRange values = new ValueRange(); - values.setValues(data); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_SHEET + "!A1:B2"); - // parameter type is com.google.api.services.sheets.v4.model.ValueRange - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "values", values); - - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "valueInputOption", "USER_ENTERED"); - - final UpdateValuesResponse result = requestBodyAndHeaders("direct://UPDATE", null, headers); - - assertNotNull(result, "update result is null"); - assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); - assertEquals(TEST_SHEET + "!A1:B2", result.getUpdatedRange()); - assertEquals(Integer.valueOf(2), result.getUpdatedRows()); - assertEquals(Integer.valueOf(4), result.getUpdatedCells()); - - LOG.debug("update: " + result); + @Test + public void test() throws Exception { + + ValueRange values = new ValueRange(); + values.setValues(data); + + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", range); + // parameter type is com.google.api.services.sheets.v4.model.ValueRange + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "values", values); + + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "valueInputOption", "USER_ENTERED"); + + final UpdateValuesResponse result = requestBodyAndHeaders("direct://UPDATE", null, headers); + + assertNotNull(result, "update result is null"); + assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); + assertEquals(range, result.getUpdatedRange()); + assertEquals(data.size(), result.getUpdatedRows()); + assertEquals(data.size() * data.get(0).size(), result.getUpdatedCells()); + + LOG.debug("update: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent("{" + "\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + + "\"updatedRange\": \"" + range + "\"," + "\"updatedRows\": " + + data.size() + "," + "\"updatedColumns\": " + + Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + "," + + "\"updatedCells\": " + + data.size() + * Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + + "}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://UPDATE") + .to("google-sheets://" + PATH_PREFIX + "/update"); + } + }; + } } - @Test - public void testAppend() throws Exception { - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnRandomSpreadsheet(); - - Spreadsheet testSheet = getSpreadsheet(); - - List<List<Object>> data = Collections.singletonList(Arrays.asList("A10", "B10", "C10")); - - assertThatGoogleApi(getGoogleApiTestServer()) - .appendValuesRequest(testSheet.getSpreadsheetId(), TEST_SHEET + "!A10", data) - .andReturnAppendResponse(TEST_SHEET + "!A10:C10"); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_SHEET + "!A10"); - // parameter type is com.google.api.services.sheets.v4.model.ValueRange - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "values", new ValueRange().setValues(data)); - - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "valueInputOption", "USER_ENTERED"); - - final AppendValuesResponse result = requestBodyAndHeaders("direct://APPEND", null, headers); - - assertNotNull(result, "append result is null"); - assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); - assertEquals(TEST_SHEET + "!A10:C10", result.getUpdates().getUpdatedRange()); - assertEquals(Integer.valueOf(1), result.getUpdates().getUpdatedRows()); - assertEquals(Integer.valueOf(3), result.getUpdates().getUpdatedCells()); - - LOG.debug("append: " + result); - } - - @Test - public void testClear() throws Exception { - String spreadsheetId = UUID.randomUUID().toString(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnSpreadsheet(spreadsheetId); - - Spreadsheet testSheet = getSpreadsheet(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .updateValuesRequest(spreadsheetId, TEST_SHEET + "!A1:B2", - Arrays.asList(Arrays.asList("a1", "b1"), Arrays.asList("a2", "b2"))) - .andReturnUpdateResponse(); - - applyTestData(testSheet); - - assertThatGoogleApi(getGoogleApiTestServer()) - .clearValuesRequest(testSheet.getSpreadsheetId(), TEST_SHEET + "!A1:B2") - .andReturnClearResponse(TEST_SHEET + "!A1:B2"); - - final Map<String, Object> headers = new HashMap<>(); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); - // parameter type is String - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_SHEET + "!A1:B2"); - // parameter type is com.google.api.services.sheets.v4.model.ClearValuesRequest - headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "clearValuesRequest", new ClearValuesRequest()); - - final ClearValuesResponse result = requestBodyAndHeaders("direct://CLEAR", null, headers); - - assertNotNull(result, "clear result is null"); - assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); - assertEquals(TEST_SHEET + "!A1:B2", result.getClearedRange()); - - LOG.debug("clear: " + result); + public static class AppendTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + private List<List<Object>> data = Collections.singletonList(Arrays.asList("A10", "B10", "C10")); + private String range = TEST_SHEET + "!A10"; + private String updateRange = TEST_SHEET + "!" + data.get(0).get(0) + ":" + data.get(0).get(data.get(0).size() - 1); + + @Test + public void test() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", range); + // parameter type is com.google.api.services.sheets.v4.model.ValueRange + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "values", new ValueRange().setValues(data)); + + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "valueInputOption", "USER_ENTERED"); + + final AppendValuesResponse result = requestBodyAndHeaders("direct://APPEND", null, headers); + + assertNotNull(result, "append result is null"); + assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); + assertEquals(updateRange, result.getUpdates().getUpdatedRange()); + assertEquals(data.size(), result.getUpdates().getUpdatedRows()); + assertEquals(data.get(0).size(), result.getUpdates().getUpdatedCells()); + + LOG.debug("append: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent( + "{" + "\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + "\"updates\":" + "{" + + "\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + + "\"updatedRange\": \"" + updateRange + "\"," + "\"updatedRows\": " + + data.size() + "," + "\"updatedColumns\": " + + Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + "," + + "\"updatedCells\": " + + data.size() + * Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + + "}" + "}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://APPEND") + .to("google-sheets://" + PATH_PREFIX + "/append"); + } + }; + } } - @Override - protected RouteBuilder createRouteBuilder() { - return new RouteBuilder() { - @Override - public void configure() { - // test route for append - from("direct://APPEND") - .to("google-sheets://" + PATH_PREFIX + "/append"); - - // test route for clear - from("direct://CLEAR") - .to("google-sheets://" + PATH_PREFIX + "/clear"); - - // test route for get - from("direct://GET") - .to("google-sheets://" + PATH_PREFIX + "/get"); - - // test route for update - from("direct://UPDATE") - .to("google-sheets://" + PATH_PREFIX + "/update"); - } - }; + public static class ClearTest extends AbstractGoogleSheetsTestSupport { + private Spreadsheet testSheet = getSpreadsheet(); + + @Test + public void test() throws Exception { + final Map<String, Object> headers = new HashMap<>(); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "spreadsheetId", testSheet.getSpreadsheetId()); + // parameter type is String + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "range", TEST_RANGE); + // parameter type is com.google.api.services.sheets.v4.model.ClearValuesRequest + headers.put(GoogleSheetsConstants.PROPERTY_PREFIX + "clearValuesRequest", new ClearValuesRequest()); + + final ClearValuesResponse result = requestBodyAndHeaders("direct://CLEAR", null, headers); + + assertNotNull(result, "clear result is null"); + assertEquals(testSheet.getSpreadsheetId(), result.getSpreadsheetId()); + assertEquals(TEST_RANGE, result.getClearedRange()); + + LOG.debug("clear: " + result); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse().setContent( + "{" + "\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + "\"clearedRange\": \"" + + TEST_RANGE + "\"" + "}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from("direct://CLEAR") + .to("google-sheets://" + PATH_PREFIX + "/clear"); + } + }; + } } } diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServer.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServer.java deleted file mode 100644 index 81eaf5cd825..00000000000 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServer.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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.component.google.sheets.server; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import java.util.zip.GZIPInputStream; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ReadListener; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; - -import com.consol.citrus.Citrus; -import com.consol.citrus.dsl.runner.DefaultTestRunner; -import com.consol.citrus.dsl.runner.TestRunner; -import com.consol.citrus.exceptions.CitrusRuntimeException; -import com.consol.citrus.http.server.HttpServer; -import com.consol.citrus.http.server.HttpServerBuilder; -import com.consol.citrus.http.servlet.GzipHttpServletResponseWrapper; -import com.consol.citrus.http.servlet.RequestCachingServletFilter; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; -import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; -import org.springframework.security.oauth2.provider.AuthorizationRequest; -import org.springframework.security.oauth2.provider.ClientDetails; -import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager; -import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter; -import org.springframework.security.oauth2.provider.client.BaseClientDetails; -import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; -import org.springframework.security.oauth2.provider.token.DefaultTokenServices; -import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; -import org.springframework.web.filter.OncePerRequestFilter; - -public final class GoogleSheetsApiTestServer { - - private static Citrus citrus = Citrus.newInstance(); - - private final HttpServer httpServer; - private TestRunner runner; - - /** - * Prevent direct instantiation. - */ - private GoogleSheetsApiTestServer(HttpServer httpServer) { - this.httpServer = httpServer; - } - - /** - * Initialize new test run. - */ - public void init() { - runner = new DefaultTestRunner(citrus.getApplicationContext(), citrus.createTestContext()); - } - - /** - * Stop and reset current test run if any. - */ - public void reset() { - if (runner != null) { - runner.purgeEndpoints(action -> action.endpoint(httpServer)); - runner.stop(); - } - } - - /** - * Obtains the httpServer. - * - * @return - */ - public HttpServer getHttpServer() { - return httpServer; - } - - public void afterPropertiesSet() throws Exception { - httpServer.afterPropertiesSet(); - } - - public TestRunner getRunner() { - return runner; - } - - /** - * Builder builds server instance from given http server builder adding more setting options in fluent builder - * pattern style. - */ - public static class Builder { - private final HttpServerBuilder serverBuilder; - - private Path keyStorePath; - private String keyStorePassword; - private int securePort = 8443; - - private String basePath = ""; - - private String clientId; - private String clientSecret; - - private String accessToken; - private String refreshToken; - - public Builder(HttpServerBuilder serverBuilder) { - this.serverBuilder = serverBuilder; - } - - public Builder securePort(int securePort) { - this.securePort = securePort; - return this; - } - - public Builder keyStorePath(Path keyStorePath) { - this.keyStorePath = keyStorePath; - return this; - } - - public Builder keyStorePassword(String keyStorePass) { - this.keyStorePassword = keyStorePass; - return this; - } - - public Builder basePath(String basePath) { - this.basePath = basePath; - return this; - } - - public Builder clientId(String clientId) { - this.clientId = clientId; - return this; - } - - public Builder clientSecret(String clientSecret) { - this.clientSecret = clientSecret; - return this; - } - - public Builder accessToken(String accessToken) { - this.accessToken = accessToken; - return this; - } - - public Builder refreshToken(String refreshToken) { - this.refreshToken = refreshToken; - return this; - } - - public GoogleSheetsApiTestServer build() throws Exception { - SslContextFactory sslContextFactory = new SslContextFactory(true); - sslContextFactory.setKeyStorePath(keyStorePath.toAbsolutePath().toString()); - sslContextFactory.setKeyStorePassword(keyStorePassword); - - HttpConfiguration parent = new HttpConfiguration(); - parent.setSecureScheme("https"); - parent.setSecurePort(securePort); - HttpConfiguration httpConfiguration = new HttpConfiguration(parent); - httpConfiguration.setCustomizers(Collections.singletonList(new SecureRequestCustomizer())); - - ServerConnector sslConnector = new ServerConnector( - new org.eclipse.jetty.server.Server(), new SslConnectionFactory(sslContextFactory, "http/1.1"), - new HttpConnectionFactory(httpConfiguration)); - sslConnector.setPort(securePort); - - serverBuilder.connector(sslConnector); - - Map<String, Filter> filterMap = new LinkedHashMap<>(); - filterMap.put("request-caching-filter", new RequestCachingServletFilter()); - filterMap.put("gzip-filter", new GzipServletFilter()); - filterMap.put("oauth2-filter", oauth2Filter()); - - Map<String, String> filterMapings = new LinkedHashMap<>(); - filterMapings.put("oauth2-filter", "/" + Optional.ofNullable(basePath).map(path -> path + "/*").orElse("*")); - serverBuilder.filterMappings(filterMapings); - - serverBuilder.filters(filterMap); - - serverBuilder.applicationContext(citrus.getApplicationContext()); - - GoogleSheetsApiTestServer server = new GoogleSheetsApiTestServer(serverBuilder.build()); - server.afterPropertiesSet(); - return server; - } - - private Filter oauth2Filter() { - BaseClientDetails clientDetails = new BaseClientDetails(); - clientDetails.setClientId(clientId); - clientDetails.setClientSecret(clientSecret); - clientDetails.setAccessTokenValiditySeconds(3000); - clientDetails.setAutoApproveScopes(Arrays.asList("read", "write")); - clientDetails.setScope(Arrays.asList("read", "write")); - clientDetails.setAuthorities(Arrays.asList(new SimpleGrantedAuthority("client_credentials"), - new SimpleGrantedAuthority("authorization_code"), - new SimpleGrantedAuthority("password"), new SimpleGrantedAuthority("refresh_token"))); - - OAuth2AuthenticationProcessingFilter filter = new OAuth2AuthenticationProcessingFilter(); - OAuth2AuthenticationManager oauth2AuthenticationManager = new OAuth2AuthenticationManager(); - - InMemoryClientDetailsService clientDetailsService = new InMemoryClientDetailsService(); - Map<String, ClientDetails> clientDetailsStore = new HashMap<>(); - clientDetailsStore.put(clientId, clientDetails); - clientDetailsService.setClientDetailsStore(clientDetailsStore); - oauth2AuthenticationManager.setClientDetailsService(clientDetailsService); - - InMemoryTokenStore tokenStore = new InMemoryTokenStore(); - AuthorizationRequest authorizationRequest = new AuthorizationRequest(); - authorizationRequest.setClientId(clientDetails.getClientId()); - authorizationRequest.setAuthorities(clientDetails.getAuthorities()); - authorizationRequest.setApproved(true); - - OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest.createOAuth2Request(), null); - - tokenStore.storeAccessToken(new DefaultOAuth2AccessToken(accessToken), authentication); - tokenStore.storeRefreshToken(new DefaultOAuth2RefreshToken(refreshToken), authentication); - - DefaultTokenServices tokenServices = new DefaultTokenServices(); - tokenServices.setTokenStore(tokenStore); - tokenServices.setClientDetailsService(clientDetailsService); - tokenServices.setSupportRefreshToken(true); - oauth2AuthenticationManager.setTokenServices(tokenServices); - - filter.setAuthenticationManager(oauth2AuthenticationManager); - return filter; - } - } - - private static class GzipServletFilter extends OncePerRequestFilter { - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - HttpServletRequest filteredRequest = request; - HttpServletResponse filteredResponse = response; - - String contentEncoding = request.getHeader(HttpHeaders.CONTENT_ENCODING); - if (contentEncoding != null && contentEncoding.contains("gzip")) { - filteredRequest = new GzipHttpServletRequestWrapper(request); - } - - String acceptEncoding = request.getHeader(HttpHeaders.ACCEPT_ENCODING); - if (acceptEncoding != null && acceptEncoding.contains("gzip")) { - filteredResponse = new GzipHttpServletResponseWrapper(response); - } - - filterChain.doFilter(filteredRequest, filteredResponse); - - if (filteredResponse instanceof GzipHttpServletResponseWrapper) { - ((GzipHttpServletResponseWrapper) filteredResponse).finish(); - } - } - } - - private static class GzipHttpServletRequestWrapper extends HttpServletRequestWrapper { - /** - * Constructs a request adaptor wrapping the given request. - * - * @param request - * @throws IllegalArgumentException if the request is null - */ - public GzipHttpServletRequestWrapper(HttpServletRequest request) { - super(request); - } - - @Override - public ServletInputStream getInputStream() throws IOException { - return new GzipServletInputStream(getRequest()); - } - - /** - * Gzip enabled servlet input stream. - */ - private static class GzipServletInputStream extends ServletInputStream { - private final GZIPInputStream gzipStream; - - /** - * Default constructor using wrapped input stream. - * - * @param request - * @throws IOException - */ - public GzipServletInputStream(ServletRequest request) throws IOException { - gzipStream = new GZIPInputStream(request.getInputStream()); - } - - @Override - public boolean isFinished() { - try { - return gzipStream.available() == 0; - } catch (IOException e) { - throw new CitrusRuntimeException("Failed to check gzip intput stream availability", e); - } - } - - @Override - public boolean isReady() { - return true; - } - - @Override - public void setReadListener(final ReadListener readListener) { - throw new UnsupportedOperationException("Unsupported operation"); - } - - @Override - public int read() { - try { - return gzipStream.read(); - } catch (IOException e) { - throw new CitrusRuntimeException("Failed to read gzip input stream", e); - } - } - - @Override - public int read(byte[] b) throws IOException { - return gzipStream.read(b); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return gzipStream.read(b, off, len); - } - } - } -} diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerAssert.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerAssert.java deleted file mode 100644 index d9cf1b03cd1..00000000000 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerAssert.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * 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.component.google.sheets.server; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.stream.Collectors; - -import com.consol.citrus.message.MessageType; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.google.api.services.sheets.v4.model.Spreadsheet; -import com.google.api.services.sheets.v4.model.ValueRange; -import org.apache.camel.util.ObjectHelper; -import org.assertj.core.api.AbstractAssert; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; - -public final class GoogleSheetsApiTestServerAssert - extends AbstractAssert<GoogleSheetsApiTestServerAssert, GoogleSheetsApiTestServer> { - - private ObjectMapper mapper = new ObjectMapper() - .setDefaultPropertyInclusion( - JsonInclude.Value.construct(JsonInclude.Include.NON_EMPTY, JsonInclude.Include.NON_EMPTY)) - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) - .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) - .enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING).disable(JsonParser.Feature.AUTO_CLOSE_SOURCE); - - private GoogleSheetsApiTestServerAssert(GoogleSheetsApiTestServer server) { - super(server, GoogleSheetsApiTestServerAssert.class); - } - - /** - * A fluent entry point to the assertion class. - * - * @param server the target server to perform assertions to. - * @return - */ - public static GoogleSheetsApiTestServerAssert assertThatGoogleApi(GoogleSheetsApiTestServer server) { - return new GoogleSheetsApiTestServerAssert(server); - } - - public GetSpreadsheetAssert getSpreadsheetRequest(String spreadsheetId) { - return new GetSpreadsheetAssert(spreadsheetId); - } - - public void isRunning() { - isRunning(5000, TimeUnit.MILLISECONDS); - } - - public void isRunning(long timeout, TimeUnit timeUnit) { - ScheduledFuture<?> schedule = null; - try { - CompletableFuture<Boolean> runningProbe = new CompletableFuture<>(); - schedule = Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { - if (actual.getHttpServer().isRunning()) { - runningProbe.complete(true); - } - }, 0, timeout / 10, timeUnit); - - runningProbe.get(timeout, timeUnit); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - throw new IllegalStateException(e); - } finally { - Optional.ofNullable(schedule).ifPresent(future -> future.cancel(true)); - } - } - - public class GetSpreadsheetAssert { - GetSpreadsheetAssert(String spreadsheetId) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - } - - public void andReturnSpreadsheet(Spreadsheet spreadsheet) throws IOException { - String spreadsheetJson = spreadsheet.toPrettyString(); - actual.getRunner().async() - .actions( - actual.getRunner() - .http(action -> action - .server(actual.getHttpServer()).receive().get("/v4/spreadsheets/${spreadsheetId}")), - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE).payload(spreadsheetJson))); - } - } - - public ClearValuesAssert clearValuesRequest(String spreadsheetId, String range) { - return new ClearValuesAssert(spreadsheetId, range); - } - - public class ClearValuesAssert { - ClearValuesAssert(String spreadsheetId, String range) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("range", range); - } - - public void andReturnClearResponse(String clearedRange) { - actual.getRunner().async() - .actions( - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .post("/v4/spreadsheets/${spreadsheetId}/values/${range}:clear")), - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .payload("{" + "\"spreadsheetId\": \"${spreadsheetId}\"," + "\"clearedRange\": \"" - + clearedRange + "\"" + "}"))); - } - } - - public UpdateValuesAssert updateValuesRequest(String spreadsheetId, String range, List<List<Object>> data) { - return new UpdateValuesAssert(spreadsheetId, range, data); - } - - public class UpdateValuesAssert { - private final List<List<Object>> data; - - UpdateValuesAssert(String spreadsheetId, String range, List<List<Object>> data) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("range", range); - this.data = data; - } - - public void andReturnUpdateResponse() throws IOException { - String valuesJson = mapper.writer().writeValueAsString(data); - - actual - .getRunner().async().actions( - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .put("/v4/spreadsheets/${spreadsheetId}/values/${range}") - .validate("$.values.toString()", valuesJson)), - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .payload("{" + "\"spreadsheetId\": \"${spreadsheetId}\"," - + "\"updatedRange\": \"${range}\"," + "\"updatedRows\": " - + data.size() + "," + "\"updatedColumns\": " - + Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + "," - + "\"updatedCells\": " - + data.size() - * Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) - + "}"))); - } - } - - public AppendValuesAssert appendValuesRequest(String spreadsheetId, String range, List<List<Object>> data) { - return new AppendValuesAssert(spreadsheetId, range, data); - } - - public class AppendValuesAssert { - private final List<List<Object>> data; - - AppendValuesAssert(String spreadsheetId, String range, List<List<Object>> data) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("range", range); - this.data = data; - } - - public void andReturnAppendResponse(String updatedRange) throws IOException { - String valuesJson = mapper.writer().writeValueAsString(data); - - actual - .getRunner().async().actions( - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .post("/v4/spreadsheets/${spreadsheetId}/values/${range}:append") - .validate("$.values.toString()", valuesJson)), - actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .payload("{" + "\"spreadsheetId\": \"${spreadsheetId}\"," + "\"updates\":" + "{" - + "\"spreadsheetId\": \"${spreadsheetId}\"," - + "\"updatedRange\": \"" + updatedRange + "\"," + "\"updatedRows\": " - + data.size() + "," + "\"updatedColumns\": " - + Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) + "," - + "\"updatedCells\": " - + data.size() - * Optional.ofNullable(data.get(0)).map(Collection::size).orElse(0) - + "}" + "}"))); - } - } - - public GetValuesAssert getValuesRequest(String spreadsheetId, String range) { - return new GetValuesAssert(spreadsheetId, range); - } - - public class GetValuesAssert { - GetValuesAssert(String spreadsheetId, String range) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("range", range); - } - - public void andReturnValueRange(ValueRange valueRange) throws IOException { - String valueJson = valueRange.toPrettyString(); - actual.getRunner().async() - .actions(actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .get("/v4/spreadsheets/${spreadsheetId}/values/${range}")), - actual - .getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE).payload(valueJson))); - } - - public void andReturnValues(List<List<Object>> data) throws JsonProcessingException { - String valueRangeJson; - if (ObjectHelper.isEmpty(data)) { - valueRangeJson = "{" + "\"range\": \"${range}\"," + "\"majorDimension\": \"ROWS\"" + "}"; - } else { - valueRangeJson = "{" + "\"range\": \"${range}\"," + "\"majorDimension\": \"ROWS\"," + "\"values\":" - + mapper.writer().writeValueAsString(data) + "}"; - } - - actual.getRunner().async() - .actions(actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .get("/v4/spreadsheets/${spreadsheetId}/values/${range}")), - actual - .getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE).payload(valueRangeJson))); - } - } - - public BatchGetValuesAssert batchGetValuesRequest(String spreadsheetId, String range) { - return new BatchGetValuesAssert(spreadsheetId, range); - } - - public class BatchGetValuesAssert { - BatchGetValuesAssert(String spreadsheetId, String range) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("range", range); - } - - public void andReturnValues(List<List<Object>> data) throws JsonProcessingException { - String valueRangeJson; - if (ObjectHelper.isEmpty(data)) { - valueRangeJson = "{\"spreadsheetId\": \"${spreadsheetId}\"," + "\"valueRanges\": [" + "{" - + "\"range\": \"${range}\"," + "\"majorDimension\": \"ROWS\"" + "}" - + "]}"; - } else { - valueRangeJson = "{\"spreadsheetId\": \"${spreadsheetId}\"," + "\"valueRanges\": [" + "{" - + "\"range\": \"${range}\"," + "\"majorDimension\": \"ROWS\"," - + "\"values\":" + mapper.writer().writeValueAsString(data) + "}" + "]}"; - } - - actual.getRunner().async() - .actions(actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .get("/v4/spreadsheets/${spreadsheetId}/values:batchGet")), - actual - .getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE).payload(valueRangeJson))); - } - } - - public CreateSpreadsheetAssert createSpreadsheetRequest() { - return new CreateSpreadsheetAssert(); - } - - public class CreateSpreadsheetAssert { - private String title = "@ignore@"; - private String sheetTitle; - - public CreateSpreadsheetAssert hasTitle(String title) { - this.title = title; - return this; - } - - public CreateSpreadsheetAssert hasSheetTitle(String sheetTitle) { - this.sheetTitle = sheetTitle; - return this; - } - - public void andReturnRandomSpreadsheet() { - andReturnSpreadsheet("citrus:randomString(44)"); - } - - public void andReturnSpreadsheet(String spreadsheetId) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - actual.getRunner().createVariable("title", title); - - String spreadsheetJson; - if (ObjectHelper.isNotEmpty(sheetTitle)) { - actual.getRunner().createVariable("sheetTitle", sheetTitle); - spreadsheetJson - = "{\"properties\":{\"title\":\"${title}\"},\"sheets\":[{\"properties\":{\"title\":\"${sheetTitle}\"}}]}"; - } else { - spreadsheetJson = "{\"properties\":{\"title\":\"${title}\"}}"; - } - - actual.getRunner().async().actions(actual.getRunner().http(action -> action.server(actual.getHttpServer()).receive() - .post("/v4/spreadsheets").name("create.request") - .messageType(MessageType.JSON).payload(spreadsheetJson)), actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).send().response(HttpStatus.OK) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .payload( - "{\"spreadsheetId\":\"${spreadsheetId}\",\"properties\":{\"title\":\"citrus:jsonPath(citrus:message(create.request.payload()), '$.properties.title')\"}}"))); - } - } - - public BatchUpdateSpreadsheetAssert batchUpdateSpreadsheetRequest(String spreadsheetId) { - return new BatchUpdateSpreadsheetAssert(spreadsheetId); - } - - public class BatchUpdateSpreadsheetAssert { - private List<String> fields = new ArrayList<>(); - - BatchUpdateSpreadsheetAssert(String spreadsheetId) { - actual.getRunner().createVariable("spreadsheetId", spreadsheetId); - } - - public BatchUpdateSpreadsheetAssert updateTitle(String title) { - actual.getRunner().createVariable("title", title); - fields.add("title"); - return this; - } - - public void andReturnUpdated() { - actual.getRunner().async() - .actions(actual.getRunner() - .http(action -> action.server(actual.getHttpServer()).receive() - .post("/v4/spreadsheets/${spreadsheetId}:batchUpdate").messageType(MessageType.JSON) - .payload("{" + "\"includeSpreadsheetInResponse\":true," + "\"requests\":[" + "{" - + "\"updateSpreadsheetProperties\": {" + "\"fields\":\"" - + String.join(",", fields) + "\"," + "\"properties\":{" - + fields.stream().map(field -> String.format("\"%s\":\"${%s}\"", field, field)) - .collect(Collectors.joining(",")) - + "}" + "}" + "}" + "]}")), - actual.getRunner().http(action -> action.server(actual.getHttpServer()).send() - .response(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_VALUE) - .payload( - "{\"spreadsheetId\":\"${spreadsheetId}\",\"updatedSpreadsheet\":{\"properties\":{\"title\":\"${title}\"},\"spreadsheetId\":\"${spreadsheetId}\"}}"))); - } - } -} diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerRule.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerRule.java deleted file mode 100644 index 5f6750d360e..00000000000 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/server/GoogleSheetsApiTestServerRule.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.component.google.sheets.server; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -import com.consol.citrus.dsl.endpoint.CitrusEndpoints; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.InvocationInterceptor; -import org.junit.jupiter.api.extension.ReflectiveInvocationContext; -import org.springframework.core.io.ClassPathResource; -import org.springframework.http.HttpStatus; -import org.springframework.util.SocketUtils; - -import static org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerAssert.assertThatGoogleApi; - -public class GoogleSheetsApiTestServerRule implements InvocationInterceptor { - - public static final String SERVER_KEYSTORE = "googleapis.jks"; - public static final String SERVER_KEYSTORE_PASSWORD = "secret"; - - private GoogleSheetsApiTestServer googleApiTestServer; - private int serverPort = SocketUtils.findAvailableTcpPort(); - - public GoogleSheetsApiTestServerRule(String optionFile) { - try { - Map<String, Object> testOptions = getTestOptions(optionFile); - - googleApiTestServer = new GoogleSheetsApiTestServer.Builder( - CitrusEndpoints.http().server().port(serverPort).timeout(15000).defaultStatus(HttpStatus.REQUEST_TIMEOUT) - .autoStart(true)).keyStorePath(new ClassPathResource(SERVER_KEYSTORE).getFile().toPath()) - .keyStorePassword(SERVER_KEYSTORE_PASSWORD).securePort(serverPort) - .clientId(testOptions.get("clientId").toString()) - .clientSecret(testOptions.get("clientSecret").toString()) - .accessToken(testOptions.get("accessToken").toString()) - .refreshToken(testOptions.get("refreshToken").toString()).build(); - - assertThatGoogleApi(googleApiTestServer).isRunning(); - } catch (Exception e) { - throw new IllegalStateException("Error while reading server keystore file", e); - } - } - - @Override - public void interceptTestMethod( - Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, - ExtensionContext extensionContext) - throws Throwable { - googleApiTestServer.init(); - try { - invocation.proceed(); - } finally { - googleApiTestServer.reset(); - } - } - - /** - * Read component configuration from TEST_OPTIONS_PROPERTIES. - * - * @return Map of component options. - */ - private Map<String, Object> getTestOptions(String optionFile) throws IOException { - final Properties properties = new Properties(); - properties.load(getClass().getResourceAsStream(optionFile)); - - Map<String, Object> options = new HashMap<>(); - for (Map.Entry<Object, Object> entry : properties.entrySet()) { - options.put(entry.getKey().toString(), entry.getValue()); - } - - return options; - } - - public GoogleSheetsApiTestServer getGoogleApiTestServer() { - return googleApiTestServer; - } - - public int getServerPort() { - return serverPort; - } -} diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/AbstractGoogleSheetsStreamTestSupport.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/AbstractGoogleSheetsStreamTestSupport.java index 8a495811232..3b547ceaa70 100644 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/AbstractGoogleSheetsStreamTestSupport.java +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/AbstractGoogleSheetsStreamTestSupport.java @@ -16,45 +16,30 @@ */ package org.apache.camel.component.google.sheets.stream; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.sheets.v4.Sheets; import org.apache.camel.CamelContext; +import org.apache.camel.Component; import org.apache.camel.component.google.sheets.AbstractGoogleSheetsTestSupport; -import org.apache.camel.component.google.sheets.BatchGoogleSheetsClientFactory; -import org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerRule; -import org.apache.camel.support.PropertyBindingSupport; /** * Abstract base class for GoogleSheets Integration tests generated by Camel API component maven plugin. */ -public class AbstractGoogleSheetsStreamTestSupport extends AbstractGoogleSheetsTestSupport { +public abstract class AbstractGoogleSheetsStreamTestSupport extends AbstractGoogleSheetsTestSupport { @Override - protected CamelContext createCamelContext() throws Exception { + protected Component getComponent(CamelContext context) throws Exception { + GoogleSheetsStreamConfiguration configuration = new GoogleSheetsStreamConfiguration(); + configuration.setServiceAccountKey("mock"); - final CamelContext context = super.createCamelContext(); - - final GoogleSheetsStreamConfiguration configuration = new GoogleSheetsStreamConfiguration(); - PropertyBindingSupport.bindProperties(context, configuration, getTestOptions()); - - // add GoogleSheetsComponent to Camel context - final GoogleSheetsStreamComponent component = new GoogleSheetsStreamComponent(context); - component.setClientFactory(new BatchGoogleSheetsClientFactory( - new NetHttpTransport.Builder() - .trustCertificatesFromJavaKeyStore( - getClass().getResourceAsStream("/" + GoogleSheetsApiTestServerRule.SERVER_KEYSTORE), - GoogleSheetsApiTestServerRule.SERVER_KEYSTORE_PASSWORD) - .build(), - new JacksonFactory()) { - @Override - protected void configure(Sheets.Builder clientBuilder) { - clientBuilder.setRootUrl(String.format("https://localhost:%s/", googleSheetsApiTestServerRule.getServerPort())); - } - }); + GoogleSheetsStreamComponent component = new GoogleSheetsStreamComponent(context); component.setConfiguration(configuration); - context.addComponent("google-sheets-stream", component); + component.setClientFactory(getClientFactory()); + + return component; + } - return context; + @Override + protected String getComponentName() { + return "google-sheets-stream"; } + } diff --git a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/SheetsStreamConsumerIntegrationTest.java b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/SheetsStreamConsumerIntegrationTest.java index 03949824502..d2e347b1291 100644 --- a/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/SheetsStreamConsumerIntegrationTest.java +++ b/components/camel-google/camel-google-sheets/src/test/java/org/apache/camel/component/google/sheets/stream/SheetsStreamConsumerIntegrationTest.java @@ -18,17 +18,22 @@ package org.apache.camel.component.google.sheets.stream; import java.util.Arrays; import java.util.List; -import java.util.UUID; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.google.api.client.testing.http.MockLowLevelHttpResponse; import com.google.api.services.sheets.v4.model.Spreadsheet; import com.google.api.services.sheets.v4.model.ValueRange; import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.google.sheets.GoogleSheetsClientFactory; +import org.apache.camel.component.google.sheets.MockGoogleSheetsClientFactory; import org.apache.camel.component.mock.MockEndpoint; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; -import static org.apache.camel.component.google.sheets.server.GoogleSheetsApiTestServerAssert.assertThatGoogleApi; import static org.apache.camel.component.google.sheets.stream.GoogleSheetsStreamConstants.MAJOR_DIMENSION; import static org.apache.camel.component.google.sheets.stream.GoogleSheetsStreamConstants.RANGE; import static org.apache.camel.component.google.sheets.stream.GoogleSheetsStreamConstants.RANGE_INDEX; @@ -37,136 +42,131 @@ import static org.apache.camel.component.google.sheets.stream.GoogleSheetsStream import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -@EnabledIf(value = "org.apache.camel.component.google.sheets.AbstractGoogleSheetsTestSupport#hasCredentials", - disabledReason = "Google Sheets credentials were not provided") -public class SheetsStreamConsumerIntegrationTest extends AbstractGoogleSheetsStreamTestSupport { +public class SheetsStreamConsumerIntegrationTest { - private String range = TEST_SHEET + "!A1:B2"; - - @Test - public void testConsumeValueRange() throws Exception { - String spreadsheetId = UUID.randomUUID().toString(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnSpreadsheet(spreadsheetId); + private static final ObjectMapper MAPPER = new ObjectMapper() + .setDefaultPropertyInclusion( + JsonInclude.Value.construct(JsonInclude.Include.NON_EMPTY, JsonInclude.Include.NON_EMPTY)) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) + .enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING).disable(JsonParser.Feature.AUTO_CLOSE_SOURCE); + private static final List<List<Object>> TEST_DATA = Arrays.asList( + Arrays.asList("a1", "b1"), + Arrays.asList("a2", "b2")); + public static class ConsumeValueRangeTest extends AbstractGoogleSheetsStreamTestSupport { Spreadsheet testSheet = getSpreadsheet(); - List<List<Object>> data = Arrays.asList( - Arrays.asList("a1", "b1"), - Arrays.asList("a2", "b2")); - - assertThatGoogleApi(getGoogleApiTestServer()) - .updateValuesRequest(spreadsheetId, range, data) - .andReturnUpdateResponse(); - - applyTestData(testSheet); - - assertThatGoogleApi(getGoogleApiTestServer()) - .batchGetValuesRequest(testSheet.getSpreadsheetId(), range) - .andReturnValues(data); - - context().addRoutes(createGoogleStreamRouteBuilder(testSheet.getSpreadsheetId(), false)); - - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMinimumMessageCount(1); - MockEndpoint.assertIsSatisfied(context); - - Exchange exchange = mock.getReceivedExchanges().get(0); - assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); - assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); - assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); - assertEquals(range, exchange.getIn().getHeaders().get(RANGE)); - assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); - assertEquals("ROWS", exchange.getIn().getHeaders().get(MAJOR_DIMENSION)); - - ValueRange values = (ValueRange) exchange.getIn().getBody(); - assertEquals(2L, values.getValues().size()); - assertEquals("a1", values.getValues().get(0).get(0)); - assertEquals("b1", values.getValues().get(0).get(1)); - assertEquals("a2", values.getValues().get(1).get(0)); - assertEquals("b2", values.getValues().get(1).get(1)); + @Test + public void test() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMinimumMessageCount(1); + MockEndpoint.assertIsSatisfied(context); + + Exchange exchange = mock.getReceivedExchanges().get(0); + assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); + assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); + assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); + assertEquals(TEST_RANGE, exchange.getIn().getHeaders().get(RANGE)); + assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); + assertEquals("ROWS", exchange.getIn().getHeaders().get(MAJOR_DIMENSION)); + + ValueRange result = (ValueRange) exchange.getIn().getBody(); + + assertEquals(2L, result.getValues().size()); + assertEquals("a1", result.getValues().get(0).get(0)); + assertEquals("b1", result.getValues().get(0).get(1)); + assertEquals("a2", result.getValues().get(1).get(0)); + assertEquals("b2", result.getValues().get(1).get(1)); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent( + "{\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + "\"valueRanges\": [" + "{" + + "\"range\": \"" + TEST_RANGE + "\"," + "\"majorDimension\": \"ROWS\"," + + "\"values\":" + MAPPER.writer().writeValueAsString(TEST_DATA) + "}" + "]}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from(String.format("google-sheets-stream:%s?range=%s&delay=20000&maxResults=5&splitResults=%s", + testSheet.getSpreadsheetId(), TEST_RANGE, false)) + .to("mock:result"); + } + }; + } } - @Test - public void testConsumeValueRangeSplitResults() throws Exception { - String spreadsheetId = UUID.randomUUID().toString(); - - assertThatGoogleApi(getGoogleApiTestServer()) - .createSpreadsheetRequest() - .hasSheetTitle("TestData") - .andReturnSpreadsheet(spreadsheetId); - + public static class ConsumeValueRangeSplitResultsTest extends AbstractGoogleSheetsStreamTestSupport { Spreadsheet testSheet = getSpreadsheet(); - List<List<Object>> data = Arrays.asList( - Arrays.asList("a1", "b1"), - Arrays.asList("a2", "b2")); - - assertThatGoogleApi(getGoogleApiTestServer()) - .updateValuesRequest(spreadsheetId, range, data) - .andReturnUpdateResponse(); - - applyTestData(testSheet); - - assertThatGoogleApi(getGoogleApiTestServer()) - .batchGetValuesRequest(testSheet.getSpreadsheetId(), range) - .andReturnValues(data); - - context().addRoutes(createGoogleStreamRouteBuilder(testSheet.getSpreadsheetId(), true)); - context().getRouteController().startRoute("google-stream-test"); - - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMinimumMessageCount(2); - MockEndpoint.assertIsSatisfied(context); - - Exchange exchange = mock.getReceivedExchanges().get(0); - assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); - assertTrue(exchange.getIn().getHeaders().containsKey(VALUE_INDEX)); - assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); - assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); - assertEquals(range, exchange.getIn().getHeaders().get(RANGE)); - assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); - assertEquals(1, exchange.getIn().getHeaders().get(VALUE_INDEX)); - assertEquals("ROWS", exchange.getIn().getHeaders().get(MAJOR_DIMENSION)); - - List<?> values = (List) exchange.getIn().getBody(); - assertEquals(2L, values.size()); - assertEquals("a1", values.get(0)); - assertEquals("b1", values.get(1)); - - exchange = mock.getReceivedExchanges().get(1); - assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); - assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); - assertTrue(exchange.getIn().getHeaders().containsKey(VALUE_INDEX)); - assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); - assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); - assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); - assertEquals(2, exchange.getIn().getHeaders().get(VALUE_INDEX)); - - values = (List) exchange.getIn().getBody(); - assertEquals(2L, values.size()); - assertEquals("a2", values.get(0)); - assertEquals("b2", values.get(1)); - } - - private RouteBuilder createGoogleStreamRouteBuilder(String spreadsheetId, boolean splitResults) { - return new RouteBuilder() { - @Override - public void configure() { - from(String.format( - "google-sheets-stream://%s?range=%s&delay=20000&maxResults=5&splitResults=%s", - spreadsheetId, range, splitResults)) - .routeId("google-stream-test") - .to("mock:result"); - } - }; + @Test + public void test() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMinimumMessageCount(2); + MockEndpoint.assertIsSatisfied(context); + + Exchange exchange = mock.getReceivedExchanges().get(0); + assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); + assertTrue(exchange.getIn().getHeaders().containsKey(VALUE_INDEX)); + assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); + assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); + assertEquals(TEST_RANGE, exchange.getIn().getHeaders().get(RANGE)); + assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); + assertEquals(1, exchange.getIn().getHeaders().get(VALUE_INDEX)); + assertEquals("ROWS", exchange.getIn().getHeaders().get(MAJOR_DIMENSION)); + + List<?> values = (List) exchange.getIn().getBody(); + assertEquals(2L, values.size()); + assertEquals("a1", values.get(0)); + assertEquals("b1", values.get(1)); + + exchange = mock.getReceivedExchanges().get(1); + assertTrue(exchange.getIn().getHeaders().containsKey(SPREADSHEET_ID)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE)); + assertTrue(exchange.getIn().getHeaders().containsKey(RANGE_INDEX)); + assertTrue(exchange.getIn().getHeaders().containsKey(VALUE_INDEX)); + assertTrue(exchange.getIn().getHeaders().containsKey(MAJOR_DIMENSION)); + assertEquals(testSheet.getSpreadsheetId(), exchange.getIn().getHeaders().get(SPREADSHEET_ID)); + assertEquals(1, exchange.getIn().getHeaders().get(RANGE_INDEX)); + assertEquals(2, exchange.getIn().getHeaders().get(VALUE_INDEX)); + + values = (List) exchange.getIn().getBody(); + assertEquals(2L, values.size()); + assertEquals("a2", values.get(0)); + assertEquals("b2", values.get(1)); + } + + @Override + protected GoogleSheetsClientFactory getClientFactory() throws Exception { + return new MockGoogleSheetsClientFactory( + new MockLowLevelHttpResponse() + .setContent( + "{\"spreadsheetId\": \"" + testSheet.getSpreadsheetId() + "\"," + "\"valueRanges\": [" + "{" + + "\"range\": \"" + TEST_RANGE + "\"," + "\"majorDimension\": \"ROWS\"," + + "\"values\":" + MAPPER.writer().writeValueAsString(TEST_DATA) + "}" + "]}")); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + from(String.format("google-sheets-stream:%s?range=%s&delay=20000&maxResults=5&splitResults=%s", + testSheet.getSpreadsheetId(), TEST_RANGE, true)) + .to("mock:result"); + } + }; + } } } diff --git a/components/camel-google/camel-google-sheets/src/test/resources/googleapis.jks b/components/camel-google/camel-google-sheets/src/test/resources/googleapis.jks deleted file mode 100644 index 0d6097cc2c9..00000000000 Binary files a/components/camel-google/camel-google-sheets/src/test/resources/googleapis.jks and /dev/null differ diff --git a/components/camel-google/camel-google-sheets/src/test/resources/test-options.properties b/components/camel-google/camel-google-sheets/src/test/resources/test-options.properties deleted file mode 100644 index c29a60c4d27..00000000000 --- a/components/camel-google/camel-google-sheets/src/test/resources/test-options.properties +++ /dev/null @@ -1,30 +0,0 @@ -## --------------------------------------------------------------------------- -## 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. -## --------------------------------------------------------------------------- - -##################################### -## Login properties for Google Sheets Component -##################################### -## Application client id and secret -clientId= -clientSecret= -applicationName=camel-google-sheets/1.0 -accessToken= -refreshToken= - -serviceAccountKey= -scopes[]= -delegate= \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml index d26d0162f2d..f3772b354fb 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -101,7 +101,6 @@ <jta-api-1.2-version>1.2</jta-api-1.2-version> <cglib-version>3.2.12</cglib-version> <chunk-templates-version>3.6.2</chunk-templates-version> - <citrus-version>2.8.0</citrus-version> <classgraph-version>4.8.151</classgraph-version> <cmis-version>1.1.0</cmis-version> <cometd-java-client-version>4.0.4</cometd-java-client-version>