From d9917c658c0753f12afd100409864912b56ab7e9 Mon Sep 17 00:00:00 2001 From: Pete Cornish Date: Thu, 22 Sep 2016 15:00:07 +0100 Subject: [PATCH 01/13] New development version. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 852b722..6b8cfa3 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ */ group 'io.apiman.cli' -version '0.2.3' +version '0.2.4-SNAPSHOT' buildscript { repositories { From 93d611d208d2fc7ce72eee4b2e8cff30d1e20231 Mon Sep 17 00:00:00 2001 From: Pete Cornish Date: Wed, 1 Feb 2017 00:35:16 +0000 Subject: [PATCH 02/13] Bumps Gradle version. --- build.gradle | 1 + gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6b8cfa3..0e29acd 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ repositories { compileJava { sourceCompatibility = '1.8' + targetCompatibility = '1.8' } ext { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 41a3809..ca45e61 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -19,4 +19,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip From 914520552dc33fc8f94cb45f929008d0c2d9ae38 Mon Sep 17 00:00:00 2001 From: Pete Cornish Date: Sat, 4 Feb 2017 22:53:15 +0000 Subject: [PATCH 03/13] Bumps apiman test version to 1.2.8.Final. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c975050..98e4ef2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ jdk: services: - docker before_install: - - docker pull apiman/on-wildfly10:1.2.4.Final + - docker pull apiman/on-wildfly10:1.2.8.Final script: - - docker run -d -p 8080:8080 apiman/on-wildfly10:1.2.4.Final - - ./gradlew test -PintegrationTest --info \ No newline at end of file + - docker run -d -p 8080:8080 apiman/on-wildfly10:1.2.8.Final + - ./gradlew test -PintegrationTest --info --stacktrace From 4f1907b5c4e7400b2df1b5ddfba760c3019cd0a7 Mon Sep 17 00:00:00 2001 From: Pete Cornish Date: Sat, 4 Feb 2017 22:53:53 +0000 Subject: [PATCH 04/13] Adds the ability to wait for the server to start before attempting to run commands. Reorganises command package structure. Factors out declarative application logic into separate services. Improves docs. --- CHANGELOG.md | 5 + src/main/java/io/apiman/cli/Cli.java | 28 +- .../cli/{core => command}/api/ApiMixin.java | 10 +- .../api/Version11xServerApi.java | 14 +- .../api/Version12xServerApi.java | 14 +- .../api/VersionAgnosticApi.java | 12 +- .../api/command/AbstractApiCommand.java | 21 +- .../api/command/ApiCommand.java | 17 +- .../api/command/ApiCreateCommand.java | 23 +- .../api/command/ApiListCommand.java | 19 +- .../api/command/ApiPolicyAddCommand.java | 19 +- .../api/command/ApiPolicyCommand.java | 17 +- .../api/command/ApiPublishCommand.java | 20 +- .../Version11XManagementApiFactoryImpl.java | 10 +- .../Version12XManagementApiFactoryImpl.java | 16 +- .../cli/{core => command}/api/model/Api.java | 6 +- .../api/model/ApiConfig.java | 6 +- .../api/model/ApiGateway.java | 6 +- .../api/model/ApiPolicy.java | 6 +- .../api/model/ApiVersion.java | 18 +- .../api/model/EndpointProperties.java | 18 +- .../api/model/ServiceConfig.java | 6 +- .../{core => command}/common/ActionApi.java | 8 +- .../common/command/AbstractModelCommand.java | 13 +- .../common/command/ModelAction.java | 6 +- .../common/command/ModelCreateCommand.java | 11 +- .../common/command/ModelListCommand.java | 11 +- .../common/command/ModelShowCommand.java | 11 +- .../common/model/ManagementApiVersion.java | 6 +- .../common/model/ServerAction.java | 6 +- .../common/util/ServerActionUtil.java | 10 +- .../command/{ => core}/AbstractCommand.java | 55 +- .../{ => core}/AbstractFinalCommand.java | 11 +- .../cli/command/{ => core}/Command.java | 6 +- .../declarative}/DeclarativeUtil.java | 39 +- .../declarative/command/ApplyCommand.java | 188 +++++++ .../declarative/model/Declaration.java | 4 +- .../declarative/model/DeclarativeApi.java | 6 +- .../model/DeclarativeApiConfig.java | 6 +- .../model/DeclarativeEndpointSecurity.java | 18 +- .../declarative/model/DeclarativeGateway.java | 8 +- .../declarative/model/DeclarativeOrg.java | 6 +- .../declarative/model/DeclarativePolicy.java | 4 +- .../declarative/model/DeclarativeSystem.java | 6 +- .../declarative/model/SharedItems.java | 4 +- .../{core => command}/gateway/GatewayApi.java | 10 +- .../gateway/GatewayMixin.java | 10 +- .../command/AbstractGatewayCreateCommand.java | 23 +- .../gateway/command/GatewayCommand.java | 17 +- .../gateway/command/GatewayCreateCommand.java | 15 +- .../gateway/command/GatewayListCommand.java | 37 ++ .../gateway/command/GatewayShowCommand.java | 26 +- .../gateway/command/GatewayTestCommand.java | 18 +- .../gateway/model/Gateway.java | 6 +- .../gateway/model/GatewayConfig.java | 6 +- .../gateway/model/GatewayTestResponse.java | 6 +- .../gateway/model/GatewayType.java | 6 +- .../cli/{core => command}/org/OrgApi.java | 8 +- .../cli/{core => command}/org/OrgMixin.java | 10 +- .../org/command/OrgCommand.java | 17 +- .../org/command/OrgCreateCommand.java | 26 +- .../org/command/OrgShowCommand.java | 26 +- .../cli/{core => command}/org/model/Org.java | 6 +- .../{core => command}/plugin/PluginApi.java | 8 +- .../{core => command}/plugin/PluginMixin.java | 10 +- .../plugin/command/PluginAddCommand.java | 25 +- .../plugin/command/PluginCommand.java | 17 +- .../plugin/command/PluginListCommand.java | 37 ++ .../plugin/command/PluginShowCommand.java | 26 +- .../plugin/model/Plugin.java | 6 +- .../declarative/command/ApplyCommand.java | 491 ------------------ .../ManagementApiFactoryModule.java | 23 +- .../cli/management/ManagementApiUtil.java | 60 +-- .../api/StatusApi.java} | 19 +- .../binding/ManagementApiBinding.java | 4 +- .../binding/ManagementApiBindingImpl.java | 4 +- .../binding/ManagementApiBindings.java | 4 +- .../io/apiman/cli/service/ApiService.java | 51 ++ .../io/apiman/cli/service/ApiServiceImpl.java | 102 ++++ .../cli/service/DeclarativeService.java | 54 ++ .../cli/service/DeclarativeServiceImpl.java | 250 +++++++++ .../cli/service/ManagementApiService.java | 69 +++ .../cli/service/ManagementApiServiceImpl.java | 141 +++++ .../PluginService.java} | 24 +- .../apiman/cli/service/PluginServiceImpl.java | 81 +++ .../io/apiman/cli/service/PolicyService.java | 56 ++ .../apiman/cli/service/PolicyServiceImpl.java | 92 ++++ .../io/apiman/cli/service/ServiceModule.java | 36 ++ .../java/io/apiman/cli/util/AuthUtil.java | 10 +- .../java/io/apiman/cli/util/BeanUtil.java | 9 +- .../java/io/apiman/cli/util/Functions.java | 4 +- .../io/apiman/cli/util/InjectionUtil.java | 44 ++ src/main/java/io/apiman/cli/util/LogUtil.java | 22 +- .../java/io/apiman/cli/util/MappingUtil.java | 25 +- .../apiman/cli/{ => command/api}/ApiTest.java | 7 +- .../declarative}/DeclarativeUtilTest.java | 11 +- .../command}/DeclarativeTest.java | 13 +- .../{ => command/gateway}/GatewayTest.java | 7 +- .../apiman/cli/{ => command/org}/OrgTest.java | 7 +- .../cli/{ => command/plugin}/PluginTest.java | 9 +- .../cli/management/ManagementApiUtilTest.java | 20 +- .../service/ManagementApiServiceImplTest.java | 55 ++ 102 files changed, 1964 insertions(+), 996 deletions(-) rename src/main/java/io/apiman/cli/{core => command}/api/ApiMixin.java (80%) rename src/main/java/io/apiman/cli/{core => command}/api/Version11xServerApi.java (89%) rename src/main/java/io/apiman/cli/{core => command}/api/Version12xServerApi.java (89%) rename src/main/java/io/apiman/cli/{core => command}/api/VersionAgnosticApi.java (85%) rename src/main/java/io/apiman/cli/{core => command}/api/command/AbstractApiCommand.java (66%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiCommand.java (73%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiCreateCommand.java (83%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiListCommand.java (76%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiPolicyAddCommand.java (86%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiPolicyCommand.java (69%) rename src/main/java/io/apiman/cli/{core => command}/api/command/ApiPublishCommand.java (77%) rename src/main/java/io/apiman/cli/{core => command}/api/factory/Version11XManagementApiFactoryImpl.java (93%) rename src/main/java/io/apiman/cli/{core => command}/api/factory/Version12XManagementApiFactoryImpl.java (89%) rename src/main/java/io/apiman/cli/{core => command}/api/model/Api.java (94%) rename src/main/java/io/apiman/cli/{core => command}/api/model/ApiConfig.java (94%) rename src/main/java/io/apiman/cli/{core => command}/api/model/ApiGateway.java (89%) rename src/main/java/io/apiman/cli/{core => command}/api/model/ApiPolicy.java (93%) rename src/main/java/io/apiman/cli/{core => command}/api/model/ApiVersion.java (50%) rename src/main/java/io/apiman/cli/{core => command}/api/model/EndpointProperties.java (62%) rename src/main/java/io/apiman/cli/{core => command}/api/model/ServiceConfig.java (92%) rename src/main/java/io/apiman/cli/{core => command}/common/ActionApi.java (81%) rename src/main/java/io/apiman/cli/{core => command}/common/command/AbstractModelCommand.java (67%) rename src/main/java/io/apiman/cli/{core => command}/common/command/ModelAction.java (86%) rename src/main/java/io/apiman/cli/{core => command}/common/command/ModelCreateCommand.java (87%) rename src/main/java/io/apiman/cli/{core => command}/common/command/ModelListCommand.java (87%) rename src/main/java/io/apiman/cli/{core => command}/common/command/ModelShowCommand.java (87%) rename src/main/java/io/apiman/cli/{core => command}/common/model/ManagementApiVersion.java (86%) rename src/main/java/io/apiman/cli/{core => command}/common/model/ServerAction.java (91%) rename src/main/java/io/apiman/cli/{core => command}/common/util/ServerActionUtil.java (89%) rename src/main/java/io/apiman/cli/command/{ => core}/AbstractCommand.java (87%) rename src/main/java/io/apiman/cli/command/{ => core}/AbstractFinalCommand.java (81%) rename src/main/java/io/apiman/cli/command/{ => core}/Command.java (92%) rename src/main/java/io/apiman/cli/{util => command/declarative}/DeclarativeUtil.java (75%) create mode 100644 src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java rename src/main/java/io/apiman/cli/{core => command}/declarative/model/Declaration.java (95%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeApi.java (93%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeApiConfig.java (91%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeEndpointSecurity.java (57%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeGateway.java (86%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeOrg.java (90%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativePolicy.java (94%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativeSystem.java (91%) rename src/main/java/io/apiman/cli/{core => command}/declarative/model/SharedItems.java (94%) rename src/main/java/io/apiman/cli/{core => command}/gateway/GatewayApi.java (80%) rename src/main/java/io/apiman/cli/{core => command}/gateway/GatewayMixin.java (78%) rename src/main/java/io/apiman/cli/{core => command}/gateway/command/AbstractGatewayCreateCommand.java (76%) rename src/main/java/io/apiman/cli/{core => command}/gateway/command/GatewayCommand.java (72%) rename src/main/java/io/apiman/cli/{core => command}/gateway/command/GatewayCreateCommand.java (72%) create mode 100644 src/main/java/io/apiman/cli/command/gateway/command/GatewayListCommand.java rename src/main/java/io/apiman/cli/{core => command}/gateway/command/GatewayShowCommand.java (61%) rename src/main/java/io/apiman/cli/{core => command}/gateway/command/GatewayTestCommand.java (82%) rename src/main/java/io/apiman/cli/{core => command}/gateway/model/Gateway.java (92%) rename src/main/java/io/apiman/cli/{core => command}/gateway/model/GatewayConfig.java (92%) rename src/main/java/io/apiman/cli/{core => command}/gateway/model/GatewayTestResponse.java (90%) rename src/main/java/io/apiman/cli/{core => command}/gateway/model/GatewayType.java (84%) rename src/main/java/io/apiman/cli/{core => command}/org/OrgApi.java (85%) rename src/main/java/io/apiman/cli/{core => command}/org/OrgMixin.java (79%) rename src/main/java/io/apiman/cli/{core => command}/org/command/OrgCommand.java (71%) rename src/main/java/io/apiman/cli/{core => command}/org/command/OrgCreateCommand.java (66%) rename src/main/java/io/apiman/cli/{core => command}/org/command/OrgShowCommand.java (65%) rename src/main/java/io/apiman/cli/{core => command}/org/model/Org.java (90%) rename src/main/java/io/apiman/cli/{core => command}/plugin/PluginApi.java (84%) rename src/main/java/io/apiman/cli/{core => command}/plugin/PluginMixin.java (79%) rename src/main/java/io/apiman/cli/{core => command}/plugin/command/PluginAddCommand.java (72%) rename src/main/java/io/apiman/cli/{core => command}/plugin/command/PluginCommand.java (71%) create mode 100644 src/main/java/io/apiman/cli/command/plugin/command/PluginListCommand.java rename src/main/java/io/apiman/cli/{core => command}/plugin/command/PluginShowCommand.java (62%) rename src/main/java/io/apiman/cli/{core => command}/plugin/model/Plugin.java (93%) delete mode 100644 src/main/java/io/apiman/cli/core/declarative/command/ApplyCommand.java rename src/main/java/io/apiman/cli/{core/plugin/command/PluginListCommand.java => management/api/StatusApi.java} (57%) create mode 100644 src/main/java/io/apiman/cli/service/ApiService.java create mode 100644 src/main/java/io/apiman/cli/service/ApiServiceImpl.java create mode 100644 src/main/java/io/apiman/cli/service/DeclarativeService.java create mode 100644 src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java create mode 100644 src/main/java/io/apiman/cli/service/ManagementApiService.java create mode 100644 src/main/java/io/apiman/cli/service/ManagementApiServiceImpl.java rename src/main/java/io/apiman/cli/{core/gateway/command/GatewayListCommand.java => service/PluginService.java} (56%) create mode 100644 src/main/java/io/apiman/cli/service/PluginServiceImpl.java create mode 100644 src/main/java/io/apiman/cli/service/PolicyService.java create mode 100644 src/main/java/io/apiman/cli/service/PolicyServiceImpl.java create mode 100644 src/main/java/io/apiman/cli/service/ServiceModule.java create mode 100644 src/main/java/io/apiman/cli/util/InjectionUtil.java rename src/test/java/io/apiman/cli/{ => command/api}/ApiTest.java (95%) rename src/test/java/io/apiman/cli/{util => command/declarative}/DeclarativeUtilTest.java (95%) rename src/test/java/io/apiman/cli/command/{ => declarative/command}/DeclarativeTest.java (92%) rename src/test/java/io/apiman/cli/{ => command/gateway}/GatewayTest.java (94%) rename src/test/java/io/apiman/cli/{ => command/org}/OrgTest.java (90%) rename src/test/java/io/apiman/cli/{ => command/plugin}/PluginTest.java (95%) create mode 100644 src/test/java/io/apiman/cli/service/ManagementApiServiceImplTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d7a3c..849582d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] +### Added +- Adds the ability to wait for the server to start before attempting to run commands. +- Improvements to internal code structure. + ## [0.2.3] - 2016-09-22 ### Added - Adds support for multiple versions of an API in the same declaration file. diff --git a/src/main/java/io/apiman/cli/Cli.java b/src/main/java/io/apiman/cli/Cli.java index 14f4616..c461215 100644 --- a/src/main/java/io/apiman/cli/Cli.java +++ b/src/main/java/io/apiman/cli/Cli.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -17,14 +17,17 @@ package io.apiman.cli; import com.google.common.collect.Lists; -import io.apiman.cli.command.AbstractCommand; -import io.apiman.cli.command.Command; -import io.apiman.cli.core.api.command.ApiCommand; -import io.apiman.cli.core.declarative.command.ApplyCommand; -import io.apiman.cli.core.gateway.command.GatewayCommand; -import io.apiman.cli.core.org.command.OrgCommand; -import io.apiman.cli.core.plugin.command.PluginCommand; +import io.apiman.cli.command.api.command.ApiCommand; +import io.apiman.cli.command.core.AbstractCommand; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.command.declarative.command.ApplyCommand; +import io.apiman.cli.command.gateway.command.GatewayCommand; +import io.apiman.cli.command.org.command.OrgCommand; +import io.apiman.cli.command.plugin.command.PluginCommand; +import io.apiman.cli.service.ManagementApiService; +import io.apiman.cli.util.InjectionUtil; +import javax.inject.Inject; import java.util.Map; /** @@ -33,8 +36,13 @@ * @author Pete Cornish {@literal } */ public class Cli extends AbstractCommand { + @Inject + public Cli(ManagementApiService managementApiService) { + super(managementApiService); + } + public static void main(String... args) { - new Cli().run(Lists.newArrayList(args)); + InjectionUtil.getInjector().getInstance(Cli.class).run(Lists.newArrayList(args)); } @Override diff --git a/src/main/java/io/apiman/cli/core/api/ApiMixin.java b/src/main/java/io/apiman/cli/command/api/ApiMixin.java similarity index 80% rename from src/main/java/io/apiman/cli/core/api/ApiMixin.java rename to src/main/java/io/apiman/cli/command/api/ApiMixin.java index a00b3a2..cca3ab8 100644 --- a/src/main/java/io/apiman/cli/core/api/ApiMixin.java +++ b/src/main/java/io/apiman/cli/command/api/ApiMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.api; +package io.apiman.cli.command.api; -import io.apiman.cli.core.common.command.ModelAction; -import io.apiman.cli.core.api.model.Api; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.common.command.ModelAction; /** * @author Pete Cornish {@literal } diff --git a/src/main/java/io/apiman/cli/core/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java similarity index 89% rename from src/main/java/io/apiman/cli/core/api/Version11xServerApi.java rename to src/main/java/io/apiman/cli/command/api/Version11xServerApi.java index 2f259d2..bfb0c75 100644 --- a/src/main/java/io/apiman/cli/core/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.api; +package io.apiman.cli.command.api; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.api.model.ApiVersion; -import io.apiman.cli.core.api.model.ServiceConfig; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.ApiVersion; +import io.apiman.cli.command.api.model.ServiceConfig; import retrofit.client.Response; import retrofit.http.*; diff --git a/src/main/java/io/apiman/cli/core/api/Version12xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java similarity index 89% rename from src/main/java/io/apiman/cli/core/api/Version12xServerApi.java rename to src/main/java/io/apiman/cli/command/api/Version12xServerApi.java index bafdeef..8248cb2 100644 --- a/src/main/java/io/apiman/cli/core/api/Version12xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.api; +package io.apiman.cli.command.api; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiConfig; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.api.model.ApiVersion; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.ApiVersion; import retrofit.client.Response; import retrofit.http.*; diff --git a/src/main/java/io/apiman/cli/core/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java similarity index 85% rename from src/main/java/io/apiman/cli/core/api/VersionAgnosticApi.java rename to src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java index b0dd422..e097bf0 100644 --- a/src/main/java/io/apiman/cli/core/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.api; +package io.apiman.cli.command.api; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiConfig; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.api.model.ApiVersion; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiVersion; import retrofit.client.Response; import java.util.List; diff --git a/src/main/java/io/apiman/cli/core/api/command/AbstractApiCommand.java b/src/main/java/io/apiman/cli/command/api/command/AbstractApiCommand.java similarity index 66% rename from src/main/java/io/apiman/cli/core/api/command/AbstractApiCommand.java rename to src/main/java/io/apiman/cli/command/api/command/AbstractApiCommand.java index 2616171..139f255 100644 --- a/src/main/java/io/apiman/cli/core/api/command/AbstractApiCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/AbstractApiCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,13 +14,14 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; -import io.apiman.cli.core.common.command.AbstractModelCommand; -import io.apiman.cli.core.api.Version12xServerApi; -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.command.AbstractModelCommand; +import io.apiman.cli.command.api.Version12xServerApi; +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; /** @@ -34,4 +35,8 @@ public abstract class AbstractApiCommand extends AbstractModelCommand} */ public class ApiCommand extends AbstractCommand { + @Inject + public ApiCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected void populateCommands(Map> commandMap) { commandMap.put("create", ApiCreateCommand.class); diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java similarity index 83% rename from src/main/java/io/apiman/cli/core/api/command/ApiCreateCommand.java rename to src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java index f0335bf..89e418f 100644 --- a/src/main/java/io/apiman/cli/core/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,21 +14,23 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; import com.google.common.collect.Lists; -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiConfig; -import io.apiman.cli.core.api.model.ApiGateway; -import io.apiman.cli.core.api.VersionAgnosticApi; +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiGateway; +import io.apiman.cli.command.api.VersionAgnosticApi; import io.apiman.cli.exception.CommandException; import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.service.ManagementApiService; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; +import javax.inject.Inject; import java.text.MessageFormat; /** @@ -60,6 +62,11 @@ public class ApiCreateCommand extends AbstractApiCommand implements ApiMixin { @Option(name = "--gateway", aliases = {"-g"}, usage = "Gateway") private String gateway = "TheGateway"; + @Inject + public ApiCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Create {0}", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiListCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiListCommand.java similarity index 76% rename from src/main/java/io/apiman/cli/core/api/command/ApiListCommand.java rename to src/main/java/io/apiman/cli/command/api/command/ApiListCommand.java index 62b4659..23d704a 100644 --- a/src/main/java/io/apiman/cli/core/api/command/ApiListCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiListCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,18 +14,20 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.VersionAgnosticApi; +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.Api; import io.apiman.cli.exception.CommandException; +import io.apiman.cli.service.ManagementApiService; import io.apiman.cli.util.LogUtil; import io.apiman.cli.util.MappingUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; +import javax.inject.Inject; import java.text.MessageFormat; import java.util.List; @@ -37,6 +39,11 @@ public class ApiListCommand extends AbstractApiCommand implements ApiMixin { private static final Logger LOGGER = LogManager.getLogger(ApiListCommand.class); + @Inject + public ApiListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("List {0}s", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiPolicyAddCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiPolicyAddCommand.java similarity index 86% rename from src/main/java/io/apiman/cli/core/api/command/ApiPolicyAddCommand.java rename to src/main/java/io/apiman/cli/command/api/command/ApiPolicyAddCommand.java index 5359cab..6054137 100644 --- a/src/main/java/io/apiman/cli/core/api/command/ApiPolicyAddCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiPolicyAddCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,20 +14,22 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; import com.google.common.io.CharStreams; -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.api.VersionAgnosticApi; +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.ApiPolicy; import io.apiman.cli.exception.CommandException; import io.apiman.cli.exception.ExitWithCodeException; import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.service.ManagementApiService; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; +import javax.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -58,6 +60,11 @@ public class ApiPolicyAddCommand extends AbstractApiCommand implements ApiMixin @Option(name = "--configFile", aliases = {"-f"}, usage = "Policy configuration file", forbids = "-i") private Path configFile; + @Inject + public ApiPolicyAddCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Add {0} policy", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiPolicyCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiPolicyCommand.java similarity index 69% rename from src/main/java/io/apiman/cli/core/api/command/ApiPolicyCommand.java rename to src/main/java/io/apiman/cli/command/api/command/ApiPolicyCommand.java index ccea8dd..93e1dcd 100644 --- a/src/main/java/io/apiman/cli/core/api/command/ApiPolicyCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiPolicyCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,11 +14,13 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; -import io.apiman.cli.command.AbstractCommand; -import io.apiman.cli.command.Command; +import io.apiman.cli.command.core.AbstractCommand; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.service.ManagementApiService; +import javax.inject.Inject; import java.util.Map; /** @@ -27,6 +29,11 @@ * @author Pete Cornish {@literal } */ public class ApiPolicyCommand extends AbstractCommand { + @Inject + public ApiPolicyCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected void populateCommands(Map> commandMap) { commandMap.put("add", ApiPolicyAddCommand.class); diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiPublishCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiPublishCommand.java similarity index 77% rename from src/main/java/io/apiman/cli/core/api/command/ApiPublishCommand.java rename to src/main/java/io/apiman/cli/command/api/command/ApiPublishCommand.java index bd8558f..1c9424c 100644 --- a/src/main/java/io/apiman/cli/core/api/command/ApiPublishCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiPublishCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,17 +14,19 @@ * limitations under the License. */ -package io.apiman.cli.core.api.command; +package io.apiman.cli.command.api.command; -import io.apiman.cli.core.common.util.ServerActionUtil; +import io.apiman.cli.command.common.util.ServerActionUtil; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.common.ActionApi; +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.common.ActionApi; +import io.apiman.cli.service.ManagementApiService; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; +import javax.inject.Inject; import java.text.MessageFormat; /** @@ -41,6 +43,11 @@ public class ApiPublishCommand extends AbstractApiCommand implements ApiMixin { @Option(name = "--version", aliases = {"-v"}, usage = "API version", required = true) private String version; + @Inject + public ApiPublishCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Publish {0}", getModelName()); @@ -51,5 +58,4 @@ public void performAction(CmdLineParser parser) throws CommandException { LOGGER.debug("Publishing {}", this::getModelName); ServerActionUtil.publishApi(orgName, name, version, serverVersion, buildServerApiClient(ActionApi.class)); } - } diff --git a/src/main/java/io/apiman/cli/core/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java similarity index 93% rename from src/main/java/io/apiman/cli/core/api/factory/Version11XManagementApiFactoryImpl.java rename to src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java index cf4e657..47d347d 100644 --- a/src/main/java/io/apiman/cli/core/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.apiman.cli.core.api.factory; +package io.apiman.cli.command.api.factory; -import io.apiman.cli.core.api.Version11xServerApi; -import io.apiman.cli.core.api.VersionAgnosticApi; -import io.apiman.cli.core.api.model.*; +import io.apiman.cli.command.api.Version11xServerApi; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.*; import io.apiman.cli.management.factory.AbstractManagementApiFactory; import io.apiman.cli.management.factory.ManagementApiFactory; import retrofit.client.Response; diff --git a/src/main/java/io/apiman/cli/core/api/factory/Version12XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java similarity index 89% rename from src/main/java/io/apiman/cli/core/api/factory/Version12XManagementApiFactoryImpl.java rename to src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java index a36fb97..7492a68 100644 --- a/src/main/java/io/apiman/cli/core/api/factory/Version12XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. */ -package io.apiman.cli.core.api.factory; +package io.apiman.cli.command.api.factory; -import io.apiman.cli.core.api.Version12xServerApi; -import io.apiman.cli.core.api.VersionAgnosticApi; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiConfig; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.api.model.ApiVersion; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.Version12xServerApi; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiVersion; import io.apiman.cli.management.factory.AbstractManagementApiFactory; import io.apiman.cli.management.factory.ManagementApiFactory; import retrofit.client.Response; diff --git a/src/main/java/io/apiman/cli/core/api/model/Api.java b/src/main/java/io/apiman/cli/command/api/model/Api.java similarity index 94% rename from src/main/java/io/apiman/cli/core/api/model/Api.java rename to src/main/java/io/apiman/cli/command/api/model/Api.java index 23f45e9..6e0af99 100644 --- a/src/main/java/io/apiman/cli/core/api/model/Api.java +++ b/src/main/java/io/apiman/cli/command/api/model/Api.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.api.model; +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiConfig.java b/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java similarity index 94% rename from src/main/java/io/apiman/cli/core/api/model/ApiConfig.java rename to src/main/java/io/apiman/cli/command/api/model/ApiConfig.java index 988b77c..17aa14e 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ApiConfig.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.api.model; +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiGateway.java b/src/main/java/io/apiman/cli/command/api/model/ApiGateway.java similarity index 89% rename from src/main/java/io/apiman/cli/core/api/model/ApiGateway.java rename to src/main/java/io/apiman/cli/command/api/model/ApiGateway.java index f800433..f61ce0e 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ApiGateway.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiGateway.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.api.model; +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiPolicy.java b/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java similarity index 93% rename from src/main/java/io/apiman/cli/core/api/model/ApiPolicy.java rename to src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java index 1e3919c..0ab8e25 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ApiPolicy.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.api.model; +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiVersion.java b/src/main/java/io/apiman/cli/command/api/model/ApiVersion.java similarity index 50% rename from src/main/java/io/apiman/cli/core/api/model/ApiVersion.java rename to src/main/java/io/apiman/cli/command/api/model/ApiVersion.java index c8d5e0f..71f8401 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ApiVersion.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiVersion.java @@ -1,4 +1,20 @@ -package io.apiman.cli.core.api.model; +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/api/model/EndpointProperties.java b/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java similarity index 62% rename from src/main/java/io/apiman/cli/core/api/model/EndpointProperties.java rename to src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java index ef0680a..7e7935d 100644 --- a/src/main/java/io/apiman/cli/core/api/model/EndpointProperties.java +++ b/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java @@ -1,4 +1,20 @@ -package io.apiman.cli.core.api.model; +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/api/model/ServiceConfig.java b/src/main/java/io/apiman/cli/command/api/model/ServiceConfig.java similarity index 92% rename from src/main/java/io/apiman/cli/core/api/model/ServiceConfig.java rename to src/main/java/io/apiman/cli/command/api/model/ServiceConfig.java index 03adb82..d0ad696 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ServiceConfig.java +++ b/src/main/java/io/apiman/cli/command/api/model/ServiceConfig.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.api.model; +package io.apiman.cli.command.api.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/common/ActionApi.java b/src/main/java/io/apiman/cli/command/common/ActionApi.java similarity index 81% rename from src/main/java/io/apiman/cli/core/common/ActionApi.java rename to src/main/java/io/apiman/cli/command/common/ActionApi.java index 425f8d1..efaedab 100644 --- a/src/main/java/io/apiman/cli/core/common/ActionApi.java +++ b/src/main/java/io/apiman/cli/command/common/ActionApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,9 @@ * limitations under the License. */ -package io.apiman.cli.core.common; +package io.apiman.cli.command.common; -import io.apiman.cli.core.common.model.ServerAction; +import io.apiman.cli.command.common.model.ServerAction; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.POST; diff --git a/src/main/java/io/apiman/cli/core/common/command/AbstractModelCommand.java b/src/main/java/io/apiman/cli/command/common/command/AbstractModelCommand.java similarity index 67% rename from src/main/java/io/apiman/cli/core/common/command/AbstractModelCommand.java rename to src/main/java/io/apiman/cli/command/common/command/AbstractModelCommand.java index 808e231..4368aa1 100644 --- a/src/main/java/io/apiman/cli/core/common/command/AbstractModelCommand.java +++ b/src/main/java/io/apiman/cli/command/common/command/AbstractModelCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.common.command; +package io.apiman.cli.command.common.command; -import io.apiman.cli.command.AbstractFinalCommand; +import io.apiman.cli.command.core.AbstractFinalCommand; +import io.apiman.cli.service.ManagementApiService; /** * Common model CRUD functionality. @@ -25,4 +26,8 @@ */ public abstract class AbstractModelCommand extends AbstractFinalCommand implements ModelAction { + + public AbstractModelCommand(ManagementApiService managementApiService) { + super(managementApiService); + } } diff --git a/src/main/java/io/apiman/cli/core/common/command/ModelAction.java b/src/main/java/io/apiman/cli/command/common/command/ModelAction.java similarity index 86% rename from src/main/java/io/apiman/cli/core/common/command/ModelAction.java rename to src/main/java/io/apiman/cli/command/common/command/ModelAction.java index 4cd5041..f3c2412 100644 --- a/src/main/java/io/apiman/cli/core/common/command/ModelAction.java +++ b/src/main/java/io/apiman/cli/command/common/command/ModelAction.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.common.command; +package io.apiman.cli.command.common.command; /** * @author Pete Cornish {@literal } diff --git a/src/main/java/io/apiman/cli/core/common/command/ModelCreateCommand.java b/src/main/java/io/apiman/cli/command/common/command/ModelCreateCommand.java similarity index 87% rename from src/main/java/io/apiman/cli/core/common/command/ModelCreateCommand.java rename to src/main/java/io/apiman/cli/command/common/command/ModelCreateCommand.java index c78188f..53be022 100644 --- a/src/main/java/io/apiman/cli/core/common/command/ModelCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/common/command/ModelCreateCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,11 @@ * limitations under the License. */ -package io.apiman.cli.core.common.command; +package io.apiman.cli.command.common.command; import io.apiman.cli.exception.CommandException; import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.service.ManagementApiService; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; @@ -33,6 +34,10 @@ public abstract class ModelCreateCommand extends AbstractModelCommand { private static final Logger LOGGER = LogManager.getLogger(ModelCreateCommand.class); + public ModelCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Create {0}", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/common/command/ModelListCommand.java b/src/main/java/io/apiman/cli/command/common/command/ModelListCommand.java similarity index 87% rename from src/main/java/io/apiman/cli/core/common/command/ModelListCommand.java rename to src/main/java/io/apiman/cli/command/common/command/ModelListCommand.java index cd73c6a..1593051 100644 --- a/src/main/java/io/apiman/cli/core/common/command/ModelListCommand.java +++ b/src/main/java/io/apiman/cli/command/common/command/ModelListCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.common.command; +package io.apiman.cli.command.common.command; import io.apiman.cli.exception.CommandException; +import io.apiman.cli.service.ManagementApiService; import io.apiman.cli.util.LogUtil; import io.apiman.cli.util.MappingUtil; import org.apache.logging.log4j.LogManager; @@ -34,6 +35,10 @@ public abstract class ModelListCommand extends AbstractModelCommand { private static final Logger LOGGER = LogManager.getLogger(ModelListCommand.class); + public ModelListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("List {0}s", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/common/command/ModelShowCommand.java b/src/main/java/io/apiman/cli/command/common/command/ModelShowCommand.java similarity index 87% rename from src/main/java/io/apiman/cli/core/common/command/ModelShowCommand.java rename to src/main/java/io/apiman/cli/command/common/command/ModelShowCommand.java index 5b9567a..96e1d57 100644 --- a/src/main/java/io/apiman/cli/core/common/command/ModelShowCommand.java +++ b/src/main/java/io/apiman/cli/command/common/command/ModelShowCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.common.command; +package io.apiman.cli.command.common.command; import io.apiman.cli.exception.CommandException; +import io.apiman.cli.service.ManagementApiService; import io.apiman.cli.util.LogUtil; import io.apiman.cli.util.MappingUtil; import org.apache.logging.log4j.LogManager; @@ -32,6 +33,10 @@ public abstract class ModelShowCommand extends AbstractModelCommand { private static final Logger LOGGER = LogManager.getLogger(ModelShowCommand.class); + public ModelShowCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Show {0}", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/common/model/ManagementApiVersion.java b/src/main/java/io/apiman/cli/command/common/model/ManagementApiVersion.java similarity index 86% rename from src/main/java/io/apiman/cli/core/common/model/ManagementApiVersion.java rename to src/main/java/io/apiman/cli/command/common/model/ManagementApiVersion.java index 0f1b823..44661a5 100644 --- a/src/main/java/io/apiman/cli/core/common/model/ManagementApiVersion.java +++ b/src/main/java/io/apiman/cli/command/common/model/ManagementApiVersion.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.common.model; +package io.apiman.cli.command.common.model; /** * The supported management API versions. diff --git a/src/main/java/io/apiman/cli/core/common/model/ServerAction.java b/src/main/java/io/apiman/cli/command/common/model/ServerAction.java similarity index 91% rename from src/main/java/io/apiman/cli/core/common/model/ServerAction.java rename to src/main/java/io/apiman/cli/command/common/model/ServerAction.java index 046ea88..e4b1125 100644 --- a/src/main/java/io/apiman/cli/core/common/model/ServerAction.java +++ b/src/main/java/io/apiman/cli/command/common/model/ServerAction.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.common.model; +package io.apiman.cli.command.common.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/common/util/ServerActionUtil.java b/src/main/java/io/apiman/cli/command/common/util/ServerActionUtil.java similarity index 89% rename from src/main/java/io/apiman/cli/core/common/util/ServerActionUtil.java rename to src/main/java/io/apiman/cli/command/common/util/ServerActionUtil.java index 6c3ae90..ee5699b 100644 --- a/src/main/java/io/apiman/cli/core/common/util/ServerActionUtil.java +++ b/src/main/java/io/apiman/cli/command/common/util/ServerActionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.apiman.cli.core.common.util; +package io.apiman.cli.command.common.util; -import io.apiman.cli.core.common.ActionApi; -import io.apiman.cli.core.common.model.ServerAction; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.ActionApi; +import io.apiman.cli.command.common.model.ServerAction; +import io.apiman.cli.command.common.model.ManagementApiVersion; import io.apiman.cli.management.ManagementApiUtil; import java.net.HttpURLConnection; diff --git a/src/main/java/io/apiman/cli/command/AbstractCommand.java b/src/main/java/io/apiman/cli/command/core/AbstractCommand.java similarity index 87% rename from src/main/java/io/apiman/cli/command/AbstractCommand.java rename to src/main/java/io/apiman/cli/command/core/AbstractCommand.java index 7cfa32b..4e46119 100644 --- a/src/main/java/io/apiman/cli/command/AbstractCommand.java +++ b/src/main/java/io/apiman/cli/command/core/AbstractCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,13 +14,16 @@ * limitations under the License. */ -package io.apiman.cli.command; +package io.apiman.cli.command.core; import com.google.common.collect.Maps; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import com.google.inject.ConfigurationException; +import com.google.inject.ProvisionException; +import io.apiman.cli.command.common.model.ManagementApiVersion; import io.apiman.cli.exception.CommandException; import io.apiman.cli.exception.ExitWithCodeException; -import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.service.ManagementApiService; +import io.apiman.cli.util.InjectionUtil; import io.apiman.cli.util.LogUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,6 +44,7 @@ public abstract class AbstractCommand implements Command { private static final Logger LOGGER = LogManager.getLogger(AbstractCommand.class); private static final String DEFAULT_SERVER_ADDRESS = "http://localhost:8080/apiman"; + private static final Integer DEFAULT_WAIT_TIME = 0; /** * Maps commands (e.g. 'org' or 'create') to their implementations. @@ -62,6 +66,11 @@ public abstract class AbstractCommand implements Command { @Option(name = "--serverPassword", aliases = {"-sp"}, usage = "Management API server password") private String serverPassword = DEFAULT_SERVER_PASSWORD; + @Option(name = "--waitTime", aliases = {"-w"}, usage = "Server startup wait time (seconds)") + private Integer waitTime = DEFAULT_WAIT_TIME; + + private ManagementApiService managementApiService; + /** * The parent Command (null if root). */ @@ -72,7 +81,9 @@ public abstract class AbstractCommand implements Command { */ private String commandName; - public AbstractCommand() { + public AbstractCommand(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + // get child commands commandMap = Maps.newHashMap(); populateCommands(commandMap); @@ -133,6 +144,8 @@ public void run(List args) { if (displayHelp) { printUsage(parser, true); } else { + managementApiService.configureEndpoint(serverAddress, serverUsername, serverPassword); + managementApiService.waitForServer(waitTime); performAction(parser); } @@ -214,7 +227,6 @@ private void printUsage(CmdLineParser parser, int exitCode) { * @return additional usage information */ protected String getAdditionalUsage() { - final StringBuilder sb = new StringBuilder(); sb.append(LINE_SEPARATOR); @@ -260,12 +272,12 @@ protected Command getChildAction(List args, CmdLineParser parser) { final Class commandClass = commandMap.get(commandName); if (null != commandClass) { try { - final Command command = commandClass.newInstance(); + final Command command = InjectionUtil.getInjector().getInstance(commandClass); command.setParent(this); command.setCommandName(commandName); return command; - } catch (InstantiationException | IllegalAccessException e) { + } catch (ProvisionException | ConfigurationException e) { throw new CommandException(String.format("Error getting child command for args: %s", args), e); } } @@ -278,7 +290,7 @@ protected Command getChildAction(List args, CmdLineParser parser) { * @return an API client for the given Class */ protected T buildServerApiClient(Class clazz) { - return buildServerApiClient(clazz, ManagementApiVersion.UNSPECIFIED); + return managementApiService.buildServerApiClient(clazz); } /** @@ -288,28 +300,7 @@ protected T buildServerApiClient(Class clazz) { * @return an API client for the given Class */ protected T buildServerApiClient(Class clazz, ManagementApiVersion serverVersion) { - return ManagementApiUtil.buildServerApiClient( - clazz, - getManagementApiEndpoint(), - getManagementApiUsername(), - getManagementApiPassword(), - logDebug, - serverVersion); - } - - protected String getManagementApiEndpoint() { - // TODO consider reading from config file/environment - return serverAddress; - } - - private String getManagementApiUsername() { - // TODO consider reading from config file/environment - return serverUsername; - } - - private String getManagementApiPassword() { - // TODO consider reading from config file/environment - return serverPassword; + return managementApiService.buildServerApiClient(clazz, serverVersion); } public void setLogDebug(boolean logDebug) { diff --git a/src/main/java/io/apiman/cli/command/AbstractFinalCommand.java b/src/main/java/io/apiman/cli/command/core/AbstractFinalCommand.java similarity index 81% rename from src/main/java/io/apiman/cli/command/AbstractFinalCommand.java rename to src/main/java/io/apiman/cli/command/core/AbstractFinalCommand.java index 5409110..5571639 100644 --- a/src/main/java/io/apiman/cli/command/AbstractFinalCommand.java +++ b/src/main/java/io/apiman/cli/command/core/AbstractFinalCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.apiman.cli.command; +package io.apiman.cli.command.core; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.CmdLineParser; import java.util.List; @@ -27,6 +28,10 @@ * @author Pete Cornish {@literal } */ public abstract class AbstractFinalCommand extends AbstractCommand { + public AbstractFinalCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + /** * Indicates that there is no child command and that this instance should handle the request. * diff --git a/src/main/java/io/apiman/cli/command/Command.java b/src/main/java/io/apiman/cli/command/core/Command.java similarity index 92% rename from src/main/java/io/apiman/cli/command/Command.java rename to src/main/java/io/apiman/cli/command/core/Command.java index c924eda..eb2dd1d 100644 --- a/src/main/java/io/apiman/cli/command/Command.java +++ b/src/main/java/io/apiman/cli/command/core/Command.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.command; +package io.apiman.cli.command.core; import io.apiman.cli.exception.CommandException; import org.kohsuke.args4j.CmdLineParser; diff --git a/src/main/java/io/apiman/cli/util/DeclarativeUtil.java b/src/main/java/io/apiman/cli/command/declarative/DeclarativeUtil.java similarity index 75% rename from src/main/java/io/apiman/cli/util/DeclarativeUtil.java rename to src/main/java/io/apiman/cli/command/declarative/DeclarativeUtil.java index e330369..84018ad 100644 --- a/src/main/java/io/apiman/cli/util/DeclarativeUtil.java +++ b/src/main/java/io/apiman/cli/command/declarative/DeclarativeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,30 +14,26 @@ * limitations under the License. */ -package io.apiman.cli.util; +package io.apiman.cli.command.declarative; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Maps; import com.google.common.io.CharStreams; -import io.apiman.cli.core.declarative.model.Declaration; -import io.apiman.cli.core.declarative.model.SharedItems; +import io.apiman.cli.command.declarative.model.Declaration; +import io.apiman.cli.command.declarative.model.SharedItems; import io.apiman.cli.exception.DeclarativeException; +import io.apiman.cli.util.BeanUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import retrofit.RetrofitError; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.HttpURLConnection; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; -import static java.util.Optional.empty; import static java.util.Optional.ofNullable; /** @@ -100,29 +96,4 @@ private static Declaration loadDeclaration(ObjectMapper mapper, String unresolve LOGGER.trace("Declaration file after resolving {} placeholders: {}", properties.size(), resolved); return mapper.readValue(resolved, Declaration.class); } - - /** - * Check for the presence of an item using the given Supplier. - * - * @param supplier the Supplier of the item - * @param - * @return the item or {@link Optional#empty()} - */ - public static Optional checkExists(Supplier supplier) { - try { - // attempt to return the item - return ofNullable(supplier.get()); - - } catch (RetrofitError re) { - // 404 indicates the item does not exist - anything else is an error - if (ofNullable(re.getResponse()) - .filter(response -> HttpURLConnection.HTTP_NOT_FOUND == response.getStatus()) - .isPresent()) { - - return empty(); - } - - throw new DeclarativeException("Error checking for existence of existing item", re); - } - } } diff --git a/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java b/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java new file mode 100644 index 0000000..6538e4a --- /dev/null +++ b/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java @@ -0,0 +1,188 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.declarative.command; + +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.core.AbstractFinalCommand; +import io.apiman.cli.command.declarative.DeclarativeUtil; +import io.apiman.cli.command.declarative.model.Declaration; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.service.DeclarativeService; +import io.apiman.cli.service.ManagementApiService; +import io.apiman.cli.service.PluginService; +import io.apiman.cli.util.BeanUtil; +import io.apiman.cli.util.MappingUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.Option; + +import javax.inject.Inject; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import static java.util.Optional.ofNullable; + +/** + * Applies an API environment declaration. + * + * @author Pete Cornish {@literal } + */ +public class ApplyCommand extends AbstractFinalCommand { + private static final Logger LOGGER = LogManager.getLogger(ApplyCommand.class); + private static final String JSON_EXTENSION = ".json"; + + @Option(name = "--declarationFile", aliases = {"-f"}, usage = "Declaration file") + private Path declarationFile; + + @Option(name = "-P", usage = "Set property (key=value)") + private List properties; + + @Option(name = "--propertiesFile", usage = "Properties file") + private List propertiesFiles; + + @Option(name = "--serverVersion", aliases = {"-sv"}, usage = "Management API server version") + private ManagementApiVersion serverVersion = ManagementApiVersion.DEFAULT_VERSION; + + private DeclarativeService declarativeService; + private PluginService pluginService; + + @Inject + public ApplyCommand(ManagementApiService managementApiService, + DeclarativeService declarativeService, PluginService pluginService) { + + super(managementApiService); + this.declarativeService = declarativeService; + this.pluginService = pluginService; + } + + @Override + protected String getCommandDescription() { + return "Apply declaration"; + } + + @Override + public void performAction(CmdLineParser parser) throws CommandException { + applyDeclaration(); + } + + /** + * Load and then apply the Declaration. + */ + void applyDeclaration() { + final Map parsedProperties = loadProperties(); + + // parse declaration + final Declaration declaration; + + if (declarationFile.endsWith(JSON_EXTENSION)) { + declaration = DeclarativeUtil.loadDeclaration(declarationFile, MappingUtil.JSON_MAPPER, parsedProperties); + } else { + // default is YAML + declaration = DeclarativeUtil.loadDeclaration(declarationFile, MappingUtil.YAML_MAPPER, parsedProperties); + } + + LOGGER.info("Loaded declaration: {}", declarationFile); + LOGGER.debug("Declaration loaded: {}", () -> MappingUtil.safeWriteValueAsJson(declaration)); + + try { + applyDeclaration(declaration); + } catch (Exception e) { + throw new CommandException("Error applying declaration", e); + } + } + + /** + * Load the properties from command line arguments and/or file. + * + * @return the properties. + */ + private Map loadProperties() { + final Map parsedProperties = BeanUtil.parseReplacements(properties); + + // check for properties file + ofNullable(propertiesFiles).ifPresent(propertiesFiles -> propertiesFiles.forEach(propertiesFile -> { + LOGGER.trace("Loading properties file: {}", propertiesFile); + + final Properties fileProperties = new Properties(); + try (final InputStream propertiesIn = Files.newInputStream(propertiesFile, StandardOpenOption.READ)) { + if (propertiesFile.toAbsolutePath().toString().toLowerCase().endsWith(".xml")) { + fileProperties.loadFromXML(propertiesIn); + } else { + fileProperties.load(propertiesIn); + } + } catch (IOException e) { + throw new CommandException(String.format("Error loading properties file: %s", propertiesFile), e); + } + + fileProperties.forEach((key, value) -> parsedProperties.put((String) key, (String) value)); + })); + + return parsedProperties; + } + + /** + * Apply the given Declaration. + * + * @param declaration the Declaration to apply. + */ + private void applyDeclaration(Declaration declaration) { + LOGGER.debug("Applying declaration"); + + // add gateways + ofNullable(declaration.getSystem().getGateways()).ifPresent(declarativeService::applyGateways); + + // add plugins + ofNullable(declaration.getSystem().getPlugins()).ifPresent(pluginService::addPlugins); + + // add org and APIs + ofNullable(declaration.getOrg()).ifPresent(org -> { + declarativeService.applyOrg(org); + + ofNullable(org.getApis()).ifPresent(apis -> + declarativeService.applyApis(serverVersion, apis, org.getName())); + }); + + LOGGER.info("Applied declaration"); + } + + public void setDeclarationFile(Path declarationFile) { + this.declarationFile = declarationFile; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public void setPropertiesFiles(List propertiesFiles) { + this.propertiesFiles = propertiesFiles; + } + + public void setServerAddress(String serverAddress) { + this.serverAddress = serverAddress; + } + + public void setServerVersion(ManagementApiVersion serverVersion) { + this.serverVersion = serverVersion; + } +} diff --git a/src/main/java/io/apiman/cli/core/declarative/model/Declaration.java b/src/main/java/io/apiman/cli/command/declarative/model/Declaration.java similarity index 95% rename from src/main/java/io/apiman/cli/core/declarative/model/Declaration.java rename to src/main/java/io/apiman/cli/command/declarative/model/Declaration.java index 3b003e2..7ba19e9 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/Declaration.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/Declaration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApi.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApi.java similarity index 93% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApi.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApi.java index 894fd14..76ccbd6 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApi.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import io.apiman.cli.core.api.model.Api; +import io.apiman.cli.command.api.model.Api; import java.util.List; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApiConfig.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApiConfig.java similarity index 91% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApiConfig.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApiConfig.java index 3e10bee..c7d782f 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeApiConfig.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeApiConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import io.apiman.cli.core.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiConfig; /** * Declarative API configuration. diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeEndpointSecurity.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeEndpointSecurity.java similarity index 57% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeEndpointSecurity.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeEndpointSecurity.java index f0068dd..3cb25a4 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeEndpointSecurity.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeEndpointSecurity.java @@ -1,4 +1,20 @@ -package io.apiman.cli.core.declarative.model; +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeGateway.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeGateway.java similarity index 86% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeGateway.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeGateway.java index 072e42b..6853e08 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeGateway.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,13 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import io.apiman.cli.core.gateway.model.Gateway; -import io.apiman.cli.core.gateway.model.GatewayConfig; +import io.apiman.cli.command.gateway.model.Gateway; +import io.apiman.cli.command.gateway.model.GatewayConfig; /** * Declarative gateway representation. diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeOrg.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java similarity index 90% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeOrg.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java index fe4fc7e..cf9c8d9 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeOrg.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.apiman.cli.core.org.model.Org; +import io.apiman.cli.command.org.model.Org; import java.util.List; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePolicy.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java similarity index 94% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativePolicy.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java index 4614f9f..693d9aa 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePolicy.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.*; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeSystem.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeSystem.java similarity index 91% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativeSystem.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativeSystem.java index c2eed61..35fc23d 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativeSystem.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeSystem.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,12 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.command.plugin.model.Plugin; import java.util.List; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/SharedItems.java b/src/main/java/io/apiman/cli/command/declarative/model/SharedItems.java similarity index 94% rename from src/main/java/io/apiman/cli/core/declarative/model/SharedItems.java rename to src/main/java/io/apiman/cli/command/declarative/model/SharedItems.java index 8a503e4..8185a4d 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/SharedItems.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/SharedItems.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/apiman/cli/core/gateway/GatewayApi.java b/src/main/java/io/apiman/cli/command/gateway/GatewayApi.java similarity index 80% rename from src/main/java/io/apiman/cli/core/gateway/GatewayApi.java rename to src/main/java/io/apiman/cli/command/gateway/GatewayApi.java index 892217d..43f2032 100644 --- a/src/main/java/io/apiman/cli/core/gateway/GatewayApi.java +++ b/src/main/java/io/apiman/cli/command/gateway/GatewayApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway; +package io.apiman.cli.command.gateway; -import io.apiman.cli.core.gateway.model.Gateway; -import io.apiman.cli.core.gateway.model.GatewayTestResponse; +import io.apiman.cli.command.gateway.model.Gateway; +import io.apiman.cli.command.gateway.model.GatewayTestResponse; import retrofit.client.Response; import retrofit.http.*; diff --git a/src/main/java/io/apiman/cli/core/gateway/GatewayMixin.java b/src/main/java/io/apiman/cli/command/gateway/GatewayMixin.java similarity index 78% rename from src/main/java/io/apiman/cli/core/gateway/GatewayMixin.java rename to src/main/java/io/apiman/cli/command/gateway/GatewayMixin.java index bfe81b8..92dbd3b 100644 --- a/src/main/java/io/apiman/cli/core/gateway/GatewayMixin.java +++ b/src/main/java/io/apiman/cli/command/gateway/GatewayMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway; +package io.apiman.cli.command.gateway; -import io.apiman.cli.core.common.command.ModelAction; -import io.apiman.cli.core.gateway.model.Gateway; +import io.apiman.cli.command.common.command.ModelAction; +import io.apiman.cli.command.gateway.model.Gateway; /** * @author Pete Cornish {@literal } diff --git a/src/main/java/io/apiman/cli/core/gateway/command/AbstractGatewayCreateCommand.java b/src/main/java/io/apiman/cli/command/gateway/command/AbstractGatewayCreateCommand.java similarity index 76% rename from src/main/java/io/apiman/cli/core/gateway/command/AbstractGatewayCreateCommand.java rename to src/main/java/io/apiman/cli/command/gateway/command/AbstractGatewayCreateCommand.java index 18d1e82..c585d6b 100644 --- a/src/main/java/io/apiman/cli/core/gateway/command/AbstractGatewayCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/gateway/command/AbstractGatewayCreateCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,16 +14,17 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.command; +package io.apiman.cli.command.gateway.command; import com.fasterxml.jackson.core.JsonProcessingException; -import io.apiman.cli.core.common.command.ModelCreateCommand; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.gateway.GatewayMixin; +import io.apiman.cli.command.common.command.ModelCreateCommand; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.gateway.GatewayMixin; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.gateway.model.Gateway; -import io.apiman.cli.core.gateway.model.GatewayConfig; -import io.apiman.cli.core.gateway.model.GatewayType; +import io.apiman.cli.command.gateway.model.Gateway; +import io.apiman.cli.command.gateway.model.GatewayConfig; +import io.apiman.cli.command.gateway.model.GatewayType; +import io.apiman.cli.service.ManagementApiService; import io.apiman.cli.util.MappingUtil; import org.kohsuke.args4j.Option; @@ -50,6 +51,10 @@ public abstract class AbstractGatewayCreateCommand extends ModelCreateCommand} */ public class GatewayCommand extends AbstractCommand { + @Inject + public GatewayCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected void populateCommands(Map> commandMap) { commandMap.put("create", GatewayCreateCommand.class); diff --git a/src/main/java/io/apiman/cli/core/gateway/command/GatewayCreateCommand.java b/src/main/java/io/apiman/cli/command/gateway/command/GatewayCreateCommand.java similarity index 72% rename from src/main/java/io/apiman/cli/core/gateway/command/GatewayCreateCommand.java rename to src/main/java/io/apiman/cli/command/gateway/command/GatewayCreateCommand.java index ae8a689..2b104c2 100644 --- a/src/main/java/io/apiman/cli/core/gateway/command/GatewayCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/gateway/command/GatewayCreateCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,20 +14,27 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.command; +package io.apiman.cli.command.gateway.command; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; + /** * Create a gateway. * * @author Pete Cornish {@literal } */ public class GatewayCreateCommand extends AbstractGatewayCreateCommand { - @Option(name = "--name", aliases = {"-n"}, usage = "Name", required = true) private String name; + @Inject + public GatewayCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getGatewayName() { return name; diff --git a/src/main/java/io/apiman/cli/command/gateway/command/GatewayListCommand.java b/src/main/java/io/apiman/cli/command/gateway/command/GatewayListCommand.java new file mode 100644 index 0000000..68a8956 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/gateway/command/GatewayListCommand.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.gateway.command; + +import io.apiman.cli.command.common.command.ModelListCommand; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.gateway.GatewayMixin; +import io.apiman.cli.command.gateway.model.Gateway; +import io.apiman.cli.service.ManagementApiService; + +import javax.inject.Inject; + +/** + * List gateways. + * + * @author Pete Cornish {@literal } + */ +public class GatewayListCommand extends ModelListCommand implements GatewayMixin { + @Inject + public GatewayListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } +} diff --git a/src/main/java/io/apiman/cli/core/gateway/command/GatewayShowCommand.java b/src/main/java/io/apiman/cli/command/gateway/command/GatewayShowCommand.java similarity index 61% rename from src/main/java/io/apiman/cli/core/gateway/command/GatewayShowCommand.java rename to src/main/java/io/apiman/cli/command/gateway/command/GatewayShowCommand.java index 69c9a62..a52bc00 100644 --- a/src/main/java/io/apiman/cli/core/gateway/command/GatewayShowCommand.java +++ b/src/main/java/io/apiman/cli/command/gateway/command/GatewayShowCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,26 +14,32 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.command; +package io.apiman.cli.command.gateway.command; -import io.apiman.cli.core.common.command.ModelShowCommand; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.gateway.GatewayMixin; +import io.apiman.cli.command.common.command.ModelShowCommand; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.gateway.GatewayMixin; +import io.apiman.cli.command.gateway.model.Gateway; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.gateway.model.Gateway; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; + /** * Show a gateway. * * @author Pete Cornish {@literal } */ -public class GatewayShowCommand extends ModelShowCommand - implements GatewayMixin { - +public class GatewayShowCommand extends ModelShowCommand implements GatewayMixin { @Option(name = "--name", aliases = {"-n"}, usage = "Name") private String name; + @Inject + public GatewayShowCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getModelId() throws CommandException { return name; diff --git a/src/main/java/io/apiman/cli/core/gateway/command/GatewayTestCommand.java b/src/main/java/io/apiman/cli/command/gateway/command/GatewayTestCommand.java similarity index 82% rename from src/main/java/io/apiman/cli/core/gateway/command/GatewayTestCommand.java rename to src/main/java/io/apiman/cli/command/gateway/command/GatewayTestCommand.java index 3ae0f77..7a6c2fe 100644 --- a/src/main/java/io/apiman/cli/core/gateway/command/GatewayTestCommand.java +++ b/src/main/java/io/apiman/cli/command/gateway/command/GatewayTestCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,19 +14,20 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.command; +package io.apiman.cli.command.gateway.command; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.gateway.model.GatewayTestResponse; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.gateway.model.GatewayTestResponse; import io.apiman.cli.exception.CommandException; import io.apiman.cli.exception.ExitWithCodeException; +import io.apiman.cli.service.ManagementApiService; import io.apiman.cli.util.LogUtil; import io.apiman.cli.util.MappingUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.Option; +import javax.inject.Inject; import java.text.MessageFormat; /** @@ -37,6 +38,11 @@ public class GatewayTestCommand extends AbstractGatewayCreateCommand { private static final Logger LOGGER = LogManager.getLogger(GatewayTestCommand.class); + @Inject + public GatewayTestCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Test {0}", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/gateway/model/Gateway.java b/src/main/java/io/apiman/cli/command/gateway/model/Gateway.java similarity index 92% rename from src/main/java/io/apiman/cli/core/gateway/model/Gateway.java rename to src/main/java/io/apiman/cli/command/gateway/model/Gateway.java index ae8b384..91aa299 100644 --- a/src/main/java/io/apiman/cli/core/gateway/model/Gateway.java +++ b/src/main/java/io/apiman/cli/command/gateway/model/Gateway.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.model; +package io.apiman.cli.command.gateway.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/gateway/model/GatewayConfig.java b/src/main/java/io/apiman/cli/command/gateway/model/GatewayConfig.java similarity index 92% rename from src/main/java/io/apiman/cli/core/gateway/model/GatewayConfig.java rename to src/main/java/io/apiman/cli/command/gateway/model/GatewayConfig.java index 43453e6..edce27c 100644 --- a/src/main/java/io/apiman/cli/core/gateway/model/GatewayConfig.java +++ b/src/main/java/io/apiman/cli/command/gateway/model/GatewayConfig.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.model; +package io.apiman.cli.command.gateway.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/gateway/model/GatewayTestResponse.java b/src/main/java/io/apiman/cli/command/gateway/model/GatewayTestResponse.java similarity index 90% rename from src/main/java/io/apiman/cli/core/gateway/model/GatewayTestResponse.java rename to src/main/java/io/apiman/cli/command/gateway/model/GatewayTestResponse.java index 410efd3..a588f10 100644 --- a/src/main/java/io/apiman/cli/core/gateway/model/GatewayTestResponse.java +++ b/src/main/java/io/apiman/cli/command/gateway/model/GatewayTestResponse.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.model; +package io.apiman.cli.command.gateway.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/gateway/model/GatewayType.java b/src/main/java/io/apiman/cli/command/gateway/model/GatewayType.java similarity index 84% rename from src/main/java/io/apiman/cli/core/gateway/model/GatewayType.java rename to src/main/java/io/apiman/cli/command/gateway/model/GatewayType.java index e5254c3..a813846 100644 --- a/src/main/java/io/apiman/cli/core/gateway/model/GatewayType.java +++ b/src/main/java/io/apiman/cli/command/gateway/model/GatewayType.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.model; +package io.apiman.cli.command.gateway.model; /** * Models gateway types. diff --git a/src/main/java/io/apiman/cli/core/org/OrgApi.java b/src/main/java/io/apiman/cli/command/org/OrgApi.java similarity index 85% rename from src/main/java/io/apiman/cli/core/org/OrgApi.java rename to src/main/java/io/apiman/cli/command/org/OrgApi.java index d5b4231..9211d9e 100644 --- a/src/main/java/io/apiman/cli/core/org/OrgApi.java +++ b/src/main/java/io/apiman/cli/command/org/OrgApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,9 @@ * limitations under the License. */ -package io.apiman.cli.core.org; +package io.apiman.cli.command.org; -import io.apiman.cli.core.org.model.Org; +import io.apiman.cli.command.org.model.Org; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.GET; diff --git a/src/main/java/io/apiman/cli/core/org/OrgMixin.java b/src/main/java/io/apiman/cli/command/org/OrgMixin.java similarity index 79% rename from src/main/java/io/apiman/cli/core/org/OrgMixin.java rename to src/main/java/io/apiman/cli/command/org/OrgMixin.java index 1e7e222..9ceba57 100644 --- a/src/main/java/io/apiman/cli/core/org/OrgMixin.java +++ b/src/main/java/io/apiman/cli/command/org/OrgMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.org; +package io.apiman.cli.command.org; -import io.apiman.cli.core.common.command.ModelAction; -import io.apiman.cli.core.org.model.Org; +import io.apiman.cli.command.common.command.ModelAction; +import io.apiman.cli.command.org.model.Org; /** * @author Pete Cornish {@literal } diff --git a/src/main/java/io/apiman/cli/core/org/command/OrgCommand.java b/src/main/java/io/apiman/cli/command/org/command/OrgCommand.java similarity index 71% rename from src/main/java/io/apiman/cli/core/org/command/OrgCommand.java rename to src/main/java/io/apiman/cli/command/org/command/OrgCommand.java index d75b2a3..c564e5d 100644 --- a/src/main/java/io/apiman/cli/core/org/command/OrgCommand.java +++ b/src/main/java/io/apiman/cli/command/org/command/OrgCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,11 +14,13 @@ * limitations under the License. */ -package io.apiman.cli.core.org.command; +package io.apiman.cli.command.org.command; -import io.apiman.cli.command.AbstractCommand; -import io.apiman.cli.command.Command; +import io.apiman.cli.command.core.AbstractCommand; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.service.ManagementApiService; +import javax.inject.Inject; import java.util.Map; /** @@ -27,6 +29,11 @@ * @author Pete Cornish {@literal } */ public class OrgCommand extends AbstractCommand { + @Inject + public OrgCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected void populateCommands(Map> commandMap) { commandMap.put("create", OrgCreateCommand.class); diff --git a/src/main/java/io/apiman/cli/core/org/command/OrgCreateCommand.java b/src/main/java/io/apiman/cli/command/org/command/OrgCreateCommand.java similarity index 66% rename from src/main/java/io/apiman/cli/core/org/command/OrgCreateCommand.java rename to src/main/java/io/apiman/cli/command/org/command/OrgCreateCommand.java index 0c302d6..c1585f2 100644 --- a/src/main/java/io/apiman/cli/core/org/command/OrgCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/org/command/OrgCreateCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,29 +14,35 @@ * limitations under the License. */ -package io.apiman.cli.core.org.command; +package io.apiman.cli.command.org.command; -import io.apiman.cli.core.common.command.ModelCreateCommand; -import io.apiman.cli.core.org.OrgApi; -import io.apiman.cli.core.org.OrgMixin; +import io.apiman.cli.command.common.command.ModelCreateCommand; +import io.apiman.cli.command.org.OrgApi; +import io.apiman.cli.command.org.OrgMixin; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.org.model.Org; +import io.apiman.cli.command.org.model.Org; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; + /** * Create an organisation. * * @author Pete Cornish {@literal } */ -public class OrgCreateCommand extends ModelCreateCommand - implements OrgMixin { - +public class OrgCreateCommand extends ModelCreateCommand implements OrgMixin { @Option(name = "--name", aliases = {"-n"}, usage = "Name", required = true) private String name; @Option(name = "--description", aliases = {"-d"}, usage = "Description") private String description; + @Inject + public OrgCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected Org buildModelInstance() throws CommandException { return new Org(name, description); diff --git a/src/main/java/io/apiman/cli/core/org/command/OrgShowCommand.java b/src/main/java/io/apiman/cli/command/org/command/OrgShowCommand.java similarity index 65% rename from src/main/java/io/apiman/cli/core/org/command/OrgShowCommand.java rename to src/main/java/io/apiman/cli/command/org/command/OrgShowCommand.java index f400b84..f8f5405 100644 --- a/src/main/java/io/apiman/cli/core/org/command/OrgShowCommand.java +++ b/src/main/java/io/apiman/cli/command/org/command/OrgShowCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,28 +14,32 @@ * limitations under the License. */ -package io.apiman.cli.core.org.command; +package io.apiman.cli.command.org.command; -import io.apiman.cli.core.common.command.ModelShowCommand; -import io.apiman.cli.core.org.OrgApi; -import io.apiman.cli.core.org.OrgMixin; +import io.apiman.cli.command.common.command.ModelShowCommand; +import io.apiman.cli.command.org.OrgApi; +import io.apiman.cli.command.org.OrgMixin; +import io.apiman.cli.command.org.model.Org; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.org.model.Org; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; + /** * Show an organisation. * * @author Pete Cornish {@literal } */ public class OrgShowCommand extends ModelShowCommand implements OrgMixin { - private static final Logger LOGGER = LogManager.getLogger(OrgShowCommand.class); - @Option(name = "--name", aliases = {"-n"}, usage = "Name") private String name; + @Inject + public OrgShowCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getModelId() throws CommandException { return name; diff --git a/src/main/java/io/apiman/cli/core/org/model/Org.java b/src/main/java/io/apiman/cli/command/org/model/Org.java similarity index 90% rename from src/main/java/io/apiman/cli/core/org/model/Org.java rename to src/main/java/io/apiman/cli/command/org/model/Org.java index 3da59dd..9bb5a47 100644 --- a/src/main/java/io/apiman/cli/core/org/model/Org.java +++ b/src/main/java/io/apiman/cli/command/org/model/Org.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.org.model; +package io.apiman.cli.command.org.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/plugin/PluginApi.java b/src/main/java/io/apiman/cli/command/plugin/PluginApi.java similarity index 84% rename from src/main/java/io/apiman/cli/core/plugin/PluginApi.java rename to src/main/java/io/apiman/cli/command/plugin/PluginApi.java index bb8d1ec..91a7c87 100644 --- a/src/main/java/io/apiman/cli/core/plugin/PluginApi.java +++ b/src/main/java/io/apiman/cli/command/plugin/PluginApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,9 +14,9 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin; +package io.apiman.cli.command.plugin; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.command.plugin.model.Plugin; import retrofit.client.Response; import retrofit.http.*; diff --git a/src/main/java/io/apiman/cli/core/plugin/PluginMixin.java b/src/main/java/io/apiman/cli/command/plugin/PluginMixin.java similarity index 79% rename from src/main/java/io/apiman/cli/core/plugin/PluginMixin.java rename to src/main/java/io/apiman/cli/command/plugin/PluginMixin.java index 4746326..a8ff94c 100644 --- a/src/main/java/io/apiman/cli/core/plugin/PluginMixin.java +++ b/src/main/java/io/apiman/cli/command/plugin/PluginMixin.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,10 +14,10 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin; +package io.apiman.cli.command.plugin; -import io.apiman.cli.core.common.command.ModelAction; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.command.common.command.ModelAction; +import io.apiman.cli.command.plugin.model.Plugin; /** * @author Pete Cornish {@literal } diff --git a/src/main/java/io/apiman/cli/core/plugin/command/PluginAddCommand.java b/src/main/java/io/apiman/cli/command/plugin/command/PluginAddCommand.java similarity index 72% rename from src/main/java/io/apiman/cli/core/plugin/command/PluginAddCommand.java rename to src/main/java/io/apiman/cli/command/plugin/command/PluginAddCommand.java index 806b9a3..47a5865 100644 --- a/src/main/java/io/apiman/cli/core/plugin/command/PluginAddCommand.java +++ b/src/main/java/io/apiman/cli/command/plugin/command/PluginAddCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,15 +14,17 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin.command; +package io.apiman.cli.command.plugin.command; -import io.apiman.cli.core.common.command.ModelCreateCommand; +import io.apiman.cli.command.common.command.ModelCreateCommand; +import io.apiman.cli.command.plugin.PluginApi; +import io.apiman.cli.command.plugin.PluginMixin; +import io.apiman.cli.command.plugin.model.Plugin; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.plugin.PluginApi; -import io.apiman.cli.core.plugin.PluginMixin; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; import java.text.MessageFormat; /** @@ -30,9 +32,7 @@ * * @author Pete Cornish {@literal } */ -public class PluginAddCommand extends ModelCreateCommand - implements PluginMixin { - +public class PluginAddCommand extends ModelCreateCommand implements PluginMixin { @Option(name = "--groupId", aliases = {"-g"}, usage = "Group ID", required = true) private String groupId; @@ -45,6 +45,11 @@ public class PluginAddCommand extends ModelCreateCommand @Option(name = "--classifier", aliases = {"-c"}, usage = "Classifier") private String classifier; + @Inject + public PluginAddCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getCommandDescription() { return MessageFormat.format("Add {0}", getModelName()); diff --git a/src/main/java/io/apiman/cli/core/plugin/command/PluginCommand.java b/src/main/java/io/apiman/cli/command/plugin/command/PluginCommand.java similarity index 71% rename from src/main/java/io/apiman/cli/core/plugin/command/PluginCommand.java rename to src/main/java/io/apiman/cli/command/plugin/command/PluginCommand.java index d858ab6..760146c 100644 --- a/src/main/java/io/apiman/cli/core/plugin/command/PluginCommand.java +++ b/src/main/java/io/apiman/cli/command/plugin/command/PluginCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,11 +14,13 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin.command; +package io.apiman.cli.command.plugin.command; -import io.apiman.cli.command.AbstractCommand; -import io.apiman.cli.command.Command; +import io.apiman.cli.command.core.AbstractCommand; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.service.ManagementApiService; +import javax.inject.Inject; import java.util.Map; /** @@ -27,6 +29,11 @@ * @author Pete Cornish {@literal } */ public class PluginCommand extends AbstractCommand { + @Inject + public PluginCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected void populateCommands(Map> commandMap) { commandMap.put("add", PluginAddCommand.class); diff --git a/src/main/java/io/apiman/cli/command/plugin/command/PluginListCommand.java b/src/main/java/io/apiman/cli/command/plugin/command/PluginListCommand.java new file mode 100644 index 0000000..8f5d0a4 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/plugin/command/PluginListCommand.java @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.plugin.command; + +import io.apiman.cli.command.common.command.ModelListCommand; +import io.apiman.cli.command.plugin.PluginApi; +import io.apiman.cli.command.plugin.PluginMixin; +import io.apiman.cli.command.plugin.model.Plugin; +import io.apiman.cli.service.ManagementApiService; + +import javax.inject.Inject; + +/** + * List plugins. + * + * @author Pete Cornish {@literal } + */ +public class PluginListCommand extends ModelListCommand implements PluginMixin { + @Inject + public PluginListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } +} diff --git a/src/main/java/io/apiman/cli/core/plugin/command/PluginShowCommand.java b/src/main/java/io/apiman/cli/command/plugin/command/PluginShowCommand.java similarity index 62% rename from src/main/java/io/apiman/cli/core/plugin/command/PluginShowCommand.java rename to src/main/java/io/apiman/cli/command/plugin/command/PluginShowCommand.java index e774354..840a1a8 100644 --- a/src/main/java/io/apiman/cli/core/plugin/command/PluginShowCommand.java +++ b/src/main/java/io/apiman/cli/command/plugin/command/PluginShowCommand.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,26 +14,32 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin.command; +package io.apiman.cli.command.plugin.command; -import io.apiman.cli.core.common.command.ModelShowCommand; +import io.apiman.cli.command.common.command.ModelShowCommand; +import io.apiman.cli.command.plugin.PluginApi; +import io.apiman.cli.command.plugin.PluginMixin; +import io.apiman.cli.command.plugin.model.Plugin; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.core.plugin.PluginApi; -import io.apiman.cli.core.plugin.PluginMixin; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.service.ManagementApiService; import org.kohsuke.args4j.Option; +import javax.inject.Inject; + /** * Show a plugin. * * @author Pete Cornish {@literal } */ -public class PluginShowCommand extends ModelShowCommand - implements PluginMixin { - +public class PluginShowCommand extends ModelShowCommand implements PluginMixin { @Option(name = "--id", aliases = {"-i"}, usage = "Plugin ID") private String id; + @Inject + public PluginShowCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + @Override protected String getModelId() throws CommandException { return id; diff --git a/src/main/java/io/apiman/cli/core/plugin/model/Plugin.java b/src/main/java/io/apiman/cli/command/plugin/model/Plugin.java similarity index 93% rename from src/main/java/io/apiman/cli/core/plugin/model/Plugin.java rename to src/main/java/io/apiman/cli/command/plugin/model/Plugin.java index 9047d31..e84c099 100644 --- a/src/main/java/io/apiman/cli/core/plugin/model/Plugin.java +++ b/src/main/java/io/apiman/cli/command/plugin/model/Plugin.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin.model; +package io.apiman.cli.command.plugin.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/declarative/command/ApplyCommand.java b/src/main/java/io/apiman/cli/core/declarative/command/ApplyCommand.java deleted file mode 100644 index b3f1a69..0000000 --- a/src/main/java/io/apiman/cli/core/declarative/command/ApplyCommand.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright 2016 Pete Cornish - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.apiman.cli.core.declarative.command; - -import io.apiman.cli.command.AbstractFinalCommand; -import io.apiman.cli.core.api.VersionAgnosticApi; -import io.apiman.cli.core.api.model.*; -import io.apiman.cli.core.common.ActionApi; -import io.apiman.cli.core.common.model.ManagementApiVersion; -import io.apiman.cli.core.common.util.ServerActionUtil; -import io.apiman.cli.core.declarative.model.Declaration; -import io.apiman.cli.core.declarative.model.DeclarativeApi; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.gateway.model.Gateway; -import io.apiman.cli.core.org.OrgApi; -import io.apiman.cli.core.org.model.Org; -import io.apiman.cli.core.plugin.PluginApi; -import io.apiman.cli.core.plugin.model.Plugin; -import io.apiman.cli.exception.CommandException; -import io.apiman.cli.exception.DeclarativeException; -import io.apiman.cli.util.BeanUtil; -import io.apiman.cli.util.DeclarativeUtil; -import io.apiman.cli.util.MappingUtil; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.Option; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Properties; - -import static io.apiman.cli.util.Functions.of; -import static java.util.Optional.ofNullable; - -/** - * Applies an API environment declaration. - * - * @author Pete Cornish {@literal } - */ -public class ApplyCommand extends AbstractFinalCommand { - private static final Logger LOGGER = LogManager.getLogger(ApplyCommand.class); - private static final String JSON_EXTENSION = ".json"; - private static final String STATE_READY = "READY"; - private static final String STATE_PUBLISHED = "PUBLISHED"; - private static final String STATE_RETIRED = "RETIRED"; - - @Option(name = "--declarationFile", aliases = {"-f"}, usage = "Declaration file") - private Path declarationFile; - - @Option(name = "-P", usage = "Set property (key=value)") - private List properties; - - @Option(name = "--propertiesFile", usage = "Properties file") - private List propertiesFiles; - - @Option(name = "--serverVersion", aliases = {"-sv"}, usage = "Management API server version") - private ManagementApiVersion serverVersion = ManagementApiVersion.DEFAULT_VERSION; - - @Override - protected String getCommandDescription() { - return "Apply declaration"; - } - - @Override - public void performAction(CmdLineParser parser) throws CommandException { - applyDeclaration(); - } - - /** - * Load and then apply the Declaration. - */ - public void applyDeclaration() { - final Map parsedProperties = BeanUtil.parseReplacements(properties); - - // check for properties file - ofNullable(propertiesFiles).ifPresent(propertiesFiles -> propertiesFiles.forEach(propertiesFile -> { - LOGGER.trace("Loading properties file: {}", propertiesFile); - - final Properties fileProperties = new Properties(); - try (final InputStream propertiesIn = Files.newInputStream(propertiesFile, StandardOpenOption.READ)) { - if (propertiesFile.toAbsolutePath().toString().toLowerCase().endsWith(".xml")) { - fileProperties.loadFromXML(propertiesIn); - } else { - fileProperties.load(propertiesIn); - } - } catch (IOException e) { - throw new CommandException(String.format("Error loading properties file: %s", propertiesFile), e); - } - - fileProperties.forEach((key, value) -> parsedProperties.put((String) key, (String) value)); - })); - - final Declaration declaration; - - // parse declaration - if (declarationFile.endsWith(JSON_EXTENSION)) { - declaration = DeclarativeUtil.loadDeclaration(declarationFile, MappingUtil.JSON_MAPPER, parsedProperties); - } else { - // default is YAML - declaration = DeclarativeUtil.loadDeclaration(declarationFile, MappingUtil.YAML_MAPPER, parsedProperties); - } - - LOGGER.info("Loaded declaration: {}", declarationFile); - LOGGER.debug("Declaration loaded: {}", () -> MappingUtil.safeWriteValueAsJson(declaration)); - - try { - applyDeclaration(declaration); - } catch (Exception e) { - throw new CommandException("Error applying declaration", e); - } - } - - /** - * Apply the given Declaration. - * - * @param declaration the Declaration to apply. - */ - private void applyDeclaration(Declaration declaration) { - LOGGER.debug("Applying declaration"); - - // add gateways - applyGateways(declaration); - - // add plugins - applyPlugins(declaration); - - // add org - ofNullable(declaration.getOrg()).ifPresent(declarativeOrg -> { - final String orgName = declaration.getOrg().getName(); - final OrgApi orgApiClient = buildServerApiClient(OrgApi.class); - - of(DeclarativeUtil.checkExists(() -> orgApiClient.fetch(orgName))) - .ifPresent(existing -> { - LOGGER.info("Org already exists: {}", orgName); - }) - .ifNotPresent(() -> { - LOGGER.info("Adding org: {}", orgName); - orgApiClient.create(MappingUtil.map(declaration.getOrg(), Org.class)); - }); - - // add apis - applyApis(declaration, orgName); - }); - - LOGGER.info("Applied declaration"); - } - - /** - * Add gateways if they are not present. - * - * @param declaration the Declaration to apply. - */ - private void applyGateways(Declaration declaration) { - ofNullable(declaration.getSystem().getGateways()).ifPresent(gateways -> { - LOGGER.debug("Applying gateways"); - - gateways.forEach(declarativeGateway -> { - final GatewayApi apiClient = buildServerApiClient(GatewayApi.class); - final String gatewayName = declarativeGateway.getName(); - - of(DeclarativeUtil.checkExists(() -> apiClient.fetch(gatewayName))) - .ifPresent(existing -> { - LOGGER.info("Gateway already exists: {}", gatewayName); - }) - .ifNotPresent(() -> { - LOGGER.info("Adding gateway: {}", gatewayName); - - final Gateway gateway = MappingUtil.map(declarativeGateway, Gateway.class); - apiClient.create(gateway); - }); - }); - }); - } - - /** - * Add plugins if they are not present. - * - * @param declaration the Declaration to apply. - */ - private void applyPlugins(Declaration declaration) { - ofNullable(declaration.getSystem().getPlugins()).ifPresent(plugins -> { - LOGGER.debug("Applying plugins"); - - plugins.forEach(plugin -> { - final PluginApi apiClient = buildServerApiClient(PluginApi.class); - - if (checkPluginExists(plugin, apiClient)) { - LOGGER.info("Plugin already installed: {}", plugin.getName()); - } else { - LOGGER.info("Installing plugin: {}", plugin.getName()); - apiClient.create(plugin); - } - }); - }); - } - - /** - * Determine if the plugin is installed. - * - * @param plugin - * @param apiClient - * @return true if the plugin is installed, otherwise false - */ - private boolean checkPluginExists(Plugin plugin, PluginApi apiClient) { - return DeclarativeUtil.checkExists(apiClient::list) - .map(apiPolicies -> apiPolicies.stream() - .anyMatch(installedPlugin -> - plugin.getArtifactId().equals(installedPlugin.getArtifactId()) && - plugin.getGroupId().equals(installedPlugin.getGroupId()) && - plugin.getVersion().equals(installedPlugin.getVersion()) && - BeanUtil.safeEquals(plugin.getClassifier(), installedPlugin.getClassifier()) - )) - .orElse(false); - } - - /** - * Add and configure APIs if they are not present. - * - * @param declaration the Declaration to apply. - * @param orgName - */ - private void applyApis(Declaration declaration, String orgName) { - ofNullable(declaration.getOrg().getApis()).ifPresent(declarativeApis -> { - LOGGER.debug("Applying APIs"); - - declarativeApis.forEach(declarativeApi -> { - final VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); - final String apiName = declarativeApi.getName(); - - // determine the version of the API being configured - ofNullable(declarativeApi.getInitialVersion()).ifPresent(v -> - LOGGER.warn("Use of 'initialVersion' is deprecated and will be removed in future - use 'version' instead.")); - - final String apiVersion = ofNullable(declarativeApi.getVersion()).orElse(declarativeApi.getInitialVersion()); - - // create and configure API - applyApi(apiClient, declarativeApi, orgName, apiName, apiVersion); - - // add policies - applyPolicies(apiClient, declarativeApi, orgName, apiName, apiVersion); - - // publish API - if (declarativeApi.isPublished()) { - publish(apiClient, orgName, apiName, apiVersion); - } - }); - }); - } - - /** - * Add and configure the API if it is not present. - * - * @param apiClient - * @param declarativeApi - * @param orgName - * @param apiName - * @param apiVersion - * @return the state of the API - */ - private void applyApi(VersionAgnosticApi apiClient, DeclarativeApi declarativeApi, String orgName, - String apiName, String apiVersion) { - - LOGGER.debug("Applying API: {}", apiName); - - // base API - of(DeclarativeUtil.checkExists(() -> apiClient.fetch(orgName, apiName))) - .ifPresent(existing -> { - LOGGER.info("API '{}' already exists", apiName); - }) - .ifNotPresent(() -> { - LOGGER.info("Adding '{}' API", apiName); - final Api api = MappingUtil.map(declarativeApi, Api.class); - - // IMPORTANT: don't include version in the creation request - api.setInitialVersion(null); - api.setVersion(null); - - // create API *without* version - apiClient.create(orgName, api); - }); - - // API version - of(DeclarativeUtil.checkExists(() -> apiClient.fetchVersion(orgName, apiName, apiVersion))) - .ifPresent(existing -> { - LOGGER.info("API '{}' version '{}' already exists", apiName, apiVersion); - }) - .ifNotPresent(() -> { - LOGGER.info("Adding API '{}' version '{}'", apiName, apiVersion); - - // create version - final ApiVersion apiVersionWrapper = new ApiVersion(apiVersion); - apiClient.createVersion(orgName, apiName, apiVersionWrapper); - - if (ManagementApiVersion.v11x.equals(serverVersion)) { - // do this only on initial creation as v1.1.x API throws a 409 if this is called more than once - configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); - } - }); - - if (ManagementApiVersion.v12x.equals(serverVersion)) { - // The v1.2.x API supports configuration of the API even if published (but not retired) - final String apiState = fetchCurrentState(apiClient, orgName, apiName, apiVersion); - if (STATE_RETIRED.equals(apiState.toUpperCase())) { - LOGGER.warn("API '{}' is retired - skipping configuration", apiName); - - } else { - configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); - } - } - } - - /** - * Return the current state of the API. - * - * @param apiClient - * @param orgName - * @param apiName - * @param apiVersion - * @return the API state - */ - private String fetchCurrentState(VersionAgnosticApi apiClient, String orgName, String apiName, String apiVersion) { - final String apiState = ofNullable(apiClient.fetchVersion(orgName, apiName, apiVersion).getStatus()).orElse(""); - LOGGER.debug("API '{}' state: {}", apiName, apiState); - return apiState; - } - - /** - * Configures the API using the declarative API configuration. - * - * @param declarativeApi - * @param apiClient - * @param orgName - * @param apiName - * @param apiVersion - */ - private void configureApi(DeclarativeApi declarativeApi, VersionAgnosticApi apiClient, - String orgName, String apiName, String apiVersion) { - - LOGGER.info("Configuring API: {}", apiName); - - final ApiConfig apiConfig = MappingUtil.map(declarativeApi.getConfig(), ApiConfig.class); - - // map security configuration to endpoint properties - ofNullable(declarativeApi.getConfig().getSecurity()) - .ifPresent(securityConfig -> apiConfig.setEndpointProperties( - MappingUtil.map(securityConfig, EndpointProperties.class))); - - apiClient.configure(orgName, apiName, apiVersion, apiConfig); - } - - /** - * Add policies to the API if they are not present. - * - * @param apiClient - * @param declarativeApi - * @param orgName - * @param apiName - * @param apiVersion - */ - private void applyPolicies(VersionAgnosticApi apiClient, DeclarativeApi declarativeApi, String orgName, - String apiName, String apiVersion) { - - ofNullable(declarativeApi.getPolicies()).ifPresent(declarativePolicies -> { - LOGGER.debug("Applying policies to API: {}", apiName); - - // existing policies for the API - final List apiPolicies = apiClient.fetchPolicies(orgName, apiName, apiVersion); - - declarativePolicies.forEach(declarativePolicy -> { - final String policyName = declarativePolicy.getName(); - - final ApiPolicy apiPolicy = new ApiPolicy( - MappingUtil.safeWriteValueAsJson(declarativePolicy.getConfig())); - - // determine if the policy already exists for this API - final Optional existingPolicy = apiPolicies.stream() - .filter(p -> policyName.equals(p.getPolicyDefinitionId())) - .findFirst(); - - if (existingPolicy.isPresent()) { - if (ManagementApiVersion.v12x.equals(serverVersion)) { - // update the existing policy config - LOGGER.info("Updating existing policy '{}' configuration for API: {}", policyName, apiName); - - final Long policyId = existingPolicy.get().getId(); - apiClient.configurePolicy(orgName, apiName, apiVersion, policyId, apiPolicy); - - } else { - LOGGER.info("Policy '{}' already exists for API '{}' - skipping configuration update", policyName, apiName); - } - - } else { - // add new policy - LOGGER.info("Adding policy '{}' to API: {}", policyName, apiName); - - apiPolicy.setDefinitionId(policyName); - apiClient.addPolicy(orgName, apiName, apiVersion, apiPolicy); - } - }); - }); - } - - /** - * Publish the API, if it is in the 'Ready' state. - * - * @param apiClient - * @param orgName - * @param apiName - * @param apiVersion - */ - private void publish(VersionAgnosticApi apiClient, String orgName, String apiName, String apiVersion) { - LOGGER.debug("Attempting to publish API: {}", apiName); - final String apiState = fetchCurrentState(apiClient, orgName, apiName, apiVersion); - - switch (apiState.toUpperCase()) { - case STATE_READY: - performPublish(orgName, apiName, apiVersion); - break; - - case STATE_PUBLISHED: - switch (serverVersion) { - case v11x: - LOGGER.info("API '{}' already published - skipping republish", apiName); - break; - - case v12x: - LOGGER.info("Republishing API: {}", apiName); - performPublish(orgName, apiName, apiVersion); - break; - } - break; - - default: - throw new DeclarativeException(String.format( - "Unable to publish API '%s' in state: %s", apiName, apiState)); - } - } - - /** - * Trigger the publish action for the given API. - * - * @param orgName - * @param apiName - * @param apiVersion - */ - private void performPublish(String orgName, String apiName, String apiVersion) { - LOGGER.info("Publishing API: {}", apiName); - ServerActionUtil.publishApi(orgName, apiName, apiVersion, serverVersion, buildServerApiClient(ActionApi.class)); - } - - public void setDeclarationFile(Path declarationFile) { - this.declarationFile = declarationFile; - } - - public void setProperties(List properties) { - this.properties = properties; - } - - public void setPropertiesFiles(List propertiesFiles) { - this.propertiesFiles = propertiesFiles; - } - - public void setServerAddress(String serverAddress) { - this.serverAddress = serverAddress; - } - - public void setServerVersion(ManagementApiVersion serverVersion) { - this.serverVersion = serverVersion; - } -} diff --git a/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java b/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java index b835863..49c561b 100644 --- a/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java +++ b/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,18 @@ import com.google.inject.AbstractModule; import com.google.inject.Singleton; -import io.apiman.cli.core.api.factory.Version11XManagementApiFactoryImpl; -import io.apiman.cli.core.api.factory.Version12XManagementApiFactoryImpl; -import io.apiman.cli.core.api.VersionAgnosticApi; -import io.apiman.cli.core.common.ActionApi; -import io.apiman.cli.core.common.model.ManagementApiVersion; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.org.OrgApi; -import io.apiman.cli.core.plugin.PluginApi; +import io.apiman.cli.command.api.factory.Version11XManagementApiFactoryImpl; +import io.apiman.cli.command.api.factory.Version12XManagementApiFactoryImpl; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.common.ActionApi; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.org.OrgApi; +import io.apiman.cli.command.plugin.PluginApi; import io.apiman.cli.management.binding.ManagementApiBindings; import io.apiman.cli.management.factory.ManagementApiFactory; import io.apiman.cli.management.factory.SimpleManagementApiFactoryImpl; +import io.apiman.cli.management.api.StatusApi; /** * Bindings for Management API factories. @@ -38,6 +39,10 @@ public class ManagementApiFactoryModule extends AbstractModule { @Override protected void configure() { + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(StatusApi.class)) + .toInstance(new SimpleManagementApiFactoryImpl<>(StatusApi.class)); + bind(ManagementApiFactory.class) .annotatedWith(ManagementApiBindings.boundTo(GatewayApi.class)) .toInstance(new SimpleManagementApiFactoryImpl<>(GatewayApi.class)); diff --git a/src/main/java/io/apiman/cli/management/ManagementApiUtil.java b/src/main/java/io/apiman/cli/management/ManagementApiUtil.java index 422c8ee..c1adcf8 100644 --- a/src/main/java/io/apiman/cli/management/ManagementApiUtil.java +++ b/src/main/java/io/apiman/cli/management/ManagementApiUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ package io.apiman.cli.management; import com.google.common.io.CharStreams; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.Key; -import io.apiman.cli.core.common.model.ManagementApiVersion; import io.apiman.cli.exception.CommandException; -import io.apiman.cli.management.binding.ManagementApiBindings; -import io.apiman.cli.management.factory.ManagementApiFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import retrofit.RetrofitError; @@ -33,8 +27,12 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; +import java.util.Optional; import java.util.function.Supplier; +import static java.util.Optional.empty; +import static java.util.Optional.ofNullable; + /** * Shared Management API utility methods. * @@ -42,8 +40,6 @@ */ public class ManagementApiUtil { private static final Logger LOGGER = LogManager.getLogger(ManagementApiUtil.class); - private static boolean factoriesInitialised; - private static Injector apiFactories; public static void invokeAndCheckResponse(Supplier request) throws CommandException { invokeAndCheckResponse(HttpURLConnection.HTTP_OK, request); @@ -84,39 +80,27 @@ private static void httpError(int expectedStatus, Response response) throws Comm } /** - * @param clazz the Class for which to build a client - * @param username the management API username - * @param password the management API password - * @param debugLogging whether debug logging should be enabled - * @param serverVersion the server version - * @param the API interface - * @return an API client for the given Class + * Check for the presence of an item using the given Supplier. + * + * @param supplier the Supplier of the item + * @param + * @return the item or {@link Optional#empty()} */ - @SuppressWarnings("unchecked") - public static T buildServerApiClient(Class clazz, String endpoint, String username, - String password, boolean debugLogging, ManagementApiVersion serverVersion) { - - if (!factoriesInitialised) { - LOGGER.trace("Initialising API factories"); - apiFactories = Guice.createInjector(new ManagementApiFactoryModule()); - factoriesInitialised = true; - } - - // locate the Management API factory - final ManagementApiFactory managementApiFactory; + public static Optional checkExists(Supplier supplier) { try { - managementApiFactory = apiFactories.getInstance( - Key.get(ManagementApiFactory.class, ManagementApiBindings.boundTo(clazz, serverVersion))); + // attempt to return the item + return ofNullable(supplier.get()); - } catch (Exception e) { - throw new CommandException(String.format( - "Error locating API factory for %s, with server version %s", clazz, serverVersion), e); - } + } catch (RetrofitError re) { + // 404 indicates the item does not exist - anything else is an error + if (ofNullable(re.getResponse()) + .filter(response -> HttpURLConnection.HTTP_NOT_FOUND == response.getStatus()) + .isPresent()) { - LOGGER.debug("Located API factory {} for {}, with server version {}", - managementApiFactory.getClass(), clazz, serverVersion); + return empty(); + } - // use the factory to construct the Management API client - return (T) managementApiFactory.build(endpoint, username, password, debugLogging); + throw new CommandException("Error checking for existence of existing item", re); + } } } diff --git a/src/main/java/io/apiman/cli/core/plugin/command/PluginListCommand.java b/src/main/java/io/apiman/cli/management/api/StatusApi.java similarity index 57% rename from src/main/java/io/apiman/cli/core/plugin/command/PluginListCommand.java rename to src/main/java/io/apiman/cli/management/api/StatusApi.java index 94b2722..b605b18 100644 --- a/src/main/java/io/apiman/cli/core/plugin/command/PluginListCommand.java +++ b/src/main/java/io/apiman/cli/management/api/StatusApi.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,18 +14,17 @@ * limitations under the License. */ -package io.apiman.cli.core.plugin.command; +package io.apiman.cli.management.api; -import io.apiman.cli.core.common.command.ModelListCommand; -import io.apiman.cli.core.plugin.PluginApi; -import io.apiman.cli.core.plugin.PluginMixin; -import io.apiman.cli.core.plugin.model.Plugin; +import retrofit.client.Response; +import retrofit.http.GET; /** - * List plugins. + * Models the status check API. * * @author Pete Cornish {@literal } */ -public class PluginListCommand extends ModelListCommand - implements PluginMixin { +public interface StatusApi { + @GET("/system/status") + Response checkStatus(); } diff --git a/src/main/java/io/apiman/cli/management/binding/ManagementApiBinding.java b/src/main/java/io/apiman/cli/management/binding/ManagementApiBinding.java index 94625b0..d47f009 100644 --- a/src/main/java/io/apiman/cli/management/binding/ManagementApiBinding.java +++ b/src/main/java/io/apiman/cli/management/binding/ManagementApiBinding.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package io.apiman.cli.management.binding; import com.google.inject.BindingAnnotation; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.model.ManagementApiVersion; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/io/apiman/cli/management/binding/ManagementApiBindingImpl.java b/src/main/java/io/apiman/cli/management/binding/ManagementApiBindingImpl.java index 921286c..c1a8ef3 100644 --- a/src/main/java/io/apiman/cli/management/binding/ManagementApiBindingImpl.java +++ b/src/main/java/io/apiman/cli/management/binding/ManagementApiBindingImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Objects; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.model.ManagementApiVersion; import java.lang.annotation.Annotation; diff --git a/src/main/java/io/apiman/cli/management/binding/ManagementApiBindings.java b/src/main/java/io/apiman/cli/management/binding/ManagementApiBindings.java index 3832399..3327071 100644 --- a/src/main/java/io/apiman/cli/management/binding/ManagementApiBindings.java +++ b/src/main/java/io/apiman/cli/management/binding/ManagementApiBindings.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package io.apiman.cli.management.binding; -import io.apiman.cli.core.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.model.ManagementApiVersion; /** * Convenience methods for instantiating {@link ManagementApiBinding}s. diff --git a/src/main/java/io/apiman/cli/service/ApiService.java b/src/main/java/io/apiman/cli/service/ApiService.java new file mode 100644 index 0000000..d1a8b37 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/ApiService.java @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.common.model.ManagementApiVersion; + +/** + * Manages APIs. + * + * @author Pete Cornish {@literal } + */ +public interface ApiService { + String STATE_READY = "READY"; + String STATE_PUBLISHED = "PUBLISHED"; + String STATE_RETIRED = "RETIRED"; + + /** + * Return the current state of the API. + * + * @param serverVersion the management server API version + * @param orgName the organisation name + * @param apiName the API name + * @param apiVersion the API version + * @return the API state + */ + String fetchCurrentState(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion); + + /** + * Publish the API, if it is in the 'Ready' state. + * + * @param serverVersion the management server API version + * @param orgName the organisation name + * @param apiName the API name + * @param apiVersion the API version + */ + void publish(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion); +} diff --git a/src/main/java/io/apiman/cli/service/ApiServiceImpl.java b/src/main/java/io/apiman/cli/service/ApiServiceImpl.java new file mode 100644 index 0000000..48da3e8 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/ApiServiceImpl.java @@ -0,0 +1,102 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.common.ActionApi; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.common.util.ServerActionUtil; +import io.apiman.cli.exception.CommandException; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +import static java.util.Optional.ofNullable; + +/** + * Manages APIs. + * + * @author Pete Cornish {@literal } + */ +public class ApiServiceImpl implements ApiService { + private static final Logger LOGGER = LogManager.getLogger(ApiServiceImpl.class); + + private ManagementApiService managementApiService; + + @Inject + public ApiServiceImpl(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } + + /** + * {@inheritDoc} + */ + @Override + public String fetchCurrentState(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { + final VersionAgnosticApi apiClient = managementApiService.buildServerApiClient(VersionAgnosticApi.class, serverVersion); + + final String apiState = ofNullable(apiClient.fetchVersion(orgName, apiName, apiVersion).getStatus()).orElse(""); + LOGGER.debug("API '{}' state: {}", apiName, apiState); + return apiState; + } + + /** + * {@inheritDoc} + */ + @Override + public void publish(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { + LOGGER.debug("Attempting to publish API: {}", apiName); + final String apiState = fetchCurrentState(serverVersion, orgName, apiName, apiVersion); + + switch (apiState.toUpperCase()) { + case STATE_READY: + performPublish(serverVersion, orgName, apiName, apiVersion); + break; + + case STATE_PUBLISHED: + switch (serverVersion) { + case v11x: + LOGGER.info("API '{}' already published - skipping republish", apiName); + break; + + case v12x: + LOGGER.info("Republishing API: {}", apiName); + performPublish(serverVersion, orgName, apiName, apiVersion); + break; + } + break; + + default: + throw new CommandException(String.format( + "Unable to publish API '%s' in state: %s", apiName, apiState)); + } + } + + /** + * Trigger the publish action for the given API. + * + * @param orgName + * @param apiName + * @param apiVersion + */ + private void performPublish(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { + LOGGER.info("Publishing API: {}", apiName); + ServerActionUtil.publishApi(orgName, apiName, apiVersion, serverVersion, + managementApiService.buildServerApiClient(ActionApi.class)); + } +} diff --git a/src/main/java/io/apiman/cli/service/DeclarativeService.java b/src/main/java/io/apiman/cli/service/DeclarativeService.java new file mode 100644 index 0000000..90045f3 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/DeclarativeService.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.declarative.model.DeclarativeApi; +import io.apiman.cli.command.declarative.model.DeclarativeGateway; +import io.apiman.cli.command.declarative.model.DeclarativeOrg; + +import java.util.List; + +/** + * Applies changes in a declarative fashion. + * + * @author Pete Cornish {@literal } + */ +public interface DeclarativeService { + /** + * Add gateways if they are not present. + * + * @param gateways the gateways to add. + */ + void applyGateways(List gateways); + + /** + * Add the organisation if it is not present. + * + * @param org the organisation to add. + */ + void applyOrg(DeclarativeOrg org); + + /** + * Add APIs to the specified organisation, if they are not present, then configure them. + * + * @param serverVersion the management server version. + * @param apis the APIs to add. + * @param orgName the name of the organisation. + */ + void applyApis(ManagementApiVersion serverVersion, List apis, String orgName); +} diff --git a/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java new file mode 100644 index 0000000..48f3665 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java @@ -0,0 +1,250 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.*; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.declarative.model.DeclarativeApi; +import io.apiman.cli.command.declarative.model.DeclarativeGateway; +import io.apiman.cli.command.declarative.model.DeclarativeOrg; +import io.apiman.cli.command.gateway.GatewayApi; +import io.apiman.cli.command.gateway.model.Gateway; +import io.apiman.cli.command.org.OrgApi; +import io.apiman.cli.command.org.model.Org; +import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.util.MappingUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.util.List; + +import static io.apiman.cli.command.common.model.ManagementApiVersion.v11x; +import static io.apiman.cli.command.common.model.ManagementApiVersion.v12x; +import static io.apiman.cli.util.Functions.of; +import static java.util.Optional.ofNullable; + +/** + * Applies changes in a declarative fashion. + * + * @author Pete Cornish {@literal } + */ +public class DeclarativeServiceImpl implements DeclarativeService { + private static final Logger LOGGER = LogManager.getLogger(DeclarativeServiceImpl.class); + + private ManagementApiService managementApiService; + private ApiService apiService; + private PolicyService policyService; + + @Inject + public DeclarativeServiceImpl(ManagementApiService managementApiService, + ApiService apiService, PolicyService policyService) { + + this.managementApiService = managementApiService; + this.apiService = apiService; + this.policyService = policyService; + } + + /** + * {@inheritDoc} + */ + @Override + public void applyGateways(List gateways) { + LOGGER.debug("Applying gateways"); + + gateways.forEach(declarativeGateway -> { + final GatewayApi apiClient = managementApiService.buildServerApiClient(GatewayApi.class); + final String gatewayName = declarativeGateway.getName(); + + of(ManagementApiUtil.checkExists(() -> apiClient.fetch(gatewayName))) + .ifPresent(existing -> { + LOGGER.info("Gateway already exists: {}", gatewayName); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding gateway: {}", gatewayName); + + final Gateway gateway = MappingUtil.map(declarativeGateway, Gateway.class); + apiClient.create(gateway); + }); + }); + } + + /** + * {@inheritDoc} + */ + @Override + public void applyOrg(DeclarativeOrg org) { + LOGGER.debug("Applying org"); + + final String orgName = org.getName(); + final OrgApi orgApiClient = managementApiService.buildServerApiClient(OrgApi.class); + + of(ManagementApiUtil.checkExists(() -> orgApiClient.fetch(orgName))) + .ifPresent(existing -> { + LOGGER.info("Org already exists: {}", orgName); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding org: {}", orgName); + orgApiClient.create(MappingUtil.map(org, Org.class)); + }); + } + + /** + * {@inheritDoc} + */ + @Override + public void applyApis(ManagementApiVersion serverVersion, List apis, String orgName) { + LOGGER.debug("Applying APIs"); + + apis.forEach(declarativeApi -> { + final VersionAgnosticApi apiClient = managementApiService.buildServerApiClient(VersionAgnosticApi.class, serverVersion); + final String apiName = declarativeApi.getName(); + + // determine the version of the API being configured + ofNullable(declarativeApi.getInitialVersion()).ifPresent(v -> + LOGGER.warn("Use of 'initialVersion' is deprecated and will be removed in future - use 'version' instead.")); + + final String apiVersion = ofNullable(declarativeApi.getVersion()).orElse(declarativeApi.getInitialVersion()); + + // create and configure API + applyApi(serverVersion, apiClient, declarativeApi, orgName, apiName, apiVersion); + + // add policies + applyPolicies(serverVersion, declarativeApi, orgName, apiName, apiVersion); + + // publish API + if (declarativeApi.isPublished()) { + apiService.publish(serverVersion, orgName, apiName, apiVersion); + } + }); + } + + /** + * Add the API, if it is not present, then configure it. + * + * @param apiClient + * @param declarativeApi + * @param orgName + * @param apiName + * @param apiVersion + * @return the state of the API + */ + private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi apiClient, + DeclarativeApi declarativeApi, String orgName, String apiName, String apiVersion) { + + LOGGER.debug("Applying API: {}", apiName); + + // base API + of(ManagementApiUtil.checkExists(() -> apiClient.fetch(orgName, apiName))) + .ifPresent(existing -> { + LOGGER.info("API '{}' already exists", apiName); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding '{}' API", apiName); + final Api api = MappingUtil.map(declarativeApi, Api.class); + + // IMPORTANT: don't include version in the creation request + api.setInitialVersion(null); + api.setVersion(null); + + // create API *without* version + apiClient.create(orgName, api); + }); + + // API version + of(ManagementApiUtil.checkExists(() -> apiClient.fetchVersion(orgName, apiName, apiVersion))) + .ifPresent(existing -> { + LOGGER.info("API '{}' version '{}' already exists", apiName, apiVersion); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding API '{}' version '{}'", apiName, apiVersion); + + // create version + final ApiVersion apiVersionWrapper = new ApiVersion(apiVersion); + apiClient.createVersion(orgName, apiName, apiVersionWrapper); + + if (v11x.equals(serverVersion)) { + // do this only on initial creation as v1.1.x API throws a 409 if this is called more than once + configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); + } + }); + + if (v12x.equals(serverVersion)) { + // The v1.2.x API supports configuration of the API even if published (but not retired) + final String apiState = apiService.fetchCurrentState(serverVersion, orgName, apiName, apiVersion); + if (ApiService.STATE_RETIRED.equals(apiState.toUpperCase())) { + LOGGER.warn("API '{}' is retired - skipping configuration", apiName); + + } else { + configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); + } + } + } + + /** + * Configures the API using the declarative API configuration. + * + * @param declarativeApi + * @param apiClient + * @param orgName + * @param apiName + * @param apiVersion + */ + private void configureApi(DeclarativeApi declarativeApi, VersionAgnosticApi apiClient, + String orgName, String apiName, String apiVersion) { + + LOGGER.info("Configuring API: {}", apiName); + + final ApiConfig apiConfig = MappingUtil.map(declarativeApi.getConfig(), ApiConfig.class); + + // map security configuration to endpoint properties + ofNullable(declarativeApi.getConfig().getSecurity()) + .ifPresent(securityConfig -> apiConfig.setEndpointProperties( + MappingUtil.map(securityConfig, EndpointProperties.class))); + + apiClient.configure(orgName, apiName, apiVersion, apiConfig); + } + + /** + * Add policies to the API if they are not present. + * + * @param declarativeApi + * @param orgName + * @param apiName + * @param apiVersion + */ + private void applyPolicies(ManagementApiVersion serverVersion, DeclarativeApi declarativeApi, + String orgName, String apiName, String apiVersion) { + + ofNullable(declarativeApi.getPolicies()).ifPresent(declarativePolicies -> { + LOGGER.debug("Applying policies to API: {}", apiName); + + // existing policies for the API + final List apiPolicies = policyService.fetchPolicies(serverVersion, orgName, apiName, apiVersion); + + declarativePolicies.forEach(declarativePolicy -> { + final String policyName = declarativePolicy.getName(); + + final ApiPolicy apiPolicy = new ApiPolicy( + MappingUtil.safeWriteValueAsJson(declarativePolicy.getConfig())); + + policyService.applyPolicies(serverVersion, orgName, apiName, apiVersion, apiPolicies, policyName, apiPolicy); + }); + }); + } +} diff --git a/src/main/java/io/apiman/cli/service/ManagementApiService.java b/src/main/java/io/apiman/cli/service/ManagementApiService.java new file mode 100644 index 0000000..75fe5b2 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/ManagementApiService.java @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.common.model.ManagementApiVersion; + +/** + * Constructs management API clients. + * + * @author Pete Cornish {@literal } + */ +public interface ManagementApiService { + /** + * Configures the server's management API endpoint. + * + * @param serverAddress the URL of the management API + * @param serverUsername management API username + * @param serverPassword management API password + */ + void configureEndpoint(String serverAddress, String serverUsername, String serverPassword); + + /** + * @param clazz the Class for which to build a client + * @param the API interface + * @return an API client for the given Class + */ + T buildServerApiClient(Class clazz); + + /** + * @param clazz the Class for which to build a client + * @param serverVersion the server version + * @param the API interface + * @return an API client for the given Class + */ + T buildServerApiClient(Class clazz, ManagementApiVersion serverVersion); + + /** + * @param the API interface + * @param clazz the Class for which to build a client + * @param serverVersion the server version + * @param username the management API username + * @param password the management API password + * @param debugLogging whether debug logging should be enabled + * @return an API client for the given Class + */ + T buildServerApiClient(Class clazz, ManagementApiVersion serverVersion, String endpoint, String username, + String password, boolean debugLogging); + + /** + * Wait for the server to be ready. + * + * @param waitTime the time, in seconds, to wait + */ + void waitForServer(int waitTime); +} diff --git a/src/main/java/io/apiman/cli/service/ManagementApiServiceImpl.java b/src/main/java/io/apiman/cli/service/ManagementApiServiceImpl.java new file mode 100644 index 0000000..fc05f80 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/ManagementApiServiceImpl.java @@ -0,0 +1,141 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import com.google.inject.Key; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.management.api.StatusApi; +import io.apiman.cli.management.binding.ManagementApiBindings; +import io.apiman.cli.management.factory.ManagementApiFactory; +import io.apiman.cli.util.InjectionUtil; +import io.apiman.cli.util.LogUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import retrofit.client.Response; + +import java.net.HttpURLConnection; + +/** + * Constructs management API clients. + * + * @author Pete Cornish {@literal } + */ +public class ManagementApiServiceImpl implements ManagementApiService { + private static final Logger LOGGER = LogManager.getLogger(ManagementApiServiceImpl.class); + + /** + * Interval, in milliseconds, that the management API's status will be polled, whilst waiting + * for the server to be ready. + * + * @see #waitForServer(int) + */ + private static final long STATUS_CHECK_INTERVAL = 1000; + + private String serverAddress; + private String serverUsername; + private String serverPassword; + + /** + * {@inheritDoc} + */ + @Override + public void configureEndpoint(String serverAddress, String serverUsername, String serverPassword) { + this.serverAddress = serverAddress; + this.serverUsername = serverUsername; + this.serverPassword = serverPassword; + } + + /** + * {@inheritDoc} + */ + @Override + public T buildServerApiClient(Class clazz) { + return buildServerApiClient(clazz, ManagementApiVersion.UNSPECIFIED); + } + + /** + * {@inheritDoc} + */ + @Override + public T buildServerApiClient(Class clazz, ManagementApiVersion serverVersion) { + return buildServerApiClient( + clazz, + serverVersion, serverAddress, + serverUsername, + serverPassword, + LogUtil.isLogDebug() + ); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public T buildServerApiClient(Class clazz, ManagementApiVersion serverVersion, + String endpoint, String username, String password, boolean debugLogging) { + + // locate the Management API factory + final ManagementApiFactory managementApiFactory; + try { + managementApiFactory = InjectionUtil.getInjector().getInstance( + Key.get(ManagementApiFactory.class, ManagementApiBindings.boundTo(clazz, serverVersion))); + + } catch (Exception e) { + throw new CommandException(String.format( + "Error locating API factory for %s, with server version %s", clazz, serverVersion), e); + } + + LOGGER.debug("Located API factory {} for {}, with server version {}", + managementApiFactory.getClass(), clazz, serverVersion); + + // use the factory to construct the Management API client + return (T) managementApiFactory.build(endpoint, username, password, debugLogging); + } + + /** + * {@inheritDoc} + */ + @Override + public void waitForServer(int waitTime) { + if (waitTime == 0) { + return; + } + + LOGGER.info("Waiting {} seconds for server to start...", waitTime); + final StatusApi apiClient = buildServerApiClient(StatusApi.class); + + final long start = System.currentTimeMillis(); + while (true) { + if (System.currentTimeMillis() - start > waitTime * 1000) { + throw new CommandException("Timed out after " + waitTime + " seconds waiting for server to start"); + } + + try { + final Response response = apiClient.checkStatus(); + if (HttpURLConnection.HTTP_OK == response.getStatus()) { + LOGGER.info("Server started"); + break; + } + + Thread.sleep(STATUS_CHECK_INTERVAL); + } catch (Exception ignored) { + } + } + } +} diff --git a/src/main/java/io/apiman/cli/core/gateway/command/GatewayListCommand.java b/src/main/java/io/apiman/cli/service/PluginService.java similarity index 56% rename from src/main/java/io/apiman/cli/core/gateway/command/GatewayListCommand.java rename to src/main/java/io/apiman/cli/service/PluginService.java index 40fba0b..a24d848 100644 --- a/src/main/java/io/apiman/cli/core/gateway/command/GatewayListCommand.java +++ b/src/main/java/io/apiman/cli/service/PluginService.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,18 +14,22 @@ * limitations under the License. */ -package io.apiman.cli.core.gateway.command; +package io.apiman.cli.service; -import io.apiman.cli.core.common.command.ModelListCommand; -import io.apiman.cli.core.gateway.GatewayApi; -import io.apiman.cli.core.gateway.GatewayMixin; -import io.apiman.cli.core.gateway.model.Gateway; +import io.apiman.cli.command.plugin.model.Plugin; + +import java.util.List; /** - * List gateways. + * Manages plugins. * * @author Pete Cornish {@literal } */ -public class GatewayListCommand extends ModelListCommand - implements GatewayMixin { +public interface PluginService { + /** + * Add plugins if they are not present. + * + * @param plugins the plugins to add. + */ + void addPlugins(List plugins); } diff --git a/src/main/java/io/apiman/cli/service/PluginServiceImpl.java b/src/main/java/io/apiman/cli/service/PluginServiceImpl.java new file mode 100644 index 0000000..b7071a4 --- /dev/null +++ b/src/main/java/io/apiman/cli/service/PluginServiceImpl.java @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.plugin.PluginApi; +import io.apiman.cli.command.plugin.model.Plugin; +import io.apiman.cli.management.ManagementApiUtil; +import io.apiman.cli.util.BeanUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.util.List; + +/** + * Manages plugins. + * + * @author Pete Cornish {@literal } + */ +public class PluginServiceImpl implements PluginService { + private static final Logger LOGGER = LogManager.getLogger(PluginServiceImpl.class); + + private ManagementApiService managementApiService; + + @Inject + public PluginServiceImpl(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } + + /** + * {@inheritDoc} + */ + @Override + public void addPlugins(List plugins) { + LOGGER.debug("Adding plugins"); + + plugins.forEach(plugin -> { + final PluginApi apiClient = managementApiService.buildServerApiClient(PluginApi.class); + + if (checkPluginExists(plugin, apiClient)) { + LOGGER.info("Plugin already installed: {}", plugin.getName()); + } else { + LOGGER.info("Installing plugin: {}", plugin.getName()); + apiClient.create(plugin); + } + }); + } + + /** + * Determine if the plugin is installed. + * + * @param plugin + * @param apiClient + * @return true if the plugin is installed, otherwise false + */ + private boolean checkPluginExists(Plugin plugin, PluginApi apiClient) { + return ManagementApiUtil.checkExists(apiClient::list) + .map(apiPolicies -> apiPolicies.stream() + .anyMatch(installedPlugin -> + plugin.getArtifactId().equals(installedPlugin.getArtifactId()) && + plugin.getGroupId().equals(installedPlugin.getGroupId()) && + plugin.getVersion().equals(installedPlugin.getVersion()) && + BeanUtil.safeEquals(plugin.getClassifier(), installedPlugin.getClassifier()) + )) + .orElse(false); + } +} diff --git a/src/main/java/io/apiman/cli/service/PolicyService.java b/src/main/java/io/apiman/cli/service/PolicyService.java new file mode 100644 index 0000000..8bd961d --- /dev/null +++ b/src/main/java/io/apiman/cli/service/PolicyService.java @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.common.model.ManagementApiVersion; + +import java.util.List; + +/** + * Manages policies. + * + * @author Pete Cornish {@literal } + */ +public interface PolicyService { + /** + * Fetch the policies attached to the specified API. + * + * @param serverVersion the management server API version + * @param orgName the organisation name + * @param apiName the API name + * @param apiVersion the API version + * @return the policies + */ + List fetchPolicies(ManagementApiVersion serverVersion, String orgName, + String apiName, String apiVersion); + + /** + * Apply the policies to the specified API. + * + * @param serverVersion the management server API version + * @param orgName the organisation name + * @param apiName the API name + * @param apiVersion the API version + * @param apiPolicies the policies to apply. + * @param policyName the policy name + * @param apiPolicy the policy to apply + */ + void applyPolicies(ManagementApiVersion serverVersion, String orgName, + String apiName, String apiVersion, List apiPolicies, + String policyName, ApiPolicy apiPolicy); +} diff --git a/src/main/java/io/apiman/cli/service/PolicyServiceImpl.java b/src/main/java/io/apiman/cli/service/PolicyServiceImpl.java new file mode 100644 index 0000000..3f6af7a --- /dev/null +++ b/src/main/java/io/apiman/cli/service/PolicyServiceImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.common.model.ManagementApiVersion; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.util.List; +import java.util.Optional; + +import static io.apiman.cli.command.common.model.ManagementApiVersion.v12x; + +/** + * Manages policies. + * + * @author Pete Cornish {@literal } + */ +public class PolicyServiceImpl implements PolicyService { + private static final Logger LOGGER = LogManager.getLogger(PolicyServiceImpl.class); + + private ManagementApiService managementApiService; + + @Inject + public PolicyServiceImpl(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } + + /** + * {@inheritDoc} + */ + @Override + public List fetchPolicies(ManagementApiVersion serverVersion, String orgName, + String apiName, String apiVersion) { + + final VersionAgnosticApi apiClient = managementApiService.buildServerApiClient(VersionAgnosticApi.class, serverVersion); + return apiClient.fetchPolicies(orgName, apiName, apiVersion); + } + + /** + * {@inheritDoc} + */ + @Override + public void applyPolicies(ManagementApiVersion serverVersion, String orgName, + String apiName, String apiVersion, List apiPolicies, + String policyName, ApiPolicy apiPolicy) { + + final VersionAgnosticApi apiClient = managementApiService.buildServerApiClient(VersionAgnosticApi.class, serverVersion); + + // determine if the policy already exists for this API + final Optional existingPolicy = apiPolicies.stream() + .filter(p -> policyName.equals(p.getPolicyDefinitionId())) + .findFirst(); + + if (existingPolicy.isPresent()) { + if (v12x.equals(serverVersion)) { + // update the existing policy config + LOGGER.info("Updating existing policy '{}' configuration for API: {}", policyName, apiName); + + final Long policyId = existingPolicy.get().getId(); + apiClient.configurePolicy(orgName, apiName, apiVersion, policyId, apiPolicy); + + } else { + LOGGER.info("Policy '{}' already exists for API '{}' - skipping configuration update", policyName, apiName); + } + + } else { + // add new policy + LOGGER.info("Adding policy '{}' to API: {}", policyName, apiName); + + apiPolicy.setDefinitionId(policyName); + apiClient.addPolicy(orgName, apiName, apiVersion, apiPolicy); + } + } +} diff --git a/src/main/java/io/apiman/cli/service/ServiceModule.java b/src/main/java/io/apiman/cli/service/ServiceModule.java new file mode 100644 index 0000000..1cd786e --- /dev/null +++ b/src/main/java/io/apiman/cli/service/ServiceModule.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; + +/** + * Dependency injection configuration for services. + * + * @author Pete Cornish {@literal } + */ +public class ServiceModule extends AbstractModule { + @Override + protected void configure() { + bind(ManagementApiService.class).to(ManagementApiServiceImpl.class).in(Singleton.class); + bind(ApiService.class).to(ApiServiceImpl.class).in(Singleton.class); + bind(PluginService.class).to(PluginServiceImpl.class).in(Singleton.class); + bind(PolicyService.class).to(PolicyServiceImpl.class).in(Singleton.class); + bind(DeclarativeService.class).to(DeclarativeServiceImpl.class).in(Singleton.class); + } +} diff --git a/src/main/java/io/apiman/cli/util/AuthUtil.java b/src/main/java/io/apiman/cli/util/AuthUtil.java index 50fd89d..7469fcf 100644 --- a/src/main/java/io/apiman/cli/util/AuthUtil.java +++ b/src/main/java/io/apiman/cli/util/AuthUtil.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -24,9 +24,6 @@ * @author Pete Cornish {@literal } */ public final class AuthUtil { - private AuthUtil() { - } - /** * Authorization HTTP header. */ @@ -52,6 +49,9 @@ private AuthUtil() { */ public static final String BASIC_AUTH_VALUE = buildAuthString(DEFAULT_SERVER_USERNAME, DEFAULT_SERVER_PASSWORD); + private AuthUtil() { + } + /** * @param username the username * @param password the password diff --git a/src/main/java/io/apiman/cli/util/BeanUtil.java b/src/main/java/io/apiman/cli/util/BeanUtil.java index 6ba2fef..739bd18 100644 --- a/src/main/java/io/apiman/cli/util/BeanUtil.java +++ b/src/main/java/io/apiman/cli/util/BeanUtil.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -30,7 +30,10 @@ * * @author Pete Cornish {@literal } */ -public class BeanUtil { +public final class BeanUtil { + private BeanUtil() { + } + /** * Parse the {@code replacements} into a Map. * diff --git a/src/main/java/io/apiman/cli/util/Functions.java b/src/main/java/io/apiman/cli/util/Functions.java index 89ffbaf..e10b69c 100644 --- a/src/main/java/io/apiman/cli/util/Functions.java +++ b/src/main/java/io/apiman/cli/util/Functions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ public Functions ifNotPresent(Runnable r) { return this; } - public static Predicate not(Predicate p) { + public static Predicate not(Predicate p) { return t -> !p.test(t); } } diff --git a/src/main/java/io/apiman/cli/util/InjectionUtil.java b/src/main/java/io/apiman/cli/util/InjectionUtil.java new file mode 100644 index 0000000..a71bb68 --- /dev/null +++ b/src/main/java/io/apiman/cli/util/InjectionUtil.java @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.util; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import io.apiman.cli.management.ManagementApiFactoryModule; +import io.apiman.cli.service.ServiceModule; + +/** + * Manages the injection context. + * + * @author Pete Cornish {@literal } + */ +public final class InjectionUtil { + private static Injector injector; + + private InjectionUtil() { + } + + public synchronized static Injector getInjector() { + if (null == injector) { + injector = Guice.createInjector( + new ManagementApiFactoryModule(), + new ServiceModule() + ); + } + return injector; + } +} diff --git a/src/main/java/io/apiman/cli/util/LogUtil.java b/src/main/java/io/apiman/cli/util/LogUtil.java index f788e2c..da23a3c 100644 --- a/src/main/java/io/apiman/cli/util/LogUtil.java +++ b/src/main/java/io/apiman/cli/util/LogUtil.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -28,7 +28,7 @@ * * @author Pete Cornish {@literal } */ -public class LogUtil { +public final class LogUtil { /** * Used for printing output to the user; typically this is mapped to stdout. */ @@ -39,12 +39,22 @@ public class LogUtil { */ public static final String LINE_SEPARATOR = System.getProperty("line.separator"); + /** + * Whether to log at debug level. + */ + private static boolean logDebug; + + private LogUtil() { + } + /** * Configure the logging subsystem. * * @param logDebug whether debug logging is enabled */ public static void configureLogging(boolean logDebug) { + LogUtil.logDebug = logDebug; + final LoggerContext context = (LoggerContext) LogManager.getContext(false); final LoggerConfig rootLogger = context.getConfiguration().getRootLogger(); @@ -55,7 +65,7 @@ public static void configureLogging(boolean logDebug) { if (logDebug) { rootLogger.setLevel(Level.DEBUG); appender = context.getConfiguration().getAppender("ConsoleVerbose"); - + } else { appender = context.getConfiguration().getAppender("ConsoleTerse"); } @@ -63,4 +73,8 @@ public static void configureLogging(boolean logDebug) { rootLogger.addAppender(appender, null, null); context.updateLoggers(); } + + public static boolean isLogDebug() { + return logDebug; + } } diff --git a/src/main/java/io/apiman/cli/util/MappingUtil.java b/src/main/java/io/apiman/cli/util/MappingUtil.java index 64171fc..9f8eaae 100644 --- a/src/main/java/io/apiman/cli/util/MappingUtil.java +++ b/src/main/java/io/apiman/cli/util/MappingUtil.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -21,14 +21,14 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.common.collect.Lists; -import io.apiman.cli.core.api.model.ApiConfig; -import io.apiman.cli.core.api.model.ApiGateway; -import io.apiman.cli.core.api.model.EndpointProperties; -import io.apiman.cli.core.api.model.ServiceConfig; -import io.apiman.cli.core.declarative.model.DeclarativeApiConfig; -import io.apiman.cli.core.declarative.model.DeclarativeEndpointSecurity; -import io.apiman.cli.core.declarative.model.DeclarativeGateway; -import io.apiman.cli.core.gateway.model.Gateway; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiGateway; +import io.apiman.cli.command.api.model.EndpointProperties; +import io.apiman.cli.command.api.model.ServiceConfig; +import io.apiman.cli.command.declarative.model.DeclarativeApiConfig; +import io.apiman.cli.command.declarative.model.DeclarativeEndpointSecurity; +import io.apiman.cli.command.declarative.model.DeclarativeGateway; +import io.apiman.cli.command.gateway.model.Gateway; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.modelmapper.ModelMapper; @@ -39,7 +39,7 @@ * * @author Pete Cornish {@literal } */ -public class MappingUtil { +public final class MappingUtil { private static final Logger LOGGER = LogManager.getLogger(MappingUtil.class); /** @@ -67,6 +67,9 @@ public class MappingUtil { MODEL_MAPPER = buildModelMapper(); } + private MappingUtil() { + } + /** * @param obj the Object to write as a JSON String * @return the {@code obj} as JSON, or {@code null} if an error occurs diff --git a/src/test/java/io/apiman/cli/ApiTest.java b/src/test/java/io/apiman/cli/command/api/ApiTest.java similarity index 95% rename from src/test/java/io/apiman/cli/ApiTest.java rename to src/test/java/io/apiman/cli/command/api/ApiTest.java index 8aa60d4..6eb0583 100644 --- a/src/test/java/io/apiman/cli/ApiTest.java +++ b/src/test/java/io/apiman/cli/command/api/ApiTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.apiman.cli; +package io.apiman.cli.command.api; +import io.apiman.cli.Cli; import io.apiman.cli.util.AuthUtil; import io.apiman.cli.common.BaseTest; import io.apiman.cli.common.IntegrationTest; diff --git a/src/test/java/io/apiman/cli/util/DeclarativeUtilTest.java b/src/test/java/io/apiman/cli/command/declarative/DeclarativeUtilTest.java similarity index 95% rename from src/test/java/io/apiman/cli/util/DeclarativeUtilTest.java rename to src/test/java/io/apiman/cli/command/declarative/DeclarativeUtilTest.java index 9b1cb60..de317c2 100644 --- a/src/test/java/io/apiman/cli/util/DeclarativeUtilTest.java +++ b/src/test/java/io/apiman/cli/command/declarative/DeclarativeUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,13 @@ * limitations under the License. */ -package io.apiman.cli.util; +package io.apiman.cli.command.declarative; import com.google.common.collect.ImmutableMap; -import io.apiman.cli.command.DeclarativeTest; -import io.apiman.cli.core.declarative.model.Declaration; -import io.apiman.cli.core.declarative.model.DeclarativeGateway; +import io.apiman.cli.command.declarative.command.DeclarativeTest; +import io.apiman.cli.command.declarative.model.Declaration; +import io.apiman.cli.command.declarative.model.DeclarativeGateway; +import io.apiman.cli.util.MappingUtil; import org.junit.Test; import java.nio.file.Paths; diff --git a/src/test/java/io/apiman/cli/command/DeclarativeTest.java b/src/test/java/io/apiman/cli/command/declarative/command/DeclarativeTest.java similarity index 92% rename from src/test/java/io/apiman/cli/command/DeclarativeTest.java rename to src/test/java/io/apiman/cli/command/declarative/command/DeclarativeTest.java index 8d18697..3f225f9 100644 --- a/src/test/java/io/apiman/cli/command/DeclarativeTest.java +++ b/src/test/java/io/apiman/cli/command/declarative/command/DeclarativeTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,19 @@ * limitations under the License. */ -package io.apiman.cli.command; +package io.apiman.cli.command.declarative.command; import com.google.common.collect.Lists; +import io.apiman.cli.command.common.model.ManagementApiVersion; import io.apiman.cli.common.BaseTest; import io.apiman.cli.common.IntegrationTest; -import io.apiman.cli.core.common.model.ManagementApiVersion; -import io.apiman.cli.core.declarative.command.ApplyCommand; +import io.apiman.cli.util.InjectionUtil; import io.apiman.cli.util.LogUtil; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; +import javax.inject.Inject; import java.nio.file.Paths; import java.util.List; @@ -38,11 +39,13 @@ public class DeclarativeTest extends BaseTest { private static final boolean LOG_DEBUG = true; + @Inject private ApplyCommand command; @Before public void setUp() { - command = new ApplyCommand(); + InjectionUtil.getInjector().injectMembers(this); + command.setServerAddress(getApimanUrl()); // version specific test diff --git a/src/test/java/io/apiman/cli/GatewayTest.java b/src/test/java/io/apiman/cli/command/gateway/GatewayTest.java similarity index 94% rename from src/test/java/io/apiman/cli/GatewayTest.java rename to src/test/java/io/apiman/cli/command/gateway/GatewayTest.java index 6f26478..02b5e55 100644 --- a/src/test/java/io/apiman/cli/GatewayTest.java +++ b/src/test/java/io/apiman/cli/command/gateway/GatewayTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.apiman.cli; +package io.apiman.cli.command.gateway; +import io.apiman.cli.Cli; import io.apiman.cli.util.AuthUtil; import io.apiman.cli.common.BaseTest; import io.apiman.cli.common.IntegrationTest; diff --git a/src/test/java/io/apiman/cli/OrgTest.java b/src/test/java/io/apiman/cli/command/org/OrgTest.java similarity index 90% rename from src/test/java/io/apiman/cli/OrgTest.java rename to src/test/java/io/apiman/cli/command/org/OrgTest.java index 6f07679..5652f84 100644 --- a/src/test/java/io/apiman/cli/OrgTest.java +++ b/src/test/java/io/apiman/cli/command/org/OrgTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,8 +14,9 @@ * limitations under the License. */ -package io.apiman.cli; +package io.apiman.cli.command.org; +import io.apiman.cli.Cli; import io.apiman.cli.util.AuthUtil; import io.apiman.cli.common.BaseTest; import io.apiman.cli.common.IntegrationTest; diff --git a/src/test/java/io/apiman/cli/PluginTest.java b/src/test/java/io/apiman/cli/command/plugin/PluginTest.java similarity index 95% rename from src/test/java/io/apiman/cli/PluginTest.java rename to src/test/java/io/apiman/cli/command/plugin/PluginTest.java index 9993fca..a53bfdf 100644 --- a/src/test/java/io/apiman/cli/PluginTest.java +++ b/src/test/java/io/apiman/cli/command/plugin/PluginTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,14 +14,15 @@ * limitations under the License. */ -package io.apiman.cli; +package io.apiman.cli.command.plugin; import com.fasterxml.jackson.core.type.TypeReference; import com.jayway.restassured.response.Response; +import io.apiman.cli.Cli; import io.apiman.cli.util.AuthUtil; import io.apiman.cli.common.BaseTest; import io.apiman.cli.common.IntegrationTest; -import io.apiman.cli.core.plugin.model.Plugin; +import io.apiman.cli.command.plugin.model.Plugin; import io.apiman.cli.util.MappingUtil; import org.jetbrains.annotations.NotNull; import org.junit.FixMethodOrder; diff --git a/src/test/java/io/apiman/cli/management/ManagementApiUtilTest.java b/src/test/java/io/apiman/cli/management/ManagementApiUtilTest.java index 9389c26..2cb5618 100644 --- a/src/test/java/io/apiman/cli/management/ManagementApiUtilTest.java +++ b/src/test/java/io/apiman/cli/management/ManagementApiUtilTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Pete Cornish + * Copyright 2017 Pete Cornish * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package io.apiman.cli.management; -import io.apiman.cli.core.common.model.ManagementApiVersion; -import io.apiman.cli.core.org.OrgApi; import io.apiman.cli.exception.CommandException; import org.junit.After; import org.junit.Before; @@ -31,8 +29,6 @@ import java.util.function.Supplier; import static com.google.common.collect.Lists.newArrayList; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; @@ -43,7 +39,7 @@ * @author Pete Cornish {@literal } */ public class ManagementApiUtilTest { - public static final String URL = "http://example.com"; + private static final String URL = "http://example.com"; @Mock private Supplier request; @@ -134,14 +130,4 @@ public void testInvokeAndCheckResponse_RetrofitErrorNullResponse() throws Except verify(request).get(); } } - - @Test - public void testBuildApiClient() throws Exception { - // test - final OrgApi actual = ManagementApiUtil.buildServerApiClient(OrgApi.class, URL, "username", "password", true, ManagementApiVersion.UNSPECIFIED); - - // assertions - assertNotNull(actual); - assertTrue(OrgApi.class.isAssignableFrom(actual.getClass())); - } -} \ No newline at end of file +} diff --git a/src/test/java/io/apiman/cli/service/ManagementApiServiceImplTest.java b/src/test/java/io/apiman/cli/service/ManagementApiServiceImplTest.java new file mode 100644 index 0000000..ebd6663 --- /dev/null +++ b/src/test/java/io/apiman/cli/service/ManagementApiServiceImplTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Pete Cornish + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.service; + +import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.org.OrgApi; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Tests for {@link ManagementApiServiceImpl}. + * + * @author Pete Cornish {@literal } + */ +public class ManagementApiServiceImplTest { + private static final String URL = "http://example.com"; + + /** + * Unit under test. + */ + private ManagementApiServiceImpl service; + + @Before + public void setUp() throws Exception { + service = new ManagementApiServiceImpl(); + } + + @Test + public void testBuildServerApiClient() throws Exception { + // test + final OrgApi actual = service.buildServerApiClient( + OrgApi.class, ManagementApiVersion.UNSPECIFIED, URL, "username", "password", true); + + // assertions + assertNotNull(actual); + assertTrue(OrgApi.class.isAssignableFrom(actual.getClass())); + } +} From da5d106767bf6a996c4a9c06a2f733af506a61d5 Mon Sep 17 00:00:00 2001 From: Quantin Date: Tue, 27 Jun 2017 13:54:50 +0200 Subject: [PATCH 05/13] add multi-gateways support --- .../command/api/command/ApiCreateCommand.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java index 89e418f..c669636 100644 --- a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java @@ -32,6 +32,8 @@ import javax.inject.Inject; import java.text.MessageFormat; +import java.util.List; +import java.util.StringTokenizer; /** * Create an API. @@ -62,6 +64,9 @@ public class ApiCreateCommand extends AbstractApiCommand implements ApiMixin { @Option(name = "--gateway", aliases = {"-g"}, usage = "Gateway") private String gateway = "TheGateway"; + @Option(name = "--gateways", aliases = {"-gs"}, usage = "Gateways") + private String gateways = ""; + @Inject public ApiCreateCommand(ManagementApiService managementApiService) { super(managementApiService); @@ -81,11 +86,22 @@ public void performAction(CmdLineParser parser) throws CommandException { description, initialVersion); + final List gatewaysList = Lists.newArrayList(); + + if (!gateways.equals("")) { + final StringTokenizer st = new StringTokenizer(gateways); + while (st.hasMoreTokens()) { + gatewaysList.add(new ApiGateway(st.nextToken())); + } + } else { + gatewaysList.add(new ApiGateway(gateway)); + } + final ApiConfig config = new ApiConfig( endpoint, endpointType, publicApi, - Lists.newArrayList(new ApiGateway(gateway))); + gatewaysList); // create final VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); From c49c49e45febf63ae03817bfeb4afb21911c5d30 Mon Sep 17 00:00:00 2001 From: Quantin Date: Tue, 27 Jun 2017 16:15:41 +0200 Subject: [PATCH 06/13] add plan support to declarative command --- .../declarative/command/ApplyCommand.java | 13 +- .../declarative/model/DeclarativeOrg.java | 11 ++ .../declarative/model/DeclarativePlan.java | 46 +++++++ .../io/apiman/cli/command/plan/PlanApi.java | 54 ++++++++ .../apiman/cli/command/plan/model/Plan.java | 84 ++++++++++++ .../cli/command/plan/model/PlanVersion.java | 43 +++++++ .../ManagementApiFactoryModule.java | 5 + .../cli/service/DeclarativeService.java | 11 ++ .../cli/service/DeclarativeServiceImpl.java | 120 +++++++++++++++++- 9 files changed, 383 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java create mode 100644 src/main/java/io/apiman/cli/command/plan/PlanApi.java create mode 100644 src/main/java/io/apiman/cli/command/plan/model/Plan.java create mode 100644 src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java diff --git a/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java b/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java index 6538e4a..c5adc8c 100644 --- a/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java +++ b/src/main/java/io/apiman/cli/command/declarative/command/ApplyCommand.java @@ -20,6 +20,9 @@ import io.apiman.cli.command.core.AbstractFinalCommand; import io.apiman.cli.command.declarative.DeclarativeUtil; import io.apiman.cli.command.declarative.model.Declaration; +import io.apiman.cli.command.plan.PlanApi; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.command.plan.model.PlanVersion; import io.apiman.cli.exception.CommandException; import io.apiman.cli.service.DeclarativeService; import io.apiman.cli.service.ManagementApiService; @@ -155,14 +158,22 @@ private void applyDeclaration(Declaration declaration) { // add plugins ofNullable(declaration.getSystem().getPlugins()).ifPresent(pluginService::addPlugins); - // add org and APIs + // add org, APIs and Plans ofNullable(declaration.getOrg()).ifPresent(org -> { + // add org declarativeService.applyOrg(org); + // add apis ofNullable(org.getApis()).ifPresent(apis -> declarativeService.applyApis(serverVersion, apis, org.getName())); + + // add plans + ofNullable(org.getPlans()).ifPresent(plans -> + declarativeService.applyPlans(buildServerApiClient(PlanApi.class), declaration, org.getName())); }); + + LOGGER.info("Applied declaration"); } diff --git a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java index cf9c8d9..408a137 100644 --- a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java @@ -34,6 +34,9 @@ public class DeclarativeOrg extends Org { @JsonProperty private List apis; + @JsonProperty + private List plans; + public List getApis() { return apis; } @@ -41,4 +44,12 @@ public List getApis() { public void setApis(List apis) { this.apis = apis; } + + public List getPlans() { + return plans; + } + + public void setPlans(List plans) { + this.plans = plans; + } } diff --git a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java new file mode 100644 index 0000000..dd27be6 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.declarative.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.apiman.cli.command.plan.model.Plan; + +import java.util.List; + +/** + * Declarative Plan representation. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeclarativePlan extends Plan { + + @JsonProperty + private List policies; + + public List getPolicies() { + return policies; + } + + public void setPolicies(List policies) { + this.policies = policies; + } + +} diff --git a/src/main/java/io/apiman/cli/command/plan/PlanApi.java b/src/main/java/io/apiman/cli/command/plan/PlanApi.java new file mode 100644 index 0000000..9a0b5d8 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/plan/PlanApi.java @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.plan; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.command.plan.model.PlanVersion; +import retrofit.client.Response; +import retrofit.http.*; + +import java.util.List; + +/** + * @author Jean-Charles Quantin {@literal } + */ +public interface PlanApi { + @POST("/organizations/{orgName}/plans") + Response create(@Path("orgName") String orgName, @Body Plan plan); + + @POST("/organizations/{orgName}/plans/{planName}/versions") + Response createVersion(@Path("orgName") String orgName, @Path("planName") String planName, @Body PlanVersion apiVersion); + + @GET("/organizations/{orgName}/plans") + List list(@Path("orgName") String orgName); + + @GET("/organizations/{orgName}/plans/{planName}") + Plan fetch(@Path("orgName") String orgName, @Path("planName") String planName); + + @GET("/organizations/{orgName}/plans/{planName}/versions/{version}") + Plan fetchVersion(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version); + + @POST("/organizations/{orgName}/plans/{planName}/versions/{version}/policies") + Response addPolicy(@Path("orgName") String orgName, @Path("planName") String apiName, + @Path("version") String version, @Body ApiPolicy policyConfig); + + @GET("/organizations/{orgName}/plans/{apiName}/versions/{version}/policies") + List fetchPolicies(@Path("orgName") String orgName, @Path("apiName") String apiName, + @Path("version") String version); + +} diff --git a/src/main/java/io/apiman/cli/command/plan/model/Plan.java b/src/main/java/io/apiman/cli/command/plan/model/Plan.java new file mode 100644 index 0000000..d5c7b8d --- /dev/null +++ b/src/main/java/io/apiman/cli/command/plan/model/Plan.java @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.plan.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Models a Plan. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Plan { + @JsonProperty + private String name; + + @JsonProperty + private String description; + + @JsonProperty + private String organizationName; + + /** + * Note: use {@link #version} instead for declarative API configuration. + */ + @JsonProperty + private String initialVersion; + + @JsonProperty + private String version; + + @JsonProperty + private String status; + + public Plan() { + } + + public Plan(String name, String description, String initialVersion) { + this.name = name; + this.description = description; + this.initialVersion = initialVersion; + } + + public String getName() { + return name; + } + + public void setInitialVersion(String initialVersion) { + this.initialVersion = initialVersion; + } + + public String getInitialVersion() { + return initialVersion; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getVersion() { + return version; + } + + public String getStatus() { + return status; + } +} diff --git a/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java new file mode 100644 index 0000000..768865e --- /dev/null +++ b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.plan.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Models an Plan version. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class PlanVersion { + @JsonProperty + private String version; + + /** + * Never clone a previous version when creating a new version. + */ + @JsonProperty + final private boolean clone = false; + + public PlanVersion(String version) { + this.version = version; + } +} diff --git a/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java b/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java index 49c561b..6332ee1 100644 --- a/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java +++ b/src/main/java/io/apiman/cli/management/ManagementApiFactoryModule.java @@ -25,6 +25,7 @@ import io.apiman.cli.command.common.model.ManagementApiVersion; import io.apiman.cli.command.gateway.GatewayApi; import io.apiman.cli.command.org.OrgApi; +import io.apiman.cli.command.plan.PlanApi; import io.apiman.cli.command.plugin.PluginApi; import io.apiman.cli.management.binding.ManagementApiBindings; import io.apiman.cli.management.factory.ManagementApiFactory; @@ -66,5 +67,9 @@ protected void configure() { bind(ManagementApiFactory.class) .annotatedWith(ManagementApiBindings.boundTo(VersionAgnosticApi.class, ManagementApiVersion.v12x)) .to(Version12XManagementApiFactoryImpl.class).in(Singleton.class); + + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(PlanApi.class)) + .toInstance(new SimpleManagementApiFactoryImpl<>(PlanApi.class)); } } diff --git a/src/main/java/io/apiman/cli/service/DeclarativeService.java b/src/main/java/io/apiman/cli/service/DeclarativeService.java index 90045f3..d87328d 100644 --- a/src/main/java/io/apiman/cli/service/DeclarativeService.java +++ b/src/main/java/io/apiman/cli/service/DeclarativeService.java @@ -17,9 +17,11 @@ package io.apiman.cli.service; import io.apiman.cli.command.common.model.ManagementApiVersion; +import io.apiman.cli.command.declarative.model.Declaration; import io.apiman.cli.command.declarative.model.DeclarativeApi; import io.apiman.cli.command.declarative.model.DeclarativeGateway; import io.apiman.cli.command.declarative.model.DeclarativeOrg; +import io.apiman.cli.command.plan.PlanApi; import java.util.List; @@ -51,4 +53,13 @@ public interface DeclarativeService { * @param orgName the name of the organisation. */ void applyApis(ManagementApiVersion serverVersion, List apis, String orgName); + + /** + * Add plans if they are not present. + * + * @param planClient the plan Api. + * @param declaration the Declaration to apply. + * @param orgName the organization name. + */ + void applyPlans(PlanApi planClient, Declaration declaration, String orgName); } diff --git a/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java index 48f3665..d290528 100644 --- a/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/service/DeclarativeServiceImpl.java @@ -19,13 +19,15 @@ import io.apiman.cli.command.api.VersionAgnosticApi; import io.apiman.cli.command.api.model.*; import io.apiman.cli.command.common.model.ManagementApiVersion; -import io.apiman.cli.command.declarative.model.DeclarativeApi; -import io.apiman.cli.command.declarative.model.DeclarativeGateway; -import io.apiman.cli.command.declarative.model.DeclarativeOrg; +import io.apiman.cli.command.declarative.DeclarativeUtil; +import io.apiman.cli.command.declarative.model.*; import io.apiman.cli.command.gateway.GatewayApi; import io.apiman.cli.command.gateway.model.Gateway; import io.apiman.cli.command.org.OrgApi; import io.apiman.cli.command.org.model.Org; +import io.apiman.cli.command.plan.PlanApi; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.command.plan.model.PlanVersion; import io.apiman.cli.management.ManagementApiUtil; import io.apiman.cli.util.MappingUtil; import org.apache.logging.log4j.LogManager; @@ -33,6 +35,7 @@ import javax.inject.Inject; import java.util.List; +import java.util.Optional; import static io.apiman.cli.command.common.model.ManagementApiVersion.v11x; import static io.apiman.cli.command.common.model.ManagementApiVersion.v12x; @@ -247,4 +250,115 @@ private void applyPolicies(ManagementApiVersion serverVersion, DeclarativeApi de }); }); } + + + + /** + * Add plans if they are not present. + * + * @param planClient the plan Api. + * @param declaration the Declaration to apply. + * @param orgName the organization name. + */ + public void applyPlans(PlanApi planClient, Declaration declaration, String orgName) { + ofNullable(declaration.getOrg().getPlans()).ifPresent(declarativePlans -> { + LOGGER.debug("Applying Plans"); + declarativePlans.forEach(declarativePlan -> { + + of(ManagementApiUtil.checkExists(() -> planClient.fetch(orgName, declarativePlan.getName()))) + .ifPresent(existing -> { + LOGGER.info("Plan already exists: {}", declarativePlan.getName()); + // create and configure Plan version + applyPlanVersion(planClient, declarativePlan, orgName, declarativePlan.getName(), declarativePlan.getVersion()); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding plan: {}", declarativePlan.getName()); + + final Plan plan = MappingUtil.map(declarativePlan, Plan.class); + plan.setInitialVersion(plan.getVersion()); + plan.setVersion(null); + planClient.create(orgName, plan); + }); + + // add policies + applyPolicies(planClient, declarativePlan, orgName, declarativePlan.getName(), declarativePlan.getVersion()); + }); + + }); + } + + /** + * Add and configure the Plan if it is not present. + * + * @param planClient + * @param declarativePlan + * @param orgName + * @param planName + * @param planVersion + * @return the state of the Plan + */ + private void applyPlanVersion(PlanApi planClient, DeclarativePlan declarativePlan, String orgName, + String planName, String planVersion) { + + LOGGER.debug("Applying Plan: {}", planName); + + // Plan version + of(ManagementApiUtil.checkExists(() -> planClient.fetchVersion(orgName, planName, planVersion))) + .ifPresent(existing -> { + LOGGER.info("Plan '{}' version '{}' already exists", planName, planVersion); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding Plan '{}' version '{}'", planName, planVersion); + + // create version + final PlanVersion planVersionWrapper = new PlanVersion(planVersion); + planClient.createVersion(orgName, planName, planVersionWrapper); + }); + } + + /** + * Add policies to the Plan if they are not present. + * + * @param planClient + * @param declarativePlan + * @param orgName + * @param planName + * @param planVersion + */ + private void applyPolicies(PlanApi planClient, DeclarativePlan declarativePlan, String orgName, + String planName, String planVersion) { + + ofNullable(declarativePlan.getPolicies()).ifPresent(declarativePolicies -> { + LOGGER.debug("Applying policies to Plan: {}", planName); + + // existing policies for the Plan + final List apiPolicies = planClient.fetchPolicies(orgName, planName, planVersion); + + declarativePolicies.forEach(declarativePolicy -> { + final String policyName = declarativePolicy.getName(); + + final ApiPolicy apiPolicy = new ApiPolicy( + MappingUtil.safeWriteValueAsJson(declarativePolicy.getConfig())); + + // determine if the policy already exists for this Plan + final Optional existingPolicy = apiPolicies.stream() + .filter(p -> policyName.equals(p.getPolicyDefinitionId())) + .findFirst(); + + if (existingPolicy.isPresent()) { + // update the existing policy config + LOGGER.info("Updating existing policy '{}' configuration for Plan: {}", policyName, planName); + + final Long policyId = existingPolicy.get().getId(); + //planClient.configurePolicy(orgName, planName, planVersion, policyId, apiPolicy); + } else { + // add new policy + LOGGER.info("Adding policy '{}' to Plan: {}", policyName, planName); + + apiPolicy.setDefinitionId(policyName); + planClient.addPolicy(orgName, planName, planVersion, apiPolicy); + } + }); + }); + } } From e1769977cbe28c7ab345f05853de62b0711457e7 Mon Sep 17 00:00:00 2001 From: Quantin Date: Tue, 27 Jun 2017 17:12:34 +0200 Subject: [PATCH 07/13] support for none public api with plan declarartion in api Configuration --- .../command/api/command/ApiCreateCommand.java | 6 ++- .../cli/command/api/model/ApiConfig.java | 9 +++- .../apiman/cli/command/api/model/ApiPlan.java | 42 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/apiman/cli/command/api/model/ApiPlan.java diff --git a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java index c669636..ae22d6f 100644 --- a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java @@ -22,6 +22,8 @@ import io.apiman.cli.command.api.model.ApiConfig; import io.apiman.cli.command.api.model.ApiGateway; import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.ApiPlan; +import io.apiman.cli.command.plan.PlanApi; import io.apiman.cli.exception.CommandException; import io.apiman.cli.management.ManagementApiUtil; import io.apiman.cli.service.ManagementApiService; @@ -32,6 +34,7 @@ import javax.inject.Inject; import java.text.MessageFormat; +import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -101,7 +104,8 @@ public void performAction(CmdLineParser parser) throws CommandException { endpoint, endpointType, publicApi, - gatewaysList); + gatewaysList, + new ArrayList()); // create final VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); diff --git a/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java b/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java index 17aa14e..ab41f0e 100644 --- a/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiConfig.java @@ -46,19 +46,26 @@ public class ApiConfig { @JsonProperty private List gateways; + @JsonProperty + private List plans; + public ApiConfig() { } - public ApiConfig(String endpoint, String endpointType, boolean publicApi, List gateways) { + public ApiConfig(String endpoint, String endpointType, boolean publicApi, List gateways, List plans) { this.endpoint = endpoint; this.endpointType = endpointType; this.publicApi = publicApi; this.gateways = gateways; + this.plans = plans; } public void setGateways(ArrayList gateways) { this.gateways = gateways; } + public void setPlans(ArrayList plans) { + this.plans = plans; + } public void setPublicApi(boolean publicApi) { this.publicApi = publicApi; diff --git a/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java new file mode 100644 index 0000000..b970026 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApiPlan { + @JsonProperty + private String planId; + + @JsonProperty + private String version; + + public ApiPlan() { + } + + public ApiPlan(String planId, String version) { + this.planId = planId; + this.version = version; + } +} From 5c207c73601e0eef5876a3ce9c0eb24df1c86954 Mon Sep 17 00:00:00 2001 From: Quantin Date: Tue, 27 Jun 2017 17:44:49 +0200 Subject: [PATCH 08/13] document declaratice Plan Usage with yml --- README.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9d52936..4959623 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Here's how it works: Here's a simple YAML file (you can use JSON if you want): - # simple.yml + # simpleApi.yml --- org: name: "test" @@ -73,17 +73,34 @@ Here's a simple YAML file (you can use JSON if you want): config: endpoint: "http://example.com" endpointType: "rest" - public: true + public: false gateway: "TheGateway" + plans: + - planId: "planExample" + version: "1.0" policies: - name: "CachingPolicy" config: ttl: 60 + # simplePlan.yml + --- + org: + name: "test" + description: "Test organisation" + plans: + - name: "planExample" + description: "This is a plan" + version: "1.0" + policies: + - name: "CachingPolicy" + config: + ttl: 120 + ### Step 2: Apply the environment declaration - $ ./apiman apply -f simple.yml - INFO Loaded declaration: examples/declarative/simple.yml + $ ./apiman apply -f simpleApi.yml + INFO Loaded declaration: examples/declarative/simpleApi.yml INFO Adding org: test INFO Adding API: example INFO Configuring API: example From 604e71c17e625f9a13e92585671e91d00ef1485e Mon Sep 17 00:00:00 2001 From: Quantin Date: Wed, 28 Jun 2017 09:23:29 +0200 Subject: [PATCH 09/13] ability to fetch all versions of an api ({apiName}/versions) --- .../java/io/apiman/cli/command/api/Version11xServerApi.java | 3 +++ .../java/io/apiman/cli/command/api/Version12xServerApi.java | 3 +++ .../java/io/apiman/cli/command/api/VersionAgnosticApi.java | 2 ++ .../api/factory/Version11XManagementApiFactoryImpl.java | 5 +++++ .../api/factory/Version12XManagementApiFactoryImpl.java | 5 +++++ 5 files changed, 18 insertions(+) diff --git a/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java index bfb0c75..d870d17 100644 --- a/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java @@ -46,6 +46,9 @@ public interface Version11xServerApi { @GET("/organizations/{orgName}/services/{serviceName}/versions/{version}") Api fetchVersion(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version); + @GET("/organizations/{orgName}/services/{serviceName}/versions") + List fetchVersions(@Path("orgName") String orgName, @Path("serviceName") String serviceName); + @PUT("/organizations/{orgName}/services/{serviceName}/versions/{version}") Response configure(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version, @Body ServiceConfig config); diff --git a/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java index 8248cb2..d3149f3 100644 --- a/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java @@ -46,6 +46,9 @@ public interface Version12xServerApi { @GET("/organizations/{orgName}/apis/{apiName}/versions/{version}") Api fetchVersion(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version); + @GET("/organizations/{orgName}/apis/{apiName}/versions") + List fetchVersions(@Path("orgName") String orgName, @Path("apiName") String apiName); + @PUT("/organizations/{orgName}/apis/{apiName}/versions/{version}") Response configure(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version, @Body ApiConfig config); diff --git a/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java index e097bf0..28dd43a 100644 --- a/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java @@ -38,6 +38,8 @@ public interface VersionAgnosticApi { Api fetchVersion(String orgName, String apiName, String version); + List fetchVersions(String orgName, String apiName); + Response configure(String orgName, String apiName, String version, ApiConfig config); diff --git a/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java index 47d347d..041187d 100644 --- a/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -63,6 +63,11 @@ public Api fetchVersion(String orgName, String apiName, String version) { return delegate.fetchVersion(orgName, apiName, version); } + @Override + public List fetchVersions(String orgName, String apiName) { + return delegate.fetchVersions(orgName, apiName); + } + @Override public Response configure(String orgName, String apiName, String version, ApiConfig apiConfig) { // convert to 1.1.x format diff --git a/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java index 7492a68..d97e3e3 100644 --- a/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java @@ -64,6 +64,11 @@ public Api fetchVersion(String orgName, String apiName, String version) { return delegate.fetchVersion(orgName, apiName, version); } + @Override + public List fetchVersions(String orgName, String apiName) { + return delegate.fetchVersions(orgName, apiName); + } + @Override public Response configure(String orgName, String apiName, String version, ApiConfig apiConfig) { return delegate.configure(orgName, apiName, version, apiConfig); From 0ffb6ed01532d326e7486acad4133f8a4abf81ee Mon Sep 17 00:00:00 2001 From: Quantin Date: Thu, 29 Jun 2017 21:01:17 +0200 Subject: [PATCH 10/13] making -gateway arg a list (can occurs more than once) --- .../command/api/command/ApiCreateCommand.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java index ae22d6f..4fb39aa 100644 --- a/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiCreateCommand.java @@ -65,11 +65,8 @@ public class ApiCreateCommand extends AbstractApiCommand implements ApiMixin { private boolean publicApi; @Option(name = "--gateway", aliases = {"-g"}, usage = "Gateway") - private String gateway = "TheGateway"; + private List gateway = new ArrayList(); - @Option(name = "--gateways", aliases = {"-gs"}, usage = "Gateways") - private String gateways = ""; - @Inject public ApiCreateCommand(ManagementApiService managementApiService) { super(managementApiService); @@ -89,16 +86,10 @@ public void performAction(CmdLineParser parser) throws CommandException { description, initialVersion); - final List gatewaysList = Lists.newArrayList(); - - if (!gateways.equals("")) { - final StringTokenizer st = new StringTokenizer(gateways); - while (st.hasMoreTokens()) { - gatewaysList.add(new ApiGateway(st.nextToken())); - } - } else { - gatewaysList.add(new ApiGateway(gateway)); - } + if (gateway.size()==0) { gateway.add("TheGateway"); } + // populating the list of Gateway + final List gatewaysList = Lists.newArrayList(); + gateway.forEach(strGat -> { gatewaysList.add(new ApiGateway(strGat)); }); final ApiConfig config = new ApiConfig( endpoint, From 5a1b1de1c6bbc5310ec6429365a08eb15785d079 Mon Sep 17 00:00:00 2001 From: Quantin Date: Thu, 29 Jun 2017 23:03:55 +0200 Subject: [PATCH 11/13] Add ability to fetch individual Policy Configuration from an API --- .../java/io/apiman/cli/command/api/Version11xServerApi.java | 4 ++++ .../java/io/apiman/cli/command/api/Version12xServerApi.java | 4 ++++ .../java/io/apiman/cli/command/api/VersionAgnosticApi.java | 5 ++++- .../api/factory/Version11XManagementApiFactoryImpl.java | 5 +++++ .../api/factory/Version12XManagementApiFactoryImpl.java | 5 +++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java index d870d17..d795231 100644 --- a/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version11xServerApi.java @@ -61,6 +61,10 @@ Response addPolicy(@Path("orgName") String orgName, @Path("serviceName") String List fetchPolicies(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version); + @GET("/organizations/{orgName}/services/{serviceName}/versions/{version}/policies/{policyId}") + ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("serviceName") String serviceName, + @Path("version") String version, @Path("policyId") Long policyId); + @PUT("/organizations/{orgName}/services/{serviceName}/versions/{version}/policies/{policyId}") Response configurePolicy(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version, @Path("policyId") Long policyId, @Body ApiPolicy policyConfig); diff --git a/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java index d3149f3..ea5d4d7 100644 --- a/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java +++ b/src/main/java/io/apiman/cli/command/api/Version12xServerApi.java @@ -61,6 +61,10 @@ Response addPolicy(@Path("orgName") String orgName, @Path("apiName") String apiN List fetchPolicies(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version); + @GET("/organizations/{orgName}/apis/{apiName}/versions/{version}/policies/{policyId}") + ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("apiName") String apiName, + @Path("version") String version, @Path("policyId") Long policyId); + @PUT("/organizations/{orgName}/apis/{apiName}/versions/{version}/policies/{policyId}") Response configurePolicy(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version, @Path("policyId") Long policyId, @Body ApiPolicy policyConfig); diff --git a/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java index 28dd43a..eca865f 100644 --- a/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/command/api/VersionAgnosticApi.java @@ -46,9 +46,12 @@ Response configure(String orgName, String apiName, Response addPolicy(String orgName, String apiName, String version, ApiPolicy policyConfig); - List fetchPolicies(String orgName, String serviceName, + List fetchPolicies(String orgName, String apiName, String version); + ApiPolicy fetchPolicy(String orgName, String apiName, + String version, Long policyId); + Response configurePolicy(String orgName, String apiName, String apiVersion, Long policyId, ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java index 041187d..b6d26d5 100644 --- a/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -84,6 +84,11 @@ public Response addPolicy(String orgName, String apiName, String version, ApiPol public List fetchPolicies(String orgName, String serviceName, String version) { return delegate.fetchPolicies(orgName, serviceName, version); } + + @Override + public ApiPolicy fetchPolicy(String orgName, String serviceName, String version, Long policyId) { + return delegate.fetchPolicy(orgName, serviceName, version, policyId); + } @Override public Response configurePolicy(String orgName, String apiName, String apiVersion, Long policyId, ApiPolicy policyConfig) { diff --git a/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java index d97e3e3..9966683 100644 --- a/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/command/api/factory/Version12XManagementApiFactoryImpl.java @@ -84,6 +84,11 @@ public List fetchPolicies(String orgName, String serviceName, String return delegate.fetchPolicies(orgName, serviceName, version); } + @Override + public ApiPolicy fetchPolicy(String orgName, String serviceName, String version, Long policyId) { + return delegate.fetchPolicy(orgName, serviceName, version, policyId); + } + @Override public Response configurePolicy(String orgName, String apiName, String apiVersion, Long policyId, ApiPolicy policyConfig) { return delegate.configurePolicy(orgName, apiName, apiVersion, policyId, policyConfig); From c30537b68b78a27b268060d18061c623a6f440b2 Mon Sep 17 00:00:00 2001 From: Quantin Date: Tue, 4 Jul 2017 09:45:03 +0200 Subject: [PATCH 12/13] Adds DeepList of APi description (with policies) --- .../cli/command/api/command/ApiCommand.java | 1 + .../api/command/ApiDeepListCommand.java | 83 +++++++++++++++++++ .../cli/command/api/model/ApiPolicy.java | 5 ++ .../declarative/model/DeclarativePolicy.java | 10 +++ .../java/io/apiman/cli/util/MappingUtil.java | 34 +++++++- 5 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/apiman/cli/command/api/command/ApiDeepListCommand.java diff --git a/src/main/java/io/apiman/cli/command/api/command/ApiCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiCommand.java index 5012e51..e78ceed 100644 --- a/src/main/java/io/apiman/cli/command/api/command/ApiCommand.java +++ b/src/main/java/io/apiman/cli/command/api/command/ApiCommand.java @@ -38,6 +38,7 @@ public ApiCommand(ManagementApiService managementApiService) { protected void populateCommands(Map> commandMap) { commandMap.put("create", ApiCreateCommand.class); commandMap.put("list", ApiListCommand.class); + commandMap.put("dlist", ApiDeepListCommand.class); commandMap.put("publish", ApiPublishCommand.class); commandMap.put("policy", ApiPolicyCommand.class); } diff --git a/src/main/java/io/apiman/cli/command/api/command/ApiDeepListCommand.java b/src/main/java/io/apiman/cli/command/api/command/ApiDeepListCommand.java new file mode 100644 index 0000000..63fd5bb --- /dev/null +++ b/src/main/java/io/apiman/cli/command/api/command/ApiDeepListCommand.java @@ -0,0 +1,83 @@ +/* + * Copyright 2017 jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.api.command; + +import io.apiman.cli.command.api.ApiMixin; +import io.apiman.cli.command.api.VersionAgnosticApi; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.declarative.model.DeclarativeApi; +import io.apiman.cli.command.declarative.model.DeclarativePolicy; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.service.ManagementApiService; +import io.apiman.cli.util.LogUtil; +import io.apiman.cli.util.MappingUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.kohsuke.args4j.CmdLineParser; + +import javax.inject.Inject; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +/** + * Deep List of APIs : with versions and policies + * + * @author Jean-Charles Quantin {@literal } + */ +public class ApiDeepListCommand extends AbstractApiCommand implements ApiMixin { + private static final Logger LOGGER = LogManager.getLogger(ApiDeepListCommand.class); + + @Inject + public ApiDeepListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected String getCommandDescription() { + return MessageFormat.format("List {0}s", getModelName()); + } + + @Override + public void performAction(CmdLineParser parser) throws CommandException { + LOGGER.debug("Listing {}", this::getModelName); + + VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); + final List apis = apiClient.list(orgName); + final List deepApisList = new ArrayList(); + apis.forEach(api -> { + apiClient.fetchVersions(orgName, api.getName()).forEach(apiVersion -> { + final DeclarativeApi declApi = MappingUtil.map(apiVersion, DeclarativeApi.class); + final List ListPolicies = new ArrayList(); + apiClient.fetchPolicies(orgName, api.getName(), apiVersion.getVersion()) + .forEach(policy -> { + ApiPolicy apiPolicy = apiClient.fetchPolicy(orgName, api.getName(), apiVersion.getVersion(), policy.getId()); + DeclarativePolicy declarativePolicy = MappingUtil.map(apiPolicy, DeclarativePolicy.class); + declarativePolicy.setName(policy.getPolicyDefinitionId()); + declarativePolicy.setId(policy.getId().toString()); + declarativePolicy.setConfig(MappingUtil.safeGetValueFromJson(apiPolicy.getConfiguration())); + ListPolicies.add(declarativePolicy); + }); + declApi.setPolicies(ListPolicies); + deepApisList.add(declApi); + }); + }); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(deepApisList)); + + } +} diff --git a/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java b/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java index 0ab8e25..59367a5 100644 --- a/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPolicy.java @@ -40,6 +40,7 @@ public class ApiPolicy { @JsonProperty private String policyDefinitionId; + @JsonProperty private String configuration; @@ -64,6 +65,10 @@ public Long getId() { return id; } + public String getConfiguration() { + return configuration; + } + public void setDefinitionId(String definitionId) { this.definitionId = definitionId; } diff --git a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java index 693d9aa..0547956 100644 --- a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePolicy.java @@ -29,6 +29,8 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="$id") public class DeclarativePolicy { + + @JsonProperty("$id") private String id; @@ -38,6 +40,14 @@ public class DeclarativePolicy { @JsonProperty private Map config; + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + public String getName() { return name; } diff --git a/src/main/java/io/apiman/cli/util/MappingUtil.java b/src/main/java/io/apiman/cli/util/MappingUtil.java index 9f8eaae..18e3990 100644 --- a/src/main/java/io/apiman/cli/util/MappingUtil.java +++ b/src/main/java/io/apiman/cli/util/MappingUtil.java @@ -17,23 +17,28 @@ package io.apiman.cli.util; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.util.JSONPObject; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.common.collect.Lists; -import io.apiman.cli.command.api.model.ApiConfig; -import io.apiman.cli.command.api.model.ApiGateway; -import io.apiman.cli.command.api.model.EndpointProperties; -import io.apiman.cli.command.api.model.ServiceConfig; +import io.apiman.cli.command.api.model.*; import io.apiman.cli.command.declarative.model.DeclarativeApiConfig; import io.apiman.cli.command.declarative.model.DeclarativeEndpointSecurity; import io.apiman.cli.command.declarative.model.DeclarativeGateway; +import io.apiman.cli.command.declarative.model.DeclarativePolicy; import io.apiman.cli.command.gateway.model.Gateway; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.modelmapper.ModelMapper; import org.modelmapper.config.Configuration; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + /** * Shared POJO/JSON/YAML mapping utility methods. * @@ -84,6 +89,27 @@ public static String safeWriteValueAsJson(Object obj) { } } + + /** + * @param jsonObj the JsonObject to get object from + * @return the {@code jsonObj} as Map, or {@code null} if an error occurs + */ + public static Map safeGetValueFromJson(String jsonObj) { + try { + // convert JSON string to Map + return JSON_MAPPER.readValue(jsonObj, new TypeReference>(){}); + } catch (IOException | NullPointerException e) { + // insufficient Map structure -> putting in a JsonNode + Map m = new HashMap(); + try { + m.put("unparsed", JSON_MAPPER.readTree(jsonObj)); + } catch (IOException e1) { + LOGGER.trace(String.format("Error getting value from JSON string: %s", jsonObj), e1); + } + return m; + } + } + /** * Return an instance of {@code destinationClass} with a copy of identical fields to those found * in {@code source}. From d5c43acb96faff3e1eac0342d1e0b4c2c66ff351 Mon Sep 17 00:00:00 2001 From: Quantin Date: Thu, 6 Jul 2017 13:07:25 +0200 Subject: [PATCH 13/13] add multigateway support on api declarative command --- src/main/java/io/apiman/cli/util/MappingUtil.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/apiman/cli/util/MappingUtil.java b/src/main/java/io/apiman/cli/util/MappingUtil.java index 18e3990..df9cc04 100644 --- a/src/main/java/io/apiman/cli/util/MappingUtil.java +++ b/src/main/java/io/apiman/cli/util/MappingUtil.java @@ -36,8 +36,7 @@ import org.modelmapper.config.Configuration; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Shared POJO/JSON/YAML mapping utility methods. @@ -169,7 +168,13 @@ private static ModelMapper buildModelMapper() { final ApiConfig apiConfig = context.getDestination(); apiConfig.setPublicApi(declarativeApiConfig.isMakePublic()); - apiConfig.setGateways(Lists.newArrayList(new ApiGateway(declarativeApiConfig.getGateway()))); + + // Gateways management + final String strGateway = declarativeApiConfig.getGateway(); + final StringTokenizer st = new StringTokenizer(strGateway); + final ArrayList gatewaysList = Lists.newArrayList(); + while (st.hasMoreTokens()) gatewaysList.add(new ApiGateway(st.nextToken())); + apiConfig.setGateways(gatewaysList); return apiConfig; });