diff --git a/fineract-client/build.gradle b/fineract-client/build.gradle index 44cc5c5b4..a5a8ecc9a 100644 --- a/fineract-client/build.gradle +++ b/fineract-client/build.gradle @@ -87,3 +87,7 @@ configurations { generatedCompile.extendsFrom implementation generatedRuntime.extendsFrom runtime } + +test { + useJUnitPlatform() +} diff --git a/fineract-client/dependencies.gradle b/fineract-client/dependencies.gradle index b495840af..00a69fe01 100644 --- a/fineract-client/dependencies.gradle +++ b/fineract-client/dependencies.gradle @@ -39,6 +39,13 @@ dependencies { 'commons-codec:commons-codec', ) implementation('org.apache.oltu.oauth2:org.apache.oltu.oauth2.client') { - exclude group: 'org.apache.oltu.oauth2' , module: 'org.apache.oltu.oauth2.common' + exclude group: 'org.apache.oltu.oauth2', module: 'org.apache.oltu.oauth2.common' } + testImplementation( + 'org.junit.jupiter:junit-jupiter-api:5.7.0', + 'com.google.truth:truth:1.0.1' + ) + testRuntimeOnly( + 'org.junit.jupiter:junit-jupiter-engine:5.7.0' + ) } diff --git a/fineract-client/src/main/java/.gitkeep b/fineract-client/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/fineract-client/src/main/java/org/apache/fineract/client/util/Calls.java b/fineract-client/src/main/java/org/apache/fineract/client/util/Calls.java new file mode 100644 index 000000000..651aee7bf --- /dev/null +++ b/fineract-client/src/main/java/org/apache/fineract/client/util/Calls.java @@ -0,0 +1,51 @@ +/** + * 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.fineract.client.util; + +import java.io.IOException; +import retrofit2.Call; +import retrofit2.Response; + +/** + * Extension methods for {@link Call}. This class is recommended to be statically imported. + * + * @author Michael Vorburger.ch + */ +public class Calls { + + private Calls() {} + + /** + * Execute a Call, expecting success. + * + * @param call + * the Call to execute + * @return the body of the successful call (never null) + * @throws IOException + * thrown either if a problem occurred talking to the server, or the HTTP response code was not + * [200..300) successful + */ + public static T ok(Call call) throws IOException { + Response response = call.execute(); + if (response.isSuccessful()) { + return response.body(); + } + throw new IOException("HTTP failed: " + call.request() + "; " + response); + } +} diff --git a/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java b/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java new file mode 100644 index 000000000..43b2f1d5d --- /dev/null +++ b/fineract-client/src/main/java/org/apache/fineract/client/util/FineractClient.java @@ -0,0 +1,86 @@ +/** + * 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.fineract.client.util; + +import org.apache.fineract.client.ApiClient; +import org.apache.fineract.client.auth.ApiKeyAuth; + +/** + * Fineract Client Java SDK API entry point. This is recommended to be used instead of {@link ApiClient}. + * + * @author Michael Vorburger.ch + */ +public class FineractClient { + + private final ApiClient apiClient; + + private FineractClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + public static FineractClientBuilder builder() { + return new FineractClientBuilder(); + } + + public S createService(Class serviceClass) { + return apiClient.createService(serviceClass); + } + + public static class FineractClientBuilder { + + private String baseURL; + private String tenant; + private String username; + private String password; + + private FineractClientBuilder() {} + + public FineractClientBuilder baseURL(String baseURL) { + this.baseURL = baseURL; + return this; + } + + public FineractClientBuilder tenant(String tenant) { + this.tenant = tenant; + return this; + } + + public FineractClientBuilder basicAuth(String username, String password) { + this.username = username; + this.password = password; + return this; + } + + public FineractClient build() { + ApiClient apiClient = new ApiClient("basicAuth", has("username", username), has("password", password)); + apiClient.getAdapterBuilder().baseUrl(has("baseURL", baseURL)); + ApiKeyAuth authorization = new ApiKeyAuth("header", "fineract-platform-tenantid"); + authorization.setApiKey(has("tenant", tenant)); + apiClient.addAuthorization("tenantid", authorization); + return new FineractClient(apiClient); + } + + private T has(String propertyName, T value) throws IllegalStateException { + if (value == null) { + throw new IllegalStateException("Must call " + propertyName + "(...) to create valid Builder"); + } + return value; + } + } +} diff --git a/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTest.java b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTest.java new file mode 100644 index 000000000..b4ccb8288 --- /dev/null +++ b/fineract-client/src/test/java/org/apache/fineract/client/test/FineractClientTest.java @@ -0,0 +1,58 @@ +/** + * 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.fineract.client.test; + +import static com.google.common.truth.Truth.assertThat; +import static org.apache.fineract.client.util.Calls.ok; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import org.apache.fineract.client.services.ClientApi; +import org.apache.fineract.client.util.FineractClient; +import org.junit.jupiter.api.Test; + +/** + * Illustrates use of Fineract SDK REST Client. + * + * @author Michael Vorburger.ch + */ +public class FineractClientTest { + + @Test + void testRetrieveAllClients() throws IOException { + FineractClient client = FineractClient.builder().baseURL("https://demo.fineract.dev/fineract-provider/api/v1/").tenant("default") + .basicAuth("mifos", "password").build(); + ClientApi clientApi = client.createService(ClientApi.class); + assertThat(ok(clientApi.retrieveAll20(null, null, null, null, null, null, null, null, 0, 100, null, null, null)) + .getTotalFilteredRecords()).isAtLeast(3); + } + + @Test + void testFineractClientBuilder() throws IOException { + assertThrows(IllegalStateException.class, () -> { + FineractClient.builder().build(); + }); + assertThrows(IllegalStateException.class, () -> { + FineractClient.builder().baseURL("https://server/").build(); + }); + assertThrows(IllegalStateException.class, () -> { + FineractClient.builder().baseURL("https://server/").tenant("default").build(); + }); + } +}