diff --git a/README.md b/README.md index e82c4b5837..0d2907d336 100644 --- a/README.md +++ b/README.md @@ -4,25 +4,26 @@ Copyright (C) 2017 The Open Library Foundation This software is distributed under the terms of the Apache License, Version 2.0. See the file "[LICENSE](LICENSE)" for more information. -# Goal +## Goal FOLIO compatible circulation capabilities, including loan items from the inventory. -# Prerequisites +## Prerequisites -# Required +### Required - Java 8 JDK - Gradle 3.3 +- [FOLIO Loan Storage Module](https://github.com/folio-org/mod-loan-storage) -## Optional +### Optional - Node.js 6.4 (for API linting) - NPM 3.10 (for API linting) -# Preparation +## Preparation -## Git Submodules +### Git Submodules There are some common RAML definitions that are shared between FOLIO projects via Git submodules. @@ -32,16 +33,30 @@ If these are not initialised, the inventory-storage module will fail to build co More information is available on the [developer site](http://dev.folio.org/doc/setup#update-git-submodules). -# Common activities +## Common activities -## Running a general build +### Running a general build In order to run a general build (including the default tests), run `gradle build`. -## Creating the circulation module JAR +### Creating the circulation module JAR In order to build an executable Jar (e.g. for Okapi to deploy), run `gradle fatJar`. -## Checking the RAML and JSON.Schema definitions +### Running the tests + +#### Using a fake loan storage module + +In order to run the tests, using a fake loan storage module, run ./quick-test.sh. + +#### Using a real loan storage module (via Okapi) + +In order to run the tests against a real storage module, run ./real-storage-module-test.sh. + +This requires [Okapi](https://github.com/folio-org/okapi) to be running and an loan storage module be registered with it. + +The test script will create a tenant and activate the module for that tenant. + +### Checking the RAML and JSON.Schema definitions run `./lint.sh` to validate the RAML and JSON.Schema descriptions of the API (requires node.js and NPM) diff --git a/activate-loan-storage.json b/activate-loan-storage.json new file mode 100644 index 0000000000..477f599d53 --- /dev/null +++ b/activate-loan-storage.json @@ -0,0 +1,3 @@ +{ + "id": "loan-storage" +} diff --git a/build.gradle b/build.gradle index e5ce2b3b4f..26a370efd3 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,8 @@ repositories { } dependencies { + //Don't use the code gen directly but hoping to get rid of warnings in build + compile 'io.vertx:vertx-codegen:3.3.3' compile 'io.vertx:vertx-core:3.3.3' compile 'io.vertx:vertx-web:3.3.3' compile 'org.apache.httpcomponents:httpclient-osgi:4.5.2' @@ -31,6 +33,12 @@ test { exclude '**/api/**Tests.class' } +task testApiViaOkapi(type: Test) { + include '**/APITestSuite.class' + + systemProperty 'okapi.useForStorage', 'true' +} + jar { manifest { attributes 'Main-Class': mainClassName diff --git a/create-tenant.sh b/create-tenant.sh new file mode 100755 index 0000000000..659be71acd --- /dev/null +++ b/create-tenant.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +tenant_id=${1:-demo_tenant} + +tenant_json=$(cat ./okapi-setup/tenant.json) + +tenant_json="${tenant_json/tenantidhere/$tenant_id}" + +curl -w '\n' -X POST -D - \ + -H "Content-type: application/json" \ + -d "${tenant_json}" \ + http://localhost:9130/_/proxy/tenants diff --git a/delete-tenant.sh b/delete-tenant.sh new file mode 100755 index 0000000000..b62837f5ae --- /dev/null +++ b/delete-tenant.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +tenant_id=${1:-demo_tenant} + +curl -X DELETE -D - -w '\n' http://localhost:9130/_/proxy/tenants/${tenant_id} + diff --git a/okapi-setup/tenant.json b/okapi-setup/tenant.json new file mode 100644 index 0000000000..6385ce725e --- /dev/null +++ b/okapi-setup/tenant.json @@ -0,0 +1,5 @@ +{ + "id": "tenantidhere", + "name": "A Library", + "description": "A library" +} diff --git a/real-storage-module-test.sh b/real-storage-module-test.sh new file mode 100755 index 0000000000..e940580370 --- /dev/null +++ b/real-storage-module-test.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +okapi_proxy_address="http://localhost:9130" +tenant_id="test_tenant" + +echo "Check if Okapi is contactable" +curl -w '\n' -X GET -D - \ + "${okapi_proxy_address}/_/env" || exit 1 + +echo "Create ${tenant_id} tenant" +./create-tenant.sh ${tenant_id} + +echo "Activate loan storage for ${tenant_id}" +activate_json=$(cat ./activate-loan-storage.json) + +curl -w '\n' -X POST -D - \ + -H "Content-type: application/json" \ + -d "${activate_json}" \ + "${okapi_proxy_address}/_/proxy/tenants/${tenant_id}/modules" + +echo "Run API tests" +gradle clean testApiViaOkapi + +test_results=$? + +echo "Deactivate loan storage for ${tenant_id}" +curl -X DELETE -D - -w '\n' "${okapi_proxy_address}/_/proxy/tenants/${tenant_id}/modules/loan-storage" + +echo "Deleting ${tenant_id}" +./delete-tenant.sh ${tenant_id} + +if [ $test_results != 0 ]; then + echo '--------------------------------------' + echo 'BUILD FAILED' + echo '--------------------------------------' + exit 1; +else + echo '--------------------------------------' + echo 'BUILD SUCCEEDED' + echo '--------------------------------------' + exit 1; +fi diff --git a/src/main/java/org/folio/circulation/support/http/client/HttpClient.java b/src/main/java/org/folio/circulation/support/http/client/HttpClient.java index c70b4e0f62..e36ea3eaec 100644 --- a/src/main/java/org/folio/circulation/support/http/client/HttpClient.java +++ b/src/main/java/org/folio/circulation/support/http/client/HttpClient.java @@ -5,6 +5,7 @@ import io.vertx.core.http.HttpClientRequest; import io.vertx.core.http.HttpClientResponse; import io.vertx.core.json.Json; +import org.folio.circulation.support.VertxAssistant; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; @@ -28,6 +29,15 @@ public HttpClient(Vertx vertx, this.exceptionHandler = exceptionHandler; } + public HttpClient(VertxAssistant vertxAssistant, + URL okapiUrl, + Consumer exceptionHandler) { + this.client = vertxAssistant + .createUsingVertx(vertx -> vertx.createHttpClient()); + this.okapiUrl = okapiUrl; + this.exceptionHandler = exceptionHandler; + } + public void post(URL url, Object body, String tenantId, @@ -43,7 +53,7 @@ public void post(URL url, request.headers().add(TENANT_HEADER, tenantId); } - request.setTimeout(3000); + request.setTimeout(5000); request.exceptionHandler(exception -> { this.exceptionHandler.accept(exception); diff --git a/src/test/java/org/folio/circulation/api/APITestSuite.java b/src/test/java/org/folio/circulation/api/APITestSuite.java index b012e94604..afa8820d44 100644 --- a/src/test/java/org/folio/circulation/api/APITestSuite.java +++ b/src/test/java/org/folio/circulation/api/APITestSuite.java @@ -1,9 +1,9 @@ package org.folio.circulation.api; -import io.vertx.core.Vertx; import org.folio.circulation.CirculationVerticle; import org.folio.circulation.api.fakes.FakeLoanStorageModule; import org.folio.circulation.support.VertxAssistant; +import org.folio.circulation.support.http.client.HttpClient; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.RunWith; @@ -16,8 +16,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.Consumer; -import java.util.function.Function; @RunWith(Suite.class) @@ -33,14 +31,7 @@ public class APITestSuite { private static String circulationModuleDeploymentId; private static String fakeLoanStorageModuleDeploymentId; - public static URL storageUrl() { - try { - return new URL(FakeLoanStorageModule.getAddress()); - } - catch(MalformedURLException ex) { - return null; - } - } + private static Boolean useOkapiForStorage; public static URL moduleUrl(String path) { try { @@ -55,6 +46,9 @@ public static URL moduleUrl(String path) { public static void before() throws Exception { + useOkapiForStorage = Boolean.parseBoolean( + System.getProperty("okapi.useForStorage", "false")); + vertxAssistant = new VertxAssistant(); port = 9605; @@ -65,9 +59,15 @@ public static void before() vertxAssistant.start(); - CompletableFuture fakeStorageModuleDeployed = - vertxAssistant.deployVerticle(FakeLoanStorageModule.class.getName(), - new HashMap<>()); + CompletableFuture fakeStorageModuleDeployed = new CompletableFuture<>(); + + if(!useOkapiForStorage) { + vertxAssistant.deployVerticle(FakeLoanStorageModule.class.getName(), + new HashMap<>(), fakeStorageModuleDeployed); + } + else { + fakeStorageModuleDeployed.complete(null); + } CompletableFuture circulationModuleDeployed = vertxAssistant.deployVerticle(CirculationVerticle.class.getName(), @@ -85,11 +85,18 @@ public static void after() CompletableFuture circulationModuleUndeployed = vertxAssistant.undeployVerticle(circulationModuleDeploymentId); - CompletableFuture fakeStorageModuleUndeployed = - vertxAssistant.undeployVerticle(fakeLoanStorageModuleDeploymentId); + CompletableFuture fakeStorageModuleUndeployed = new CompletableFuture<>(); - CompletableFuture.allOf(circulationModuleUndeployed, - fakeStorageModuleUndeployed).get(10, TimeUnit.SECONDS); + if(!useOkapiForStorage) { + vertxAssistant.undeployVerticle(fakeLoanStorageModuleDeploymentId, + fakeStorageModuleUndeployed); + } + else { + fakeStorageModuleUndeployed.complete(null); + } + + circulationModuleUndeployed.get(10, TimeUnit.SECONDS); + fakeStorageModuleUndeployed.get(10, TimeUnit.SECONDS); CompletableFuture stopped = new CompletableFuture<>(); @@ -98,11 +105,25 @@ public static void after() stopped.get(5, TimeUnit.SECONDS); } - public static void useVertx(Consumer action) { - vertxAssistant.useVertx(action); + public static HttpClient createHttpClient() { + return new HttpClient(vertxAssistant, storageUrl(), exception -> { + System.out.println( + String.format("Request to circulation module failed: %s", + exception.toString())); + }); } - public static T createUsingVertx(Function function) { - return vertxAssistant.createUsingVertx(function); + private static URL storageUrl() { + try { + if(useOkapiForStorage) { + return new URL("http://localhost:9130/loan-storage/loans"); + } + else { + return new URL(FakeLoanStorageModule.getAddress()); + } + } + catch(MalformedURLException ex) { + return null; + } } } diff --git a/src/test/java/org/folio/circulation/api/LoanAPITests.java b/src/test/java/org/folio/circulation/api/LoanAPITests.java index e477ccd3fa..b307bc9f38 100644 --- a/src/test/java/org/folio/circulation/api/LoanAPITests.java +++ b/src/test/java/org/folio/circulation/api/LoanAPITests.java @@ -1,6 +1,5 @@ package org.folio.circulation.api; -import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import org.folio.circulation.support.http.client.HttpClient; import org.folio.circulation.support.http.client.IndividualResource; @@ -26,13 +25,7 @@ public class LoanAPITests { - HttpClient client = APITestSuite.createUsingVertx( - (Vertx vertx) -> new HttpClient(vertx, - APITestSuite.storageUrl(), exception -> { - System.out.println( - String.format("Request to circulation module failed: %s", - exception.toString())); - })); + HttpClient client = APITestSuite.createHttpClient(); @Test public void canCreateALoan()