From ae6ff735336d619424715f5049af7ec6389c4bbd Mon Sep 17 00:00:00 2001 From: Jean-Charles Quantin Date: Wed, 9 Aug 2017 17:07:00 +0200 Subject: [PATCH 01/15] working with more than one gateways --- .../io/apiman/cli/command/api/model/Api.java | 24 ++- .../cli/command/api/model/ApiConfig.java | 14 +- .../cli/command/api/model/ApiPolicy.java | 4 + .../declarative/model/DeclarativeOrg.java | 24 +++ .../declarative/model/DeclarativePolicy.java | 28 +++- .../io/apiman/cli/command/org/model/Org.java | 15 ++ .../core/api/command/ApiDeepListCommand.java | 158 ++++++++++++++++++ .../io/apiman/cli/core/api/model/ApiPlan.java | 51 ++++++ .../io/apiman/cli/core/client/ClientApi.java | 62 +++++++ .../apiman/cli/core/client/model/ApiKey.java | 40 +++++ .../apiman/cli/core/client/model/Client.java | 85 ++++++++++ .../cli/core/client/model/Contract.java | 73 ++++++++ .../core/client/model/DeclaredContract.java | 73 ++++++++ .../declarative/model/DeclarativePlan.java | 47 ++++++ .../io/apiman/cli/core/org/model/Bean.java | 108 ++++++++++++ .../io/apiman/cli/core/org/model/Filter.java | 69 ++++++++ .../io/apiman/cli/core/org/model/OrderBy.java | 56 +++++++ .../cli/core/org/model/OrgSearchIn.java | 97 +++++++++++ .../cli/core/org/model/OrgSearchOut.java | 60 +++++++ .../io/apiman/cli/core/org/model/Paging.java | 56 +++++++ .../java/io/apiman/cli/core/plan/PlanApi.java | 64 +++++++ .../io/apiman/cli/core/plan/model/Plan.java | 100 +++++++++++ .../cli/core/plan/model/PlanVersion.java | 43 +++++ .../cli/management/factory/PostConverter.java | 6 + .../command/api/Version11xServerApi.java | 10 ++ .../command/api/Version12xServerApi.java | 10 ++ .../command/api/VersionAgnosticApi.java | 9 +- .../command/api/command/ApiCommand.java | 1 + .../Version11XManagementApiFactoryImpl.java | 14 ++ .../Version12XManagementApiFactoryImpl.java | 20 ++- .../command/common/util/ServerActionUtil.java | 46 +++++ .../cli/managerapi/command/org/OrgApi.java | 3 + .../ManagementApiFactoryModule.java | 8 + .../factory/AbstractManagementApiFactory.java | 32 +++- .../factory/ManagementApiFactory.java | 3 +- .../SimpleManagementApiFactoryImpl.java | 10 +- .../java/io/apiman/cli/util/MappingUtil.java | 8 + .../cli/command/GatewayDeclarativeTest.java | 2 +- 38 files changed, 1514 insertions(+), 19 deletions(-) create mode 100644 src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java create mode 100644 src/main/java/io/apiman/cli/core/api/model/ApiPlan.java create mode 100644 src/main/java/io/apiman/cli/core/client/ClientApi.java create mode 100644 src/main/java/io/apiman/cli/core/client/model/ApiKey.java create mode 100644 src/main/java/io/apiman/cli/core/client/model/Client.java create mode 100644 src/main/java/io/apiman/cli/core/client/model/Contract.java create mode 100644 src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java create mode 100644 src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/Bean.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/Filter.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/OrderBy.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java create mode 100644 src/main/java/io/apiman/cli/core/org/model/Paging.java create mode 100644 src/main/java/io/apiman/cli/core/plan/PlanApi.java create mode 100644 src/main/java/io/apiman/cli/core/plan/model/Plan.java create mode 100644 src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java create mode 100644 src/main/java/io/apiman/cli/management/factory/PostConverter.java diff --git a/src/main/java/io/apiman/cli/command/api/model/Api.java b/src/main/java/io/apiman/cli/command/api/model/Api.java index 6e0af99..c4526b0 100644 --- a/src/main/java/io/apiman/cli/command/api/model/Api.java +++ b/src/main/java/io/apiman/cli/command/api/model/Api.java @@ -28,7 +28,8 @@ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class Api { - @JsonProperty + + @JsonProperty private String name; @JsonProperty @@ -81,4 +82,25 @@ public String getVersion() { public String getStatus() { return status; } + + public void clearStatus() { + this.status = null; + } + + public String getOrganizationName() { + return organizationName; + } + + public void setOrganizationName(String organizationName) { + this.organizationName = organizationName; + } + + public String getDescription() { + return description; + } + + public void setName(String name) { + this.name = name; + } + } 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 8da1087..092549e 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,14 +46,18 @@ 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 List getGateways() { @@ -76,6 +80,14 @@ public void setGateways(ArrayList gateways) { this.gateways = gateways; } + public void setPlans(ArrayList plans) { + this.plans = plans; + } + + public List getPlans() { + return plans; + } + public void setPublicApi(boolean publicApi) { this.publicApi = publicApi; } 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..e534f9c 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 @@ -56,6 +56,10 @@ public ApiPolicy(String configuration) { this.configuration = configuration; } + public String getConfiguration() { + return configuration; + } + public String getPolicyDefinitionId() { return policyDefinitionId; } 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..b99b59c 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 @@ -33,7 +33,15 @@ public class DeclarativeOrg extends Org { @JsonProperty private List apis; + + @JsonProperty + private List plans; + + @JsonProperty + private List clients; + + public List getApis() { return apis; } @@ -41,4 +49,20 @@ public List getApis() { public void setApis(List apis) { this.apis = apis; } + + public List getPlans() { + return plans; + } + + public void setPlans(List plans) { + this.plans = plans; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } } 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 0f7520c..e7549ef 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 @@ -16,13 +16,15 @@ package io.apiman.cli.command.declarative.model; -import java.util.Map; +import java.io.IOException; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; /** * Declarative policy representation. @@ -43,7 +45,7 @@ public class DeclarativePolicy { private String plugin; @JsonProperty - private Map config; + private JsonNode config; public String getId() { return id; @@ -57,13 +59,20 @@ public void setName(String name) { this.name = name; } - public Map getConfig() { + public JsonNode getConfig() { return config; } - - public void setConfig(Map config) { - this.config = config; - } + + public void setConfig(String jsonConfig) { + ObjectMapper mapper = new ObjectMapper(); + JsonNode actualObj = null; + try { + actualObj = mapper.readTree(jsonConfig); + } catch (IOException e) { + e.printStackTrace(); + } + this.config = actualObj; + } public String getPlugin() { return plugin; @@ -76,4 +85,9 @@ public void setPlugin(String plugin) { public boolean isPlugin() { return !(plugin == null || plugin.isEmpty()); } + + public void setId(String id) { + this.id = id; + } + } diff --git a/src/main/java/io/apiman/cli/command/org/model/Org.java b/src/main/java/io/apiman/cli/command/org/model/Org.java index 0ca11a8..b885f23 100644 --- a/src/main/java/io/apiman/cli/command/org/model/Org.java +++ b/src/main/java/io/apiman/cli/command/org/model/Org.java @@ -16,10 +16,18 @@ package io.apiman.cli.command.org.model; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import io.apiman.cli.ManagerApi; +import io.apiman.cli.core.api.model.Api; +import io.apiman.cli.core.org.OrgApi; +import io.apiman.cli.management.factory.ManagementApiFactory; + /** * Models an organisation. * @@ -34,6 +42,9 @@ public class Org { @JsonProperty private String description; + @JsonIgnore + public ManagerApi managerApi; + public Org() { } @@ -45,4 +56,8 @@ public Org(String name, String description) { public String getName() { return name; } + + public List listApis() throws Exception { + return managerApi.api().list(getName()); + } } diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java b/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java new file mode 100644 index 0000000..48afdee --- /dev/null +++ b/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java @@ -0,0 +1,158 @@ +/* + * 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.core.api.command; + +import java.io.IOException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.kohsuke.args4j.CmdLineParser; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.apiman.cli.core.api.ApiMixin; +import io.apiman.cli.core.api.VersionAgnosticApi; +import io.apiman.cli.core.api.model.Api; +import io.apiman.cli.core.api.model.ApiPolicy; +import io.apiman.cli.core.declarative.model.BaseDeclaration; +import io.apiman.cli.core.declarative.model.DeclarativeApi; +import io.apiman.cli.core.declarative.model.DeclarativeApiConfig; +import io.apiman.cli.core.declarative.model.DeclarativeOrg; +import io.apiman.cli.core.declarative.model.DeclarativePlan; +import io.apiman.cli.core.declarative.model.DeclarativePolicy; +import io.apiman.cli.core.plan.PlanApi; +import io.apiman.cli.core.plan.model.Plan; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.util.LogUtil; +import io.apiman.cli.util.MappingUtil; + +/** + * 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); + + @Override + protected String getCommandDescription() { + return MessageFormat.format("List {0}s", getModelName()); + } + + @Override + public void performAction(CmdLineParser parser) throws CommandException { + final BaseDeclaration baseDeclaration = getDeepListBaseDeclaration(); + LOGGER.debug("Outputting the BaseDeclaration"); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(baseDeclaration)); + } + + public BaseDeclaration getDeepListBaseDeclaration() { + LOGGER.debug("Listing {}", this::getModelName); + + final BaseDeclaration baseDeclaration = new BaseDeclaration(); + LOGGER.debug("Creating a BaseDeclaration root object"); + try { + baseDeclaration + .setOrg(MappingUtil.JSON_MAPPER.readValue("{\"name\": \"" + orgName + "\"}", DeclarativeOrg.class)); + } catch (IOException e) { + LogUtil.OUTPUT.error("deserialisation error"); + throw new CommandException(e); + } + + LOGGER.debug("Populating the BaseDeclaration with apis"); + baseDeclaration.getOrg().setApis(new ArrayList()); + + VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); + final List apis = apiClient.list(orgName); + + apis.forEach(api -> { + apiClient.fetchVersions(orgName, api.getName()).forEach(apiVersion -> { + + apiVersion.clearStatus(); + final DeclarativeApi declApi = MappingUtil.map(apiVersion, DeclarativeApi.class); + declApi.setOrganizationName(null); + declApi.setConfig( + MappingUtil.map(apiClient.fetchVersionConfig(orgName, api.getName(), apiVersion.getVersion()), + DeclarativeApiConfig.class)); + declApi.getConfig().setGateway(""); + declApi.getConfig().getGateways().forEach(gw -> { + declApi.getConfig().setGateway(declApi.getConfig().getGateway() + " " + gw.getGatewayId()); + }); + + 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()); + try { + declarativePolicy + .setConfig(MappingUtil.JSON_MAPPER.writeValueAsString(apiPolicy.getConfiguration())); + } catch (JsonProcessingException e) { + LogUtil.OUTPUT.error("APIPolicy serialisation error"); + throw new CommandException(e); + } + + listPolicies.add(declarativePolicy); + }); + declApi.setPolicies(listPolicies); + baseDeclaration.getOrg().getApis().add(declApi); + }); + }); + LOGGER.debug("Populating the BaseDeclaration with plans"); + baseDeclaration.getOrg().setPlans(new ArrayList()); + PlanApi planClient = buildServerApiClient(PlanApi.class); + final List plans = planClient.list(orgName); + + plans.forEach(plan -> { + planClient.fetchVersions(orgName, plan.getName()).forEach(planVersion -> { + + final DeclarativePlan declPlan = MappingUtil.map(planVersion, DeclarativePlan.class); + + final List listPolicies = new ArrayList(); + planClient.fetchPolicies(orgName, plan.getName(), planVersion.getVersion()).forEach(policy -> { + ApiPolicy apiPolicy = planClient.fetchPolicy(orgName, plan.getName(), planVersion.getVersion(), + policy.getId()); + DeclarativePolicy declarativePolicy = MappingUtil.map(apiPolicy, DeclarativePolicy.class); + declarativePolicy.setName(policy.getPolicyDefinitionId()); + declarativePolicy.setId(policy.getId().toString()); + try { + declarativePolicy + .setConfig(MappingUtil.JSON_MAPPER.writeValueAsString(apiPolicy.getConfiguration())); + } catch (JsonProcessingException e) { + LogUtil.OUTPUT.error("APIPolicy serialisation error"); + throw new CommandException(e); + } + + listPolicies.add(declarativePolicy); + }); + declPlan.setPolicies(listPolicies); + baseDeclaration.getOrg().getPlans().add(declPlan); + }); + }); + + + + + + return baseDeclaration; + } +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiPlan.java b/src/main/java/io/apiman/cli/core/api/model/ApiPlan.java new file mode 100644 index 0000000..1e94618 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/api/model/ApiPlan.java @@ -0,0 +1,51 @@ +/* + * 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.core.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; + } + + public String getPlanId() { + return planId; + } + + public String getVersion() { + return version; + } + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/client/ClientApi.java b/src/main/java/io/apiman/cli/core/client/ClientApi.java new file mode 100644 index 0000000..7615f49 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/client/ClientApi.java @@ -0,0 +1,62 @@ +/* + * 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.core.client; + +import java.util.List; + +import io.apiman.cli.core.client.model.ApiKey; +import io.apiman.cli.core.client.model.Client; +import io.apiman.cli.core.client.model.Contract; +import io.apiman.cli.core.client.model.DeclaredContract; +import io.apiman.manager.api.beans.clients.NewClientBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; +import retrofit.http.Body; +import retrofit.http.GET; +import retrofit.http.POST; +import retrofit.http.Path; + +/** + * @author Jean-Charles Quantin {@literal } + */ +public interface ClientApi { + @POST("/organizations/{orgName}/clients") + Response create(@Path("orgName") String orgName, @Body NewClientBean client); + + @GET("/organizations/{orgName}/clients/{clientName}") + Client fetch(@Path("orgName") String orgName, @Path("clientName") String clientName); + + @POST("/organizations/{orgName}/clients/{clientName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Body NewClientVersionBean client); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}") + Client fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/apikey") + ApiKey getApiKey(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @POST("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") + Response createContract(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Body Contract contract); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") + List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/client/model/ApiKey.java b/src/main/java/io/apiman/cli/core/client/model/ApiKey.java new file mode 100644 index 0000000..ed2257d --- /dev/null +++ b/src/main/java/io/apiman/cli/core/client/model/ApiKey.java @@ -0,0 +1,40 @@ +/* + * 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.core.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author Jean-Charles Quantin {@literal } + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ApiKey { + + @JsonProperty + private String apiKey; + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + +} diff --git a/src/main/java/io/apiman/cli/core/client/model/Client.java b/src/main/java/io/apiman/cli/core/client/model/Client.java new file mode 100644 index 0000000..b8bb2d4 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/client/model/Client.java @@ -0,0 +1,85 @@ +/* + * 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.core.client.model; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author Jean-Charles Quantin {@literal } + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class Client { + @JsonProperty + private String name; + + @JsonProperty + private String description; + + @JsonProperty + private String version; + + @JsonProperty + private String apiKey; + + @JsonProperty + private List contracts; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public List getContracts() { + return contracts; + } + + public void setContracts(List contracts) { + this.contracts = contracts; + } + +} diff --git a/src/main/java/io/apiman/cli/core/client/model/Contract.java b/src/main/java/io/apiman/cli/core/client/model/Contract.java new file mode 100644 index 0000000..854fe11 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/client/model/Contract.java @@ -0,0 +1,73 @@ +/* + * 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.core.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * @author Jean-Charles Quantin {@literal } + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public class Contract { + + @JsonProperty + private String planId; + + @JsonProperty + private String apiOrgId; + + @JsonProperty + private String apiId; + + @JsonProperty + private String apiVersion; + + public String getPlanId() { + return planId; + } + + public void setPlanId(String planId) { + this.planId = planId; + } + + public String getApiOrgId() { + return apiOrgId; + } + + public void setApiOrgId(String apiOrgId) { + this.apiOrgId = apiOrgId; + } + + public String getApiId() { + return apiId; + } + + public void setApiId(String apiId) { + this.apiId = apiId; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + +} diff --git a/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java b/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java new file mode 100644 index 0000000..c9d97ec --- /dev/null +++ b/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java @@ -0,0 +1,73 @@ +/* + * 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.core.client.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * @author Jean-Charles Quantin {@literal } + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public class DeclaredContract { + + @JsonProperty + private String planId; + + @JsonProperty + private String apiOrganizationId; + + @JsonProperty + private String apiId; + + @JsonProperty + private String apiVersion; + + public String getPlanId() { + return planId; + } + + public void setPlanId(String planId) { + this.planId = planId; + } + + public String getApiOrganizationId() { + return apiOrganizationId; + } + + public void setApiOrganizationId(String apiOrganizationId) { + this.apiOrganizationId = apiOrganizationId; + } + + public String getApiId() { + return apiId; + } + + public void setApiId(String apiId) { + this.apiId = apiId; + } + + public String getApiVersion() { + return apiVersion; + } + + public void setApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + } + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java b/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java new file mode 100644 index 0000000..e0383d2 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java @@ -0,0 +1,47 @@ +package io.apiman.cli.core.declarative.model; +/* + * 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. + */ + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import io.apiman.cli.core.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; + } + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/org/model/Bean.java b/src/main/java/io/apiman/cli/core/org/model/Bean.java new file mode 100644 index 0000000..083bf44 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/Bean.java @@ -0,0 +1,108 @@ +package io.apiman.cli.core.org.model; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"name", +"id", +"description", +"numClients", +"numMembers", +"numApis" +}) +public class Bean { + +@JsonProperty("name") +private String name; +@JsonProperty("id") +private String id; +@JsonProperty("description") +private String description; +@JsonProperty("numClients") +private String numClients; +@JsonProperty("numMembers") +private String numMembers; +@JsonProperty("numApis") +private String numApis; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("name") +public String getName() { +return name; +} + +@JsonProperty("name") +public void setName(String name) { +this.name = name; +} + +@JsonProperty("id") +public String getId() { +return id; +} + +@JsonProperty("id") +public void setId(String id) { +this.id = id; +} + +@JsonProperty("description") +public String getDescription() { +return description; +} + +@JsonProperty("description") +public void setDescription(String description) { +this.description = description; +} + +@JsonProperty("numClients") +public String getNumClients() { +return numClients; +} + +@JsonProperty("numClients") +public void setNumClients(String numClients) { +this.numClients = numClients; +} + +@JsonProperty("numMembers") +public String getNumMembers() { +return numMembers; +} + +@JsonProperty("numMembers") +public void setNumMembers(String numMembers) { +this.numMembers = numMembers; +} + +@JsonProperty("numApis") +public String getNumApis() { +return numApis; +} + +@JsonProperty("numApis") +public void setNumApis(String numApis) { +this.numApis = numApis; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/org/model/Filter.java b/src/main/java/io/apiman/cli/core/org/model/Filter.java new file mode 100644 index 0000000..ff52c44 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/Filter.java @@ -0,0 +1,69 @@ +package io.apiman.cli.core.org.model; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"name", +"value", +"operator" +}) +public class Filter { + +@JsonProperty("name") +private String name; +@JsonProperty("value") +private String value; +@JsonProperty("operator") +private String operator; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("name") +public String getName() { +return name; +} + +@JsonProperty("name") +public void setName(String name) { +this.name = name; +} + +@JsonProperty("value") +public String getValue() { +return value; +} + +@JsonProperty("value") +public void setValue(String value) { +this.value = value; +} + +@JsonProperty("operator") +public String getOperator() { +return operator; +} + +@JsonProperty("operator") +public void setOperator(String operator) { +this.operator = operator; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/org/model/OrderBy.java b/src/main/java/io/apiman/cli/core/org/model/OrderBy.java new file mode 100644 index 0000000..6bb0e57 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/OrderBy.java @@ -0,0 +1,56 @@ +package io.apiman.cli.core.org.model; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"name", +"ascending" +}) +public class OrderBy { + +@JsonProperty("name") +private String name; +@JsonProperty("ascending") +private String ascending; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("name") +public String getName() { +return name; +} + +@JsonProperty("name") +public void setName(String name) { +this.name = name; +} + +@JsonProperty("ascending") +public String getAscending() { +return ascending; +} + +@JsonProperty("ascending") +public void setAscending(String ascending) { +this.ascending = ascending; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java b/src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java new file mode 100644 index 0000000..3aa0f64 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java @@ -0,0 +1,97 @@ +package io.apiman.cli.core.org.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"filters", +"orderBy", +"pageSize", +"page", +"paging" +}) +public class OrgSearchIn { + +@JsonProperty("filters") +private List filters = new ArrayList(); +@JsonProperty("orderBy") +private OrderBy orderBy; +@JsonProperty("pageSize") +private String pageSize; +@JsonProperty("page") +private String page; +@JsonProperty("paging") +private Paging paging; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("filters") +public List getFilters() { +return filters; +} + +@JsonProperty("filters") +public void setFilters(List filters) { +this.filters = filters; +} + +@JsonProperty("orderBy") +public OrderBy getOrderBy() { +return orderBy; +} + +@JsonProperty("orderBy") +public void setOrderBy(OrderBy orderBy) { +this.orderBy = orderBy; +} + +@JsonProperty("pageSize") +public String getPageSize() { +return pageSize; +} + +@JsonProperty("pageSize") +public void setPageSize(String pageSize) { +this.pageSize = pageSize; +} + +@JsonProperty("page") +public String getPage() { +return page; +} + +@JsonProperty("page") +public void setPage(String page) { +this.page = page; +} + +@JsonProperty("paging") +public Paging getPaging() { +return paging; +} + +@JsonProperty("paging") +public void setPaging(Paging paging) { +this.paging = paging; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java b/src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java new file mode 100644 index 0000000..64f74dd --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java @@ -0,0 +1,60 @@ +package io.apiman.cli.core.org.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"beans", +"totalSize" +}) +public class OrgSearchOut { + +@JsonProperty("beans") +private List beans = new ArrayList(); +@JsonProperty("totalSize") +private String totalSize; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("beans") +public List getBeans() { +return beans; +} + +@JsonProperty("beans") +public void setBeans(List beans) { +this.beans = beans; +} + +@JsonProperty("totalSize") +public String getTotalSize() { +return totalSize; +} + +@JsonProperty("totalSize") +public void setTotalSize(String totalSize) { +this.totalSize = totalSize; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} + diff --git a/src/main/java/io/apiman/cli/core/org/model/Paging.java b/src/main/java/io/apiman/cli/core/org/model/Paging.java new file mode 100644 index 0000000..775756f --- /dev/null +++ b/src/main/java/io/apiman/cli/core/org/model/Paging.java @@ -0,0 +1,56 @@ +package io.apiman.cli.core.org.model; + +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ +"pageSize", +"page" +}) +public class Paging { + +@JsonProperty("pageSize") +private String pageSize; +@JsonProperty("page") +private String page; +@JsonIgnore +private Map additionalProperties = new HashMap(); + +@JsonProperty("pageSize") +public String getPageSize() { +return pageSize; +} + +@JsonProperty("pageSize") +public void setPageSize(String pageSize) { +this.pageSize = pageSize; +} + +@JsonProperty("page") +public String getPage() { +return page; +} + +@JsonProperty("page") +public void setPage(String page) { +this.page = page; +} + +@JsonAnyGetter +public Map getAdditionalProperties() { +return this.additionalProperties; +} + +@JsonAnySetter +public void setAdditionalProperty(String name, Object value) { +this.additionalProperties.put(name, value); +} + +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/plan/PlanApi.java b/src/main/java/io/apiman/cli/core/plan/PlanApi.java new file mode 100644 index 0000000..9a11ce8 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/plan/PlanApi.java @@ -0,0 +1,64 @@ + +/* + * 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.core.plan; + + +import java.util.List; + +import io.apiman.cli.core.api.model.ApiPolicy; +import io.apiman.cli.core.plan.model.Plan; +import io.apiman.cli.core.plan.model.PlanVersion; +import retrofit.client.Response; +import retrofit.http.Body; +import retrofit.http.GET; +import retrofit.http.POST; +import retrofit.http.Path; + +/** + * @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") + List fetchVersions(@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/{planName}/versions/{version}/policies") + List fetchPolicies(@Path("orgName") String orgName, @Path("planName") String planName, + @Path("version") String version); + + @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies/{policyId}") + ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("planName") String planName, + @Path("version") String version, @Path("policyId") Long policyId); +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/plan/model/Plan.java b/src/main/java/io/apiman/cli/core/plan/model/Plan.java new file mode 100644 index 0000000..8cde2e1 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/plan/model/Plan.java @@ -0,0 +1,100 @@ +/* + * 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.core.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 getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setName(String name) { + this.name = name; + } + + 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 void setStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java b/src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java new file mode 100644 index 0000000..abdac61 --- /dev/null +++ b/src/main/java/io/apiman/cli/core/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.core.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; + } +} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/management/factory/PostConverter.java b/src/main/java/io/apiman/cli/management/factory/PostConverter.java new file mode 100644 index 0000000..c78e4b2 --- /dev/null +++ b/src/main/java/io/apiman/cli/management/factory/PostConverter.java @@ -0,0 +1,6 @@ +package io.apiman.cli.management.factory; + +public interface PostConverter { + public void postConvert(Object o); + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java index 5bc3101..1b3db41 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java @@ -52,6 +52,12 @@ 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); + + @GET("/organizations/{orgName}/services/{serviceName}/versions/{version}") + ApiConfig fetchVersionConfig(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version); + @PUT("/organizations/{orgName}/services/{serviceName}/versions/{version}") Response configure(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Path("version") String version, @Body ServiceConfig config); @@ -68,6 +74,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/managerapi/command/api/Version12xServerApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java index 524ccb6..88b61bd 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java @@ -52,6 +52,12 @@ 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); + + @GET("/organizations/{orgName}/apis/{apiName}/versions/{version}") + ApiConfig fetchVersionConfig(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version); + @PUT("/organizations/{orgName}/apis/{apiName}/versions/{version}") Response configure(@Path("orgName") String orgName, @Path("apiName") String apiName, @Path("version") String version, @Body ApiConfig config); @@ -68,6 +74,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/managerapi/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java index 6073be3..519a2e0 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java @@ -37,7 +37,11 @@ public interface VersionAgnosticApi { Api fetch(String orgName, String apiName); Api fetchVersion(String orgName, String apiName, String version); - + + List fetchVersions(String orgName, String apiName); + + ApiConfig fetchVersionConfig(String orgName, String apiName, String version); + Response configure(String orgName, String apiName, String version, ApiConfig config); @@ -49,6 +53,9 @@ Response setDefinition(String orgName, String apiName, List fetchPolicies(String orgName, String serviceName, 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/managerapi/command/api/command/ApiCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java index 456b7f8..b84e970 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java @@ -40,6 +40,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); commandMap.put("definition", ApiDefinitionCommand.class); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java index 27e3798..6cb1a6d 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -67,6 +67,15 @@ public Api fetch(String orgName, String apiName) { 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 ApiConfig fetchVersionConfig(String orgName, String apiName, String version) { + return delegate.fetchVersionConfig(orgName, apiName, version); + } @Override public Response configure(String orgName, String apiName, String version, ApiConfig apiConfig) { @@ -90,6 +99,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); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java index 1966487..d69c10e 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java @@ -62,7 +62,20 @@ public Api fetch(String orgName, String apiName) { @Override public Api fetchVersion(String orgName, String apiName, String version) { - return delegate.fetchVersion(orgName, apiName, version); + Api api = delegate.fetchVersion(orgName, apiName, version); + api.setOrganizationName(orgName); + api.setName(apiName); + return api; + } + + @Override + public List fetchVersions(String orgName, String apiName) { + return delegate.fetchVersions(orgName, apiName); + } + + @Override + public ApiConfig fetchVersionConfig(String orgName, String apiName, String version) { + return delegate.fetchVersionConfig(orgName, apiName, version); } @Override @@ -85,6 +98,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); diff --git a/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java b/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java index 5e19b94..b15f5d5 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java +++ b/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java @@ -64,4 +64,50 @@ public static void publishApi(String orgName, String apiName, String apiVersion, return apiClient.doAction(action); }); } + + /** + * Lock a Plan. + * + * @param orgName the organisation name + * @param planName the plan name + * @param planVersion the plan version + * @param actionClient the Server Action Plan client + */ + public static void lockPlan(String orgName, String planName, String planVersion, ActionApi actionClient) { + String actionType = "lockPlan"; + + ManagementApiUtil.invokeAndCheckResponse(HttpURLConnection.HTTP_NO_CONTENT, () -> { + final ServerAction action = new ServerAction( + actionType, + orgName, + planName, + planVersion + ); + + return actionClient.doAction(action); + }); + } + + /** + * Register a Client. + * + * @param orgName the organisation name + * @param clientName the client name + * @param clientVersion the client version + * @param actionClient the Server Action API client + */ + public static void registerClient(String orgName, String clientName, String clientVersion, ActionApi actionClient) { + String actionType = "registerClient"; + + ManagementApiUtil.invokeAndCheckResponse(HttpURLConnection.HTTP_NO_CONTENT, () -> { + final ServerAction action = new ServerAction( + actionType, + orgName, + clientName, + clientVersion + ); + + return actionClient.doAction(action); + }); + } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java b/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java index 48a714d..1d316a7 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java @@ -32,4 +32,7 @@ public interface OrgApi { @GET("/organizations/{orgName}") Org fetch(@Path("orgName") String orgName); + + @POST("/search/organizations/") + OrgSearchOut search(@Body OrgSearchIn orgSearch); } diff --git a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java index c90d312..6f22567 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java +++ b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java @@ -66,5 +66,13 @@ 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)); + + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(ClientApi.class)) + .toInstance(new SimpleManagementApiFactoryImpl<>(ClientApi.class)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java b/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java index a64f720..6908a1c 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java @@ -18,11 +18,17 @@ import io.apiman.cli.util.AuthUtil; import retrofit.RestAdapter; +import retrofit.converter.ConversionException; +import retrofit.converter.Converter; import retrofit.converter.JacksonConverter; +import retrofit.mime.TypedInput; +import retrofit.mime.TypedOutput; import static io.apiman.cli.util.AuthUtil.HEADER_AUTHORIZATION; import static io.apiman.cli.util.MappingUtil.JSON_MAPPER; +import java.lang.reflect.Type; + /** * Builds a Management API client proxy for a given API interface. * @@ -38,9 +44,31 @@ public abstract class AbstractManagementApiFactory implements ManagementAp * @param debugLogging whether debug logging should be enabled * @return an API client for the given Class */ - protected A buildClient(Class apiClass, String endpoint, String username, String password, boolean debugLogging) { + protected A buildClient(Class apiClass, String endpoint, String username, String password, boolean debugLogging, PostConverter postConverter) { + final JacksonConverter jacksonConverter = new JacksonConverter(JSON_MAPPER); + final Converter converter; + if (postConverter == null) { + converter = jacksonConverter; + } else { + converter = new Converter() { + + @Override + public Object fromBody(TypedInput body, Type type) throws ConversionException { + final Object o = jacksonConverter.fromBody(body, type); + postConverter.postConvert(o); + return o; + } + + @Override + public TypedOutput toBody(Object object) { + return jacksonConverter.toBody(object); + } + + }; + } + final RestAdapter.Builder builder = new RestAdapter.Builder() // - .setConverter(new JacksonConverter(JSON_MAPPER)) + .setConverter(converter) .setEndpoint(endpoint) .setRequestInterceptor(request -> { request.addHeader(HEADER_AUTHORIZATION, AuthUtil.buildAuthString(username, password)); diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java index 107a2bf..0dbf283 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java @@ -27,7 +27,8 @@ public interface ManagementApiFactory { * @param username the management API username * @param password the management API password * @param debugLogging whether debug logging should be enabled + * @param postConverter the PostConverter if needs * @return an API client for the given Class */ - T build(String endpoint, String username, String password, boolean debugLogging); + T build(String endpoint, String username, String password, boolean debugLogging, PostConverter postConverter); } diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java index d904374..4db82f4 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java @@ -28,8 +28,10 @@ public SimpleManagementApiFactoryImpl(Class apiClass) { this.apiClass = apiClass; } - @Override - public T build(String endpoint, String username, String password, boolean debugLogging) { - return buildClient(apiClass, endpoint, username, password, debugLogging); - } + + @Override + public T build(String endpoint, String username, String password, boolean debugLogging, + PostConverter postConverter) { + return buildClient(apiClass, endpoint, username, password, debugLogging, postConverter); + } } diff --git a/src/main/java/io/apiman/cli/util/MappingUtil.java b/src/main/java/io/apiman/cli/util/MappingUtil.java index 6041357..8d87df1 100644 --- a/src/main/java/io/apiman/cli/util/MappingUtil.java +++ b/src/main/java/io/apiman/cli/util/MappingUtil.java @@ -197,6 +197,14 @@ private static ModelMapper buildModelMapper() { 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; }); diff --git a/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java b/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java index a9c3b60..1f6ed44 100644 --- a/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java +++ b/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java @@ -53,7 +53,7 @@ public void setUp() { command.setLogDebug(LOG_DEBUG); LogUtil.configureLogging(LOG_DEBUG); // Stub Gateway API Factory - when(mGatewayApiFactory.build("http://localhost:8080/apiman-gateway-api", "apimanager", "apiman123!", true)) + when(mGatewayApiFactory.build("http://localhost:8080/apiman-gateway-api", "apimanager", "apiman123!", true, null)) .thenReturn(mGatewayApi); // Bake in OK status SystemStatus okStatus = new SystemStatus(); From c105f0f0f81ccfee62c4af823293d4aa3fad53dc Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sat, 7 Apr 2018 10:50:30 +0100 Subject: [PATCH 02/15] Add initial support for Clients and Plans, with 1.x and 2.x support. Rework contributed code to conform to existing standards. --- src/main/java/io/apiman/cli/ManagerCli.java | 4 + .../cli/command/api/model/ApiConfig.java | 24 ++- .../{core => command}/api/model/ApiPlan.java | 4 +- .../client/model/ApiKey.java | 2 +- .../client/model/Client.java | 29 +++- .../client/model/Contract.java | 2 +- .../client/model/DeclaredContract.java | 73 ++++++++ .../declarative/model/DeclarativeOrg.java | 12 +- .../declarative/model/DeclarativePlan.java | 7 +- .../cli/{core => command}/org/model/Bean.java | 9 +- .../{core => command}/org/model/Filter.java | 9 +- .../io/apiman/cli/command/org/model/Org.java | 17 +- .../org/model/OrgSearchIn.java | 15 +- .../org/model/OrgSearchOut.java | 12 +- .../{core => command}/plan/model/Plan.java | 4 +- .../plan/model/PlanVersion.java | 4 +- .../core/api/command/ApiDeepListCommand.java | 158 ------------------ .../io/apiman/cli/core/client/ClientApi.java | 62 ------- .../core/client/model/DeclaredContract.java | 73 -------- .../command => }/AbstractManagerCommand.java | 4 +- .../apiman/cli/managerapi/ManagerCommon.java | 11 ++ .../command/api/Version11xServerApi.java | 1 + .../command/api/VersionAgnosticApi.java | 2 +- .../api/command/AbstractApiCommand.java | 6 +- .../command/api/command/ApiCommand.java | 3 +- .../command/api/command/ApiCreateCommand.java | 3 +- .../api/command/ApiDefinitionCommand.java | 3 +- .../command/api/command/ApiListCommand.java | 4 +- .../api/command/ApiPolicyAddCommand.java | 4 +- .../command/api/command/ApiPolicyCommand.java | 1 + .../api/command/ApiPublishCommand.java | 6 +- .../Version11XManagementApiFactoryImpl.java | 5 +- .../managerapi/command/client/ClientApi.java | 51 ++++++ .../command/client/ClientApiVersion1x.java | 52 ++++++ .../command/client/ClientApiVersion2x.java | 52 ++++++ .../client/Version2xClientFactoryImpl.java | 74 ++++++++ .../client/command/AbstractClientCommand.java | 47 ++++++ .../command/AbstractManagerCommand.java | 15 ++ .../command/client/command/ClientCommand.java | 47 ++++++ .../client/command/ClientCreateCommand.java | 71 ++++++++ .../client/command/ClientListCommand.java | 83 +++++++++ .../command/ClientPolicyAddCommand.java | 96 +++++++++++ .../client/command/ClientPolicyCommand.java | 44 +++++ .../client/command/ClientRegisterCommand.java | 66 ++++++++ .../command/common/util/ServerActionUtil.java | 15 +- .../gateway/command/GatewayCommand.java | 2 +- .../cli/managerapi/command/org/OrgApi.java | 4 +- .../command/org/command/OrgCommand.java | 2 +- .../command}/plan/PlanApi.java | 15 +- .../plan/command/AbstractPlanCommand.java | 37 ++++ .../command/plan/command/PlanCommand.java | 46 +++++ .../plan/command/PlanCreateCommand.java | 67 ++++++++ .../command/plan/command/PlanListCommand.java | 54 ++++++ .../command/plan/command/PlanLockCommand.java | 60 +++++++ .../plan/command/PlanPolicyAddCommand.java | 92 ++++++++++ .../plan/command/PlanPolicyCommand.java | 43 +++++ .../command/plugin/command/PluginCommand.java | 2 +- .../command/ManagerApplyCommand.java | 8 +- .../ManagementApiFactoryModule.java | 12 +- .../factory/AbstractManagementApiFactory.java | 34 +--- .../factory/ManagementApiFactory.java | 4 +- .../SimpleManagementApiFactoryImpl.java | 5 +- src/main/java/io/apiman/cli/util/LogUtil.java | 3 +- .../java/io/apiman/cli/util/MappingUtil.java | 2 + .../cli/command/GatewayDeclarativeTest.java | 2 +- 65 files changed, 1356 insertions(+), 424 deletions(-) rename src/main/java/io/apiman/cli/{core => command}/api/model/ApiPlan.java (96%) rename src/main/java/io/apiman/cli/{core => command}/client/model/ApiKey.java (96%) rename src/main/java/io/apiman/cli/{core => command}/client/model/Client.java (77%) rename src/main/java/io/apiman/cli/{core => command}/client/model/Contract.java (97%) create mode 100644 src/main/java/io/apiman/cli/command/client/model/DeclaredContract.java rename src/main/java/io/apiman/cli/{core => command}/declarative/model/DeclarativePlan.java (93%) rename src/main/java/io/apiman/cli/{core => command}/org/model/Bean.java (98%) rename src/main/java/io/apiman/cli/{core => command}/org/model/Filter.java (97%) rename src/main/java/io/apiman/cli/{core => command}/org/model/OrgSearchIn.java (93%) rename src/main/java/io/apiman/cli/{core => command}/org/model/OrgSearchOut.java (97%) rename src/main/java/io/apiman/cli/{core => command}/plan/model/Plan.java (98%) rename src/main/java/io/apiman/cli/{core => command}/plan/model/PlanVersion.java (96%) delete mode 100644 src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java delete mode 100644 src/main/java/io/apiman/cli/core/client/ClientApi.java delete mode 100644 src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java rename src/main/java/io/apiman/cli/managerapi/{command/api/command => }/AbstractManagerCommand.java (89%) create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractClientCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractManagerCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientListCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyAddCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientRegisterCommand.java rename src/main/java/io/apiman/cli/{core => managerapi/command}/plan/PlanApi.java (92%) create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanLockCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyAddCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyCommand.java diff --git a/src/main/java/io/apiman/cli/ManagerCli.java b/src/main/java/io/apiman/cli/ManagerCli.java index f709416..0d52c13 100644 --- a/src/main/java/io/apiman/cli/ManagerCli.java +++ b/src/main/java/io/apiman/cli/ManagerCli.java @@ -20,8 +20,10 @@ import io.apiman.cli.command.core.AbstractCommand; import io.apiman.cli.command.core.Command; import io.apiman.cli.managerapi.command.api.command.ApiCommand; +import io.apiman.cli.managerapi.command.client.command.ClientCommand; import io.apiman.cli.managerapi.command.gateway.command.GatewayCommand; import io.apiman.cli.managerapi.command.org.command.OrgCommand; +import io.apiman.cli.managerapi.command.plan.command.PlanCommand; import io.apiman.cli.managerapi.command.plugin.command.PluginCommand; import io.apiman.cli.managerapi.declarative.command.ManagerApplyCommand; @@ -42,6 +44,8 @@ protected void populateCommands(Map> commandMap commandMap.put("gateway", GatewayCommand.class); commandMap.put("plugin", PluginCommand.class); commandMap.put("api", ApiCommand.class); + commandMap.put("client", ClientCommand.class); + commandMap.put("plan", PlanCommand.class); commandMap.put("apply", ManagerApplyCommand.class); } 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 092549e..2b8ffef 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 @@ -16,6 +16,7 @@ package io.apiman.cli.command.api.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -49,9 +50,20 @@ public class ApiConfig { @JsonProperty private List plans; + @JsonIgnore + private boolean hasPlans; + public ApiConfig() { } + public ApiConfig(String endpoint, String endpointType, boolean publicApi, List gateways) { + this.endpoint = endpoint; + this.endpointType = endpointType; + this.publicApi = publicApi; + this.gateways = gateways; + this.hasPlans = false; + } + public ApiConfig(String endpoint, String endpointType, boolean publicApi, List gateways, List plans) { this.endpoint = endpoint; this.endpointType = endpointType; @@ -80,14 +92,14 @@ public void setGateways(ArrayList gateways) { this.gateways = gateways; } - public void setPlans(ArrayList plans) { - this.plans = plans; - } - public List getPlans() { return plans; } + public void setPlans(ArrayList plans) { + this.plans = plans; + } + public void setPublicApi(boolean publicApi) { this.publicApi = publicApi; } @@ -99,4 +111,8 @@ public boolean isPublicApi() { public void setEndpointProperties(EndpointProperties endpointProperties) { this.endpointProperties = endpointProperties; } + + public boolean hasPlans() { + return hasPlans; + } } diff --git a/src/main/java/io/apiman/cli/core/api/model/ApiPlan.java b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java similarity index 96% rename from src/main/java/io/apiman/cli/core/api/model/ApiPlan.java rename to src/main/java/io/apiman/cli/command/api/model/ApiPlan.java index 1e94618..1d39ec1 100644 --- a/src/main/java/io/apiman/cli/core/api/model/ApiPlan.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java @@ -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; @@ -48,4 +48,4 @@ public String getVersion() { return version; } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/client/model/ApiKey.java b/src/main/java/io/apiman/cli/command/client/model/ApiKey.java similarity index 96% rename from src/main/java/io/apiman/cli/core/client/model/ApiKey.java rename to src/main/java/io/apiman/cli/command/client/model/ApiKey.java index ed2257d..fd5cf62 100644 --- a/src/main/java/io/apiman/cli/core/client/model/ApiKey.java +++ b/src/main/java/io/apiman/cli/command/client/model/ApiKey.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apiman.cli.core.client.model; +package io.apiman.cli.command.client.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/src/main/java/io/apiman/cli/core/client/model/Client.java b/src/main/java/io/apiman/cli/command/client/model/Client.java similarity index 77% rename from src/main/java/io/apiman/cli/core/client/model/Client.java rename to src/main/java/io/apiman/cli/command/client/model/Client.java index b8bb2d4..895c38b 100644 --- a/src/main/java/io/apiman/cli/core/client/model/Client.java +++ b/src/main/java/io/apiman/cli/command/client/model/Client.java @@ -13,27 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apiman.cli.core.client.model; - -import java.util.List; +package io.apiman.cli.command.client.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + /** * @author Jean-Charles Quantin {@literal } */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) public class Client { - @JsonProperty + + @JsonProperty private String name; @JsonProperty private String description; @JsonProperty + private String initialVersion; + + @JsonProperty private String version; @JsonProperty @@ -42,6 +46,15 @@ public class Client { @JsonProperty private List contracts; + public Client() { + } + + public Client(String name, String description, String initialVersion) { + this.name = name; + this.description = description; + this.initialVersion = initialVersion; + } + public String getName() { return name; } @@ -82,4 +95,12 @@ public void setContracts(List contracts) { this.contracts = contracts; } + public String getInitialVersion() { + return initialVersion; + } + + public Client setInitialVersion(String initialVersion) { + this.initialVersion = initialVersion; + return this; + } } diff --git a/src/main/java/io/apiman/cli/core/client/model/Contract.java b/src/main/java/io/apiman/cli/command/client/model/Contract.java similarity index 97% rename from src/main/java/io/apiman/cli/core/client/model/Contract.java rename to src/main/java/io/apiman/cli/command/client/model/Contract.java index 854fe11..bf0d5fe 100644 --- a/src/main/java/io/apiman/cli/core/client/model/Contract.java +++ b/src/main/java/io/apiman/cli/command/client/model/Contract.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apiman.cli.core.client.model; +package io.apiman.cli.command.client.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/io/apiman/cli/command/client/model/DeclaredContract.java b/src/main/java/io/apiman/cli/command/client/model/DeclaredContract.java new file mode 100644 index 0000000..e3d312b --- /dev/null +++ b/src/main/java/io/apiman/cli/command/client/model/DeclaredContract.java @@ -0,0 +1,73 @@ +///* +// * 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.client.model; +// +//import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +//import com.fasterxml.jackson.annotation.JsonProperty; +//import com.fasterxml.jackson.databind.annotation.JsonSerialize; +// +///** +// * @author Jean-Charles Quantin {@literal } +// */ +//@JsonIgnoreProperties(ignoreUnknown = true) +//@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +//public class DeclaredContract { +// +// @JsonProperty +// private String planId; +// +// @JsonProperty +// private String apiOrganizationId; +// +// @JsonProperty +// private String apiId; +// +// @JsonProperty +// private String apiVersion; +// +// public String getPlanId() { +// return planId; +// } +// +// public void setPlanId(String planId) { +// this.planId = planId; +// } +// +// public String getApiOrganizationId() { +// return apiOrganizationId; +// } +// +// public void setApiOrganizationId(String apiOrganizationId) { +// this.apiOrganizationId = apiOrganizationId; +// } +// +// public String getApiId() { +// return apiId; +// } +// +// public void setApiId(String apiId) { +// this.apiId = apiId; +// } +// +// public String getApiVersion() { +// return apiVersion; +// } +// +// public void setApiVersion(String apiVersion) { +// this.apiVersion = apiVersion; +// } +// +//} 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 b99b59c..9f7d817 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 @@ -19,6 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.org.model.Org; import java.util.List; @@ -31,16 +32,23 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public class DeclarativeOrg extends Org { + + public DeclarativeOrg() { + super(); + } + + public DeclarativeOrg(String name, String description) { + super(name, description); + } + @JsonProperty private List apis; - @JsonProperty private List plans; @JsonProperty private List clients; - public List getApis() { return apis; diff --git a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java similarity index 93% rename from src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java rename to src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java index e0383d2..8af73ee 100644 --- a/src/main/java/io/apiman/cli/core/declarative/model/DeclarativePlan.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java @@ -1,4 +1,4 @@ -package io.apiman.cli.core.declarative.model; +package io.apiman.cli.command.declarative.model; /* * Copyright 2017 Jean-Charles Quantin * @@ -19,8 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; - -import io.apiman.cli.core.plan.model.Plan; +import io.apiman.cli.command.plan.model.Plan; import java.util.List; @@ -44,4 +43,4 @@ public void setPolicies(List policies) { this.policies = policies; } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/org/model/Bean.java b/src/main/java/io/apiman/cli/command/org/model/Bean.java similarity index 98% rename from src/main/java/io/apiman/cli/core/org/model/Bean.java rename to src/main/java/io/apiman/cli/command/org/model/Bean.java index 083bf44..9d0d648 100644 --- a/src/main/java/io/apiman/cli/core/org/model/Bean.java +++ b/src/main/java/io/apiman/cli/command/org/model/Bean.java @@ -1,7 +1,5 @@ -package io.apiman.cli.core.org.model; +package io.apiman.cli.command.org.model; -import java.util.HashMap; -import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -9,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.HashMap; +import java.util.Map; + @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "name", @@ -105,4 +106,4 @@ public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/org/model/Filter.java b/src/main/java/io/apiman/cli/command/org/model/Filter.java similarity index 97% rename from src/main/java/io/apiman/cli/core/org/model/Filter.java rename to src/main/java/io/apiman/cli/command/org/model/Filter.java index ff52c44..0b8838e 100644 --- a/src/main/java/io/apiman/cli/core/org/model/Filter.java +++ b/src/main/java/io/apiman/cli/command/org/model/Filter.java @@ -1,7 +1,5 @@ -package io.apiman.cli.core.org.model; +package io.apiman.cli.command.org.model; -import java.util.HashMap; -import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -9,6 +7,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.HashMap; +import java.util.Map; + @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "name", @@ -66,4 +67,4 @@ public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/command/org/model/Org.java b/src/main/java/io/apiman/cli/command/org/model/Org.java index b885f23..63a08a4 100644 --- a/src/main/java/io/apiman/cli/command/org/model/Org.java +++ b/src/main/java/io/apiman/cli/command/org/model/Org.java @@ -16,18 +16,10 @@ package io.apiman.cli.command.org.model; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import io.apiman.cli.ManagerApi; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.org.OrgApi; -import io.apiman.cli.management.factory.ManagementApiFactory; - /** * Models an organisation. * @@ -42,9 +34,6 @@ public class Org { @JsonProperty private String description; - @JsonIgnore - public ManagerApi managerApi; - public Org() { } @@ -56,8 +45,8 @@ public Org(String name, String description) { public String getName() { return name; } - - public List listApis() throws Exception { - return managerApi.api().list(getName()); + + public String getDescription() { + return description; } } diff --git a/src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java b/src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java similarity index 93% rename from src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java rename to src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java index 3aa0f64..a4aaa98 100644 --- a/src/main/java/io/apiman/cli/core/org/model/OrgSearchIn.java +++ b/src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java @@ -1,15 +1,18 @@ -package io.apiman.cli.core.org.model; +package io.apiman.cli.command.org.model; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import io.apiman.cli.core.org.model.OrderBy; +import io.apiman.cli.core.org.model.Paging; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ @@ -94,4 +97,4 @@ public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java b/src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java similarity index 97% rename from src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java rename to src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java index 64f74dd..9f9952a 100644 --- a/src/main/java/io/apiman/cli/core/org/model/OrgSearchOut.java +++ b/src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java @@ -1,9 +1,4 @@ -package io.apiman.cli.core.org.model; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +package io.apiman.cli.command.org.model; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; @@ -12,6 +7,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "beans", diff --git a/src/main/java/io/apiman/cli/core/plan/model/Plan.java b/src/main/java/io/apiman/cli/command/plan/model/Plan.java similarity index 98% rename from src/main/java/io/apiman/cli/core/plan/model/Plan.java rename to src/main/java/io/apiman/cli/command/plan/model/Plan.java index 8cde2e1..d5711a8 100644 --- a/src/main/java/io/apiman/cli/core/plan/model/Plan.java +++ b/src/main/java/io/apiman/cli/command/plan/model/Plan.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.plan.model; +package io.apiman.cli.command.plan.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -97,4 +97,4 @@ public void setStatus(String status) { public String getStatus() { return status; } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java similarity index 96% rename from src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java rename to src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java index abdac61..768865e 100644 --- a/src/main/java/io/apiman/cli/core/plan/model/PlanVersion.java +++ b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.apiman.cli.core.plan.model; +package io.apiman.cli.command.plan.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; @@ -40,4 +40,4 @@ public class PlanVersion { public PlanVersion(String version) { this.version = version; } -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java b/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java deleted file mode 100644 index 48afdee..0000000 --- a/src/main/java/io/apiman/cli/core/api/command/ApiDeepListCommand.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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.core.api.command; - -import java.io.IOException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.kohsuke.args4j.CmdLineParser; - -import com.fasterxml.jackson.core.JsonProcessingException; - -import io.apiman.cli.core.api.ApiMixin; -import io.apiman.cli.core.api.VersionAgnosticApi; -import io.apiman.cli.core.api.model.Api; -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.declarative.model.BaseDeclaration; -import io.apiman.cli.core.declarative.model.DeclarativeApi; -import io.apiman.cli.core.declarative.model.DeclarativeApiConfig; -import io.apiman.cli.core.declarative.model.DeclarativeOrg; -import io.apiman.cli.core.declarative.model.DeclarativePlan; -import io.apiman.cli.core.declarative.model.DeclarativePolicy; -import io.apiman.cli.core.plan.PlanApi; -import io.apiman.cli.core.plan.model.Plan; -import io.apiman.cli.exception.CommandException; -import io.apiman.cli.util.LogUtil; -import io.apiman.cli.util.MappingUtil; - -/** - * 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); - - @Override - protected String getCommandDescription() { - return MessageFormat.format("List {0}s", getModelName()); - } - - @Override - public void performAction(CmdLineParser parser) throws CommandException { - final BaseDeclaration baseDeclaration = getDeepListBaseDeclaration(); - LOGGER.debug("Outputting the BaseDeclaration"); - LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(baseDeclaration)); - } - - public BaseDeclaration getDeepListBaseDeclaration() { - LOGGER.debug("Listing {}", this::getModelName); - - final BaseDeclaration baseDeclaration = new BaseDeclaration(); - LOGGER.debug("Creating a BaseDeclaration root object"); - try { - baseDeclaration - .setOrg(MappingUtil.JSON_MAPPER.readValue("{\"name\": \"" + orgName + "\"}", DeclarativeOrg.class)); - } catch (IOException e) { - LogUtil.OUTPUT.error("deserialisation error"); - throw new CommandException(e); - } - - LOGGER.debug("Populating the BaseDeclaration with apis"); - baseDeclaration.getOrg().setApis(new ArrayList()); - - VersionAgnosticApi apiClient = buildServerApiClient(VersionAgnosticApi.class, serverVersion); - final List apis = apiClient.list(orgName); - - apis.forEach(api -> { - apiClient.fetchVersions(orgName, api.getName()).forEach(apiVersion -> { - - apiVersion.clearStatus(); - final DeclarativeApi declApi = MappingUtil.map(apiVersion, DeclarativeApi.class); - declApi.setOrganizationName(null); - declApi.setConfig( - MappingUtil.map(apiClient.fetchVersionConfig(orgName, api.getName(), apiVersion.getVersion()), - DeclarativeApiConfig.class)); - declApi.getConfig().setGateway(""); - declApi.getConfig().getGateways().forEach(gw -> { - declApi.getConfig().setGateway(declApi.getConfig().getGateway() + " " + gw.getGatewayId()); - }); - - 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()); - try { - declarativePolicy - .setConfig(MappingUtil.JSON_MAPPER.writeValueAsString(apiPolicy.getConfiguration())); - } catch (JsonProcessingException e) { - LogUtil.OUTPUT.error("APIPolicy serialisation error"); - throw new CommandException(e); - } - - listPolicies.add(declarativePolicy); - }); - declApi.setPolicies(listPolicies); - baseDeclaration.getOrg().getApis().add(declApi); - }); - }); - LOGGER.debug("Populating the BaseDeclaration with plans"); - baseDeclaration.getOrg().setPlans(new ArrayList()); - PlanApi planClient = buildServerApiClient(PlanApi.class); - final List plans = planClient.list(orgName); - - plans.forEach(plan -> { - planClient.fetchVersions(orgName, plan.getName()).forEach(planVersion -> { - - final DeclarativePlan declPlan = MappingUtil.map(planVersion, DeclarativePlan.class); - - final List listPolicies = new ArrayList(); - planClient.fetchPolicies(orgName, plan.getName(), planVersion.getVersion()).forEach(policy -> { - ApiPolicy apiPolicy = planClient.fetchPolicy(orgName, plan.getName(), planVersion.getVersion(), - policy.getId()); - DeclarativePolicy declarativePolicy = MappingUtil.map(apiPolicy, DeclarativePolicy.class); - declarativePolicy.setName(policy.getPolicyDefinitionId()); - declarativePolicy.setId(policy.getId().toString()); - try { - declarativePolicy - .setConfig(MappingUtil.JSON_MAPPER.writeValueAsString(apiPolicy.getConfiguration())); - } catch (JsonProcessingException e) { - LogUtil.OUTPUT.error("APIPolicy serialisation error"); - throw new CommandException(e); - } - - listPolicies.add(declarativePolicy); - }); - declPlan.setPolicies(listPolicies); - baseDeclaration.getOrg().getPlans().add(declPlan); - }); - }); - - - - - - return baseDeclaration; - } -} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/client/ClientApi.java b/src/main/java/io/apiman/cli/core/client/ClientApi.java deleted file mode 100644 index 7615f49..0000000 --- a/src/main/java/io/apiman/cli/core/client/ClientApi.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.core.client; - -import java.util.List; - -import io.apiman.cli.core.client.model.ApiKey; -import io.apiman.cli.core.client.model.Client; -import io.apiman.cli.core.client.model.Contract; -import io.apiman.cli.core.client.model.DeclaredContract; -import io.apiman.manager.api.beans.clients.NewClientBean; -import io.apiman.manager.api.beans.clients.NewClientVersionBean; -import retrofit.client.Response; -import retrofit.http.Body; -import retrofit.http.GET; -import retrofit.http.POST; -import retrofit.http.Path; - -/** - * @author Jean-Charles Quantin {@literal } - */ -public interface ClientApi { - @POST("/organizations/{orgName}/clients") - Response create(@Path("orgName") String orgName, @Body NewClientBean client); - - @GET("/organizations/{orgName}/clients/{clientName}") - Client fetch(@Path("orgName") String orgName, @Path("clientName") String clientName); - - @POST("/organizations/{orgName}/clients/{clientName}/versions") - Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, - @Body NewClientVersionBean client); - - @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}") - Client fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, - @Path("version") String version); - - @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/apikey") - ApiKey getApiKey(@Path("orgName") String orgName, @Path("clientName") String clientName, - @Path("version") String version); - - @POST("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") - Response createContract(@Path("orgName") String orgName, @Path("clientName") String clientName, - @Path("version") String version, @Body Contract contract); - - @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") - List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, - @Path("version") String version); - -} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java b/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java deleted file mode 100644 index c9d97ec..0000000 --- a/src/main/java/io/apiman/cli/core/client/model/DeclaredContract.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.core.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -/** - * @author Jean-Charles Quantin {@literal } - */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) -public class DeclaredContract { - - @JsonProperty - private String planId; - - @JsonProperty - private String apiOrganizationId; - - @JsonProperty - private String apiId; - - @JsonProperty - private String apiVersion; - - public String getPlanId() { - return planId; - } - - public void setPlanId(String planId) { - this.planId = planId; - } - - public String getApiOrganizationId() { - return apiOrganizationId; - } - - public void setApiOrganizationId(String apiOrganizationId) { - this.apiOrganizationId = apiOrganizationId; - } - - public String getApiId() { - return apiId; - } - - public void setApiId(String apiId) { - this.apiId = apiId; - } - - public String getApiVersion() { - return apiVersion; - } - - public void setApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - } - -} \ No newline at end of file diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractManagerCommand.java b/src/main/java/io/apiman/cli/managerapi/AbstractManagerCommand.java similarity index 89% rename from src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractManagerCommand.java rename to src/main/java/io/apiman/cli/managerapi/AbstractManagerCommand.java index f263a21..017221d 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractManagerCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/AbstractManagerCommand.java @@ -1,4 +1,4 @@ -package io.apiman.cli.managerapi.command.api.command; +package io.apiman.cli.managerapi; import io.apiman.cli.command.core.AbstractCommand; import io.apiman.cli.managerapi.service.ManagementApiService; @@ -8,7 +8,7 @@ */ public abstract class AbstractManagerCommand extends AbstractCommand { protected final ManagementApiService managementApiService; - + public AbstractManagerCommand(ManagementApiService managementApiService) { this.managementApiService = managementApiService; } diff --git a/src/main/java/io/apiman/cli/managerapi/ManagerCommon.java b/src/main/java/io/apiman/cli/managerapi/ManagerCommon.java index 2dff23f..d2ca0f5 100644 --- a/src/main/java/io/apiman/cli/managerapi/ManagerCommon.java +++ b/src/main/java/io/apiman/cli/managerapi/ManagerCommon.java @@ -34,6 +34,9 @@ public class ManagerCommon { @Parameter(names = { "--server", "-s" }, description = "Management API server address") private String serverAddress = DEFAULT_SERVER_ADDRESS; + @Parameter(names = { "--serverVersion", "-sv"}, description = "Management API server version") + private ManagementApiVersion serverVersion = ManagementApiVersion.DEFAULT_VERSION; + @Parameter(names = { "--serverUsername", "-su"}, description = "Management API server username") private String serverUsername = DEFAULT_SERVER_USERNAME; @@ -85,4 +88,12 @@ public String getManagementApiPassword() { public void setServerAddress(String serverAddress) { this.serverAddress = serverAddress; } + + public ManagementApiVersion getServerVersion() { + return serverVersion; + } + + public void setServerVersion(ManagementApiVersion serverVersion) { + this.serverVersion = serverVersion; + } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java index 1b3db41..b4839fd 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java @@ -17,6 +17,7 @@ package io.apiman.cli.managerapi.command.api; 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 io.apiman.cli.command.api.model.ServiceConfig; diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java index 519a2e0..43dd386 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java @@ -34,7 +34,7 @@ public interface VersionAgnosticApi { List list(String orgName); - Api fetch(String orgName, String apiName); + Api fetch(String orgName, String apiName); // ?? Api fetchVersion(String orgName, String apiName, String version); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractApiCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractApiCommand.java index 7af63fb..203b1a1 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractApiCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/AbstractApiCommand.java @@ -21,7 +21,6 @@ import io.apiman.cli.managerapi.command.api.ApiMixin; import io.apiman.cli.managerapi.command.api.Version12xServerApi; import io.apiman.cli.managerapi.command.common.command.AbstractManagerModelCommand; -import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import io.apiman.cli.managerapi.service.ManagementApiService; /** @@ -34,10 +33,7 @@ public abstract class AbstractApiCommand extends AbstractManagerModelCommand> commandMap) { commandMap.put("create", ApiCreateCommand.class); commandMap.put("list", ApiListCommand.class); - commandMap.put("dlist", ApiDeepListCommand.class); + //commandMap.put("dlist", ApiDeepListCommand.class); commandMap.put("publish", ApiPublishCommand.class); commandMap.put("policy", ApiPolicyCommand.class); commandMap.put("definition", ApiDefinitionCommand.class); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java index dc5e9f7..cee2c31 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java @@ -84,7 +84,8 @@ public void performFinalAction(JCommander parser) throws CommandException { Lists.newArrayList(new ApiGateway(gateway))); // create - final VersionAgnosticApi apiClient = getManagerConfig().buildServerApiClient(VersionAgnosticApi.class, serverVersion); + final VersionAgnosticApi apiClient = getManagerConfig() + .buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()); ManagementApiUtil.invokeAndCheckResponse(() -> apiClient.create(orgName, api)); // configure diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiDefinitionCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiDefinitionCommand.java index e331374..985b8f6 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiDefinitionCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiDefinitionCommand.java @@ -84,6 +84,7 @@ public void performFinalAction(JCommander parser) throws CommandException { LOGGER.debug("Adding definition to API '{}' with contents: {}", this::getModelName, () -> definition); ManagementApiUtil.invokeAndCheckResponse(() -> - getManagerConfig().buildServerApiClient(VersionAgnosticApi.class, serverVersion).setDefinition(orgName, name, version, definitionType, new TypedString(definition))); + getManagerConfig().buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()) + .setDefinition(orgName, name, version, definitionType, new TypedString(definition))); } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiListCommand.java index 372cb07..3f49fdb 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiListCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiListCommand.java @@ -49,7 +49,9 @@ public ApiListCommand(ManagementApiService managementApiService) { public void performFinalAction(JCommander parser) throws CommandException { LOGGER.debug("Listing {}", this::getModelName); - final List apis = getManagerConfig().buildServerApiClient(VersionAgnosticApi.class, serverVersion).list(orgName); + final List apis = getManagerConfig() + .buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()) + .list(orgName); LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(apis)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java index 8ae1b6f..f985b5b 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java @@ -88,6 +88,8 @@ public void performFinalAction(JCommander parser) throws CommandException { apiPolicy.setDefinitionId(policyName); ManagementApiUtil.invokeAndCheckResponse(() -> - getManagerConfig().buildServerApiClient(VersionAgnosticApi.class, serverVersion).addPolicy(orgName, name, version, apiPolicy)); + getManagerConfig() + .buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()) + .addPolicy(orgName, name, version, apiPolicy)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java index 209d306..5fc16a3 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java @@ -18,6 +18,7 @@ import com.beust.jcommander.Parameters; import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.AbstractManagerCommand; import io.apiman.cli.managerapi.service.ManagementApiService; import javax.inject.Inject; diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPublishCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPublishCommand.java index a15958b..ae29d9b 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPublishCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPublishCommand.java @@ -52,7 +52,11 @@ public ApiPublishCommand(ManagementApiService managementApiService) { @Override public void performFinalAction(JCommander parser) throws CommandException { LOGGER.debug("Publishing {}", this::getModelName); - ServerActionUtil.publishApi(orgName, name, version, serverVersion, getManagerConfig().buildServerApiClient(ActionApi.class)); + ServerActionUtil.publishApi(orgName, + name, + version, + getManagerConfig().getServerVersion(), + getManagerConfig().buildServerApiClient(ActionApi.class)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java index 6cb1a6d..07afc59 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -37,7 +37,9 @@ * * @author Pete Cornish {@literal } */ -public class Version11XManagementApiFactoryImpl extends AbstractManagementApiFactory implements ManagementApiFactory { +public class Version11XManagementApiFactoryImpl + extends AbstractManagementApiFactory + implements ManagementApiFactory { @Override public VersionAgnosticApi build(String endpoint, String username, String password, boolean debugLogging) { final Version11xServerApi delegate = buildClient(Version11xServerApi.class, endpoint, username, password, debugLogging); @@ -72,6 +74,7 @@ public Api fetchVersion(String orgName, String apiName, String version) { public List fetchVersions(String orgName, String apiName) { return delegate.fetchVersions(orgName, apiName); } + @Override public ApiConfig fetchVersionConfig(String orgName, String apiName, String version) { return delegate.fetchVersionConfig(orgName, apiName, version); diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java new file mode 100644 index 0000000..d60fb4b --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java @@ -0,0 +1,51 @@ +/* + * 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.managerapi.command.client; + + +import io.apiman.cli.command.client.model.ApiKey; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; +import retrofit.http.Path; + +import java.util.List; + +/** + * @author Jean-Charles Quantin {@literal } + */ +public interface ClientApi { + + List list(String orgName); // Hack to display only name, seemingly. + + List listVersions(@Path("orgName") String orgName, @Path("clientName") String clientName); // Hack to display only version, seemingly. + + Response create(String orgName, Client client); + + Client fetch(String orgName, String clientName); + + Client createVersion(String orgName, String clientName, NewClientVersionBean client); + + ClientVersionBean fetchVersion(String orgName, String clientName, String version); + + ApiKey getApiKey(String orgName, String clientName, String version); + + Response createContract(String orgName, String clientName, String version, Contract contract); + + List listContracts(String orgName, String clientName, String version); +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java new file mode 100644 index 0000000..a055560 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java @@ -0,0 +1,52 @@ +package io.apiman.cli.managerapi.command.client; + +import io.apiman.cli.command.client.model.ApiKey; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; +import retrofit.http.Body; +import retrofit.http.GET; +import retrofit.http.POST; +import retrofit.http.Path; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public interface ClientApiVersion1x { + + @GET("/organizations/{orgName}/applications") + List list(@Path("orgName") String orgName); + + @GET("/organizations/{orgName}/applications/{clientName}/versions") + List listVersions(@Path("orgName") String orgName, @Path("clientName") String clientName); + + @POST("/organizations/{orgName}/applications") + Response create(@Path("orgName") String orgName, @Body Client client); + + @GET("/organizations/{orgName}/applications/{clientName}") + Client fetch(@Path("orgName") String orgName, @Path("clientName") String clientName); + + @POST("/organizations/{orgName}/applications/{clientName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Body NewClientVersionBean client); + + @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}") + ClientVersionBean fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}/apikey") + ApiKey getApiKey(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @POST("/organizations/{orgName}/applications/{clientName}/versions/{version}/contracts") + Response createContract(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Body Contract contract); + + @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}/contracts") + List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java new file mode 100644 index 0000000..e4734d1 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java @@ -0,0 +1,52 @@ +package io.apiman.cli.managerapi.command.client; + +import io.apiman.cli.command.client.model.ApiKey; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; +import retrofit.http.Body; +import retrofit.http.GET; +import retrofit.http.POST; +import retrofit.http.Path; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public interface ClientApiVersion2x { + + @GET("/organizations/{orgName}/clients") + List list(@Path("orgName") String orgName); + + @GET("/organizations/{orgName}/clients/{clientName}/versions") + List listVersions(@Path("orgName") String orgName, @Path("clientName") String clientName); + + @POST("/organizations/{orgName}/clients") + Response create(@Path("orgName") String orgName, @Body Client client); + + @GET("/organizations/{orgName}/clients/{clientName}") + Client fetch(@Path("orgName") String orgName, @Path("clientName") String clientName); + + @POST("/organizations/{orgName}/clients/{clientName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Body NewClientVersionBean client); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}") + ClientVersionBean fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/apikey") + ApiKey getApiKey(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @POST("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") + Response createContract(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Body Contract contract); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") + List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java new file mode 100644 index 0000000..6075d4e --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java @@ -0,0 +1,74 @@ +package io.apiman.cli.managerapi.command.client; + +import io.apiman.cli.command.client.model.ApiKey; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.cli.managerapi.management.factory.AbstractManagementApiFactory; +import io.apiman.cli.managerapi.management.factory.ManagementApiFactory; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public class Version2xClientFactoryImpl + extends AbstractManagementApiFactory + implements ManagementApiFactory { + + @Override + public ClientApi build(String endpoint, String username, String password, boolean debugLogging) { + final ClientApiVersion2x delegate = buildClient(ClientApiVersion2x.class, endpoint, username, password, debugLogging); + + return new ClientApi() { + + @Override + public List list(String orgName) { + return delegate.list(orgName); + } + + @Override + public List listVersions(String orgName, String clientName) { + return delegate.listVersions(orgName, clientName); + } + + @Override + public Response create(String orgName, Client client) { + return delegate.create(orgName, client); + } + + @Override + public Client fetch(String orgName, String clientName) { + return delegate.fetch(orgName, clientName); + } + + @Override + public Client createVersion(String orgName, String clientName, NewClientVersionBean client) { + return delegate.createVersion(orgName, clientName, client); + } + + @Override + public ClientVersionBean fetchVersion(String orgName, String clientName, String version) { + return delegate.fetchVersion(orgName, clientName, version); + } + + @Override + public ApiKey getApiKey(String orgName, String clientName, String version) { + return delegate.getApiKey(orgName, clientName, version); + } + + @Override + public Response createContract(String orgName, String clientName, String version, Contract contract) { + return delegate.createContract(orgName, clientName, version, contract); + } + + @Override + public List listContracts(String orgName, String clientName, String version) { + return delegate.listContracts(orgName, clientName, version); + } + }; + + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractClientCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractClientCommand.java new file mode 100644 index 0000000..9441a16 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractClientCommand.java @@ -0,0 +1,47 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.Parameter; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.command.common.command.AbstractManagerModelCommand; +import io.apiman.cli.managerapi.command.common.command.ModelAction; +import io.apiman.cli.managerapi.service.ManagementApiService; + +/** + * Common API functionality. + * + * @author Pete Cornish {@literal } + */ +public abstract class AbstractClientCommand extends AbstractManagerModelCommand + implements ModelAction { + @Parameter(names = { "--orgName", "-o"}, description = "Organisation name", required = true) + protected String orgName; + + AbstractClientCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + public Class getModelClass() { + return Client.class; + } + + public Class getApiClass() { + return ClientApi.class; + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractManagerCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractManagerCommand.java new file mode 100644 index 0000000..6142d24 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/AbstractManagerCommand.java @@ -0,0 +1,15 @@ +package io.apiman.cli.managerapi.command.client.command; + +import io.apiman.cli.command.core.AbstractCommand; +import io.apiman.cli.managerapi.service.ManagementApiService; + +/** + * @author Marc Savy {@literal } + */ +public abstract class AbstractManagerCommand extends AbstractCommand { + protected final ManagementApiService managementApiService; + + public AbstractManagerCommand(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java new file mode 100644 index 0000000..6e2644e --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java @@ -0,0 +1,47 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * Root Command for managing APIs. + * + * @author Pete Cornish {@literal } + */ +@Parameters(commandDescription = "Manage Clients") +public class ClientCommand extends AbstractManagerCommand { + + @Inject + public ClientCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("create", ClientCreateCommand.class); + commandMap.put("list", ClientListCommand.class); + commandMap.put("register", ClientRegisterCommand.class); + commandMap.put("policy", ClientPolicyCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java new file mode 100644 index 0000000..a78ff2c --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java @@ -0,0 +1,71 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.ManagerCommon; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * Create an API. + * + * @author Pete Cornish {@literal } + */ +@Parameters(commandDescription = "Create a Client") +public class ClientCreateCommand extends AbstractClientCommand { + private static final Logger LOGGER = LogManager.getLogger(ClientCreateCommand.class); + + @Parameter(names = {"--name", "-n"}, description = "Client name", required = true) + private String name; + + @Parameter(names = {"--description", "-d"}, description = "Description") + private String description; + + @Parameter(names = {"--initialVersion", "-v"}, description = "Initial version", required = true) + private String initialVersion; + + private final ManagerCommon manager; + + @Inject + public ClientCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + manager = getManagerConfig(); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Creating {}", this::getModelName); + + final Client client = new Client( + name, + description, + initialVersion); + + ClientApi clientApi = manager.buildServerApiClient(ClientApi.class, manager.getServerVersion()); + ManagementApiUtil.invokeAndCheckResponse(() -> clientApi.create(orgName, client)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientListCommand.java new file mode 100644 index 0000000..23dc06b --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientListCommand.java @@ -0,0 +1,83 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.gatewayapi.GatewayHelper; +import io.apiman.cli.managerapi.ManagerCommon; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.service.ManagementApiService; +import io.apiman.cli.util.LogUtil; +import io.apiman.cli.util.MappingUtil; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.util.List; +import java.util.function.Supplier; + +/** + * List clients + */ +@Parameters(commandDescription = "List Clients") +public class ClientListCommand extends AbstractClientCommand implements GatewayHelper { + private static final Logger LOGGER = LogManager.getLogger(ClientListCommand.class); + + @Parameter(names = { "--clientName", "-c"}, description = "Client name") + private String clientName; + + @Parameter(names = { "--version", "-v"} , description = "Client Version") + private String version; + + private final ManagerCommon config; + + @Inject + public ClientListCommand(ManagementApiService managementApiService) { + super(managementApiService); + config = getManagerConfig(); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Listing {}", this::getModelName); + + ClientApi clientApi = config.buildServerApiClient(ClientApi.class, config.getServerVersion()); + + // If Client ID not provided, list all Client in org + if (clientName == null) { + print("Clients", () -> clientApi.list(orgName)); + } else if (version == null) { // If version not provided, list all versions of Client + print("Client Versions", () -> clientApi.listVersions(orgName, clientName)); + } else { // Otherwise retrieve the Client explicitly. + ClientVersionBean client = callAndCatch(() -> clientApi.fetchVersion(orgName, clientName, version)); + if (client == null) { + LOGGER.debug("No Client returned for provided parameters"); + } else { + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(client)); + } + } + } + + private void print(String entityName, Supplier> action) { + LOGGER.debug(entityName); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(action.get())); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyAddCommand.java new file mode 100644 index 0000000..70b7be4 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyAddCommand.java @@ -0,0 +1,96 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.common.io.CharStreams; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.exception.ExitWithCodeException; +import io.apiman.cli.gatewayapi.GatewayHelper; +import io.apiman.cli.managerapi.ManagerCommon; +import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Add a policy to a Client. + * + * @author Pete Cornish {@literal } + */ +@Parameters(commandDescription = "Add policy to Client") +public class ClientPolicyAddCommand extends AbstractClientCommand implements GatewayHelper { + private static final Logger LOGGER = LogManager.getLogger(ClientPolicyAddCommand.class); + private final ManagerCommon manager; + + @Parameter(names = { "--name", "-n" }, description = "Client name", required = true) + private String name; + + @Parameter(names = { "--version", "-v" }, description = "Client version", required = true) + private String version; + + @Parameter(names = { "--policyName", "-p" }, description = "Policy name", required = true) + private String policyName; + + @Parameter(names = { "--configStdIn", "-i" }, description = "Read policy configuration from STDIN") // TODO forbids -f + private boolean configStdIn; + + @Parameter(names = { "--configFile", "-f" }, description = "Policy configuration file") // TODO forbids i + private Path configFile; + + @Inject + public ClientPolicyAddCommand(ManagementApiService managementApiService) { + super(managementApiService); + manager = getManagerConfig(); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + if (!configStdIn && null == configFile) { + throw new ExitWithCodeException(1, "Policy configuration must be provided", true); + } + + // read configuration from STDIN or file + String policyConfig; + try (InputStream is = (configStdIn ? System.in : Files.newInputStream(configFile))) { + policyConfig = CharStreams.toString(new InputStreamReader(is)); + + } catch (IOException e) { + throw new CommandException(e); + } + + LOGGER.debug("Adding policy '{}' to Client '{}' with configuration: {}", + () -> policyName, this::getModelName, () -> policyConfig); + + final ApiPolicy apiPolicy = new ApiPolicy(policyName); + apiPolicy.setDefinitionId(policyName); + + ManagementApiUtil.invokeAndCheckResponse(() -> + manager.buildServerApiClient(VersionAgnosticApi.class, manager.getServerVersion()).addPolicy(orgName, name, version, apiPolicy)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyCommand.java new file mode 100644 index 0000000..9fade37 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientPolicyCommand.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.managerapi.command.client.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * Root Command for managing API policies. + * + * @author Pete Cornish {@literal } + */ + +@Parameters(commandDescription = "Manage Client policies") +public class ClientPolicyCommand extends AbstractManagerCommand { + @Inject + public ClientPolicyCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("add", ClientPolicyAddCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientRegisterCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientRegisterCommand.java new file mode 100644 index 0000000..b806503 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientRegisterCommand.java @@ -0,0 +1,66 @@ +/* + * 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.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.gatewayapi.GatewayHelper; +import io.apiman.cli.managerapi.ManagerCommon; +import io.apiman.cli.managerapi.command.common.ActionApi; +import io.apiman.cli.managerapi.command.common.util.ServerActionUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * Publish an API. + * + * @author Pete Cornish {@literal } + */ +@Parameters(commandDescription = "Publish Client") +public class ClientRegisterCommand extends AbstractClientCommand implements GatewayHelper { + private static final Logger LOGGER = LogManager.getLogger(ClientRegisterCommand.class); + + @Parameter(names = { "--name", "-n"}, description = "Client name", required = true) + private String name; + + @Parameter(names = { "--version", "-v"}, description = "Client version", required = true) + private String version; + + private final ManagerCommon manager; + + @Inject + public ClientRegisterCommand(ManagementApiService managementApiService) { + super(managementApiService); + manager = getManagerConfig(); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Registering {}", this::getModelName); + ServerActionUtil.registerClient(orgName, + name, + version, + manager.getServerVersion(), + manager.buildServerApiClient(ActionApi.class)); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java b/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java index b15f5d5..8b35bfc 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java +++ b/src/main/java/io/apiman/cli/managerapi/command/common/util/ServerActionUtil.java @@ -96,9 +96,20 @@ public static void lockPlan(String orgName, String planName, String planVersion, * @param clientVersion the client version * @param actionClient the Server Action API client */ - public static void registerClient(String orgName, String clientName, String clientVersion, ActionApi actionClient) { - String actionType = "registerClient"; + public static void registerClient(String orgName, String clientName, String clientVersion, + ManagementApiVersion serverVersion, ActionApi actionClient) { + String actionType; + switch (serverVersion) { + case v11x: + // legacy apiman 1.1.x support + actionType = "registerApplication"; + break; + default: + // apiman 1.2.x support + actionType = "registerClient"; + break; + } ManagementApiUtil.invokeAndCheckResponse(HttpURLConnection.HTTP_NO_CONTENT, () -> { final ServerAction action = new ServerAction( actionType, diff --git a/src/main/java/io/apiman/cli/managerapi/command/gateway/command/GatewayCommand.java b/src/main/java/io/apiman/cli/managerapi/command/gateway/command/GatewayCommand.java index 1749bc3..e0860c6 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/gateway/command/GatewayCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/gateway/command/GatewayCommand.java @@ -18,7 +18,7 @@ import com.beust.jcommander.Parameters; import io.apiman.cli.command.core.Command; -import io.apiman.cli.managerapi.command.api.command.AbstractManagerCommand; +import io.apiman.cli.managerapi.AbstractManagerCommand; import io.apiman.cli.managerapi.service.ManagementApiService; import javax.inject.Inject; diff --git a/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java b/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java index 1d316a7..bfb4821 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/org/OrgApi.java @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package io.apiman.cli.managerapi.command.org; import io.apiman.cli.command.org.model.Org; +import io.apiman.cli.command.org.model.OrgSearchIn; +import io.apiman.cli.command.org.model.OrgSearchOut; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.GET; @@ -27,6 +28,7 @@ * @author Pete Cornish {@literal } */ public interface OrgApi { + @POST("/organizations") Response create(@Body Org organisation); diff --git a/src/main/java/io/apiman/cli/managerapi/command/org/command/OrgCommand.java b/src/main/java/io/apiman/cli/managerapi/command/org/command/OrgCommand.java index 04b7915..a29c716 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/org/command/OrgCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/org/command/OrgCommand.java @@ -18,7 +18,7 @@ import com.beust.jcommander.Parameters; import io.apiman.cli.command.core.Command; -import io.apiman.cli.managerapi.command.api.command.AbstractManagerCommand; +import io.apiman.cli.managerapi.AbstractManagerCommand; import io.apiman.cli.managerapi.service.ManagementApiService; import javax.inject.Inject; diff --git a/src/main/java/io/apiman/cli/core/plan/PlanApi.java b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java similarity index 92% rename from src/main/java/io/apiman/cli/core/plan/PlanApi.java rename to src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java index 9a11ce8..d61fbae 100644 --- a/src/main/java/io/apiman/cli/core/plan/PlanApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java @@ -14,24 +14,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.apiman.cli.core.plan; +package io.apiman.cli.managerapi.command.plan; -import java.util.List; - -import io.apiman.cli.core.api.model.ApiPolicy; -import io.apiman.cli.core.plan.model.Plan; -import io.apiman.cli.core.plan.model.PlanVersion; +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.Body; import retrofit.http.GET; import retrofit.http.POST; import retrofit.http.Path; +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); @@ -61,4 +62,4 @@ List fetchPolicies(@Path("orgName") String orgName, @Path("planName") @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies/{policyId}") ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version, @Path("policyId") Long policyId); -} \ No newline at end of file +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java new file mode 100644 index 0000000..53e317e --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java @@ -0,0 +1,37 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.Parameter; +import io.apiman.cli.command.api.model.Api; +import io.apiman.cli.managerapi.command.api.ApiMixin; +import io.apiman.cli.managerapi.command.api.Version12xServerApi; +import io.apiman.cli.managerapi.command.common.command.AbstractManagerModelCommand; +import io.apiman.cli.managerapi.service.ManagementApiService; + +/** + * @author Marc Savy {@literal } + */ +public abstract class AbstractPlanCommand extends AbstractManagerModelCommand + implements ApiMixin { + @Parameter(names = { "--orgName", "-o"}, description = "Organisation name", required = true) + protected String orgName; + + public AbstractPlanCommand(ManagementApiService managementApiService) { + super(managementApiService); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCommand.java new file mode 100644 index 0000000..3e71f78 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCommand.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.AbstractManagerCommand; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Manage Plans") +public class PlanCommand extends AbstractManagerCommand { + + @Inject + public PlanCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("create", PlanCreateCommand.class); + commandMap.put("list", PlanListCommand.class); + commandMap.put("lock", PlanLockCommand.class); + commandMap.put("policy", PlanPolicyCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java new file mode 100644 index 0000000..1461b47 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java @@ -0,0 +1,67 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.plan.PlanApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Create a Plan") +public class PlanCreateCommand extends AbstractPlanCommand { + private static final Logger LOGGER = LogManager.getLogger(PlanCreateCommand.class); + + @Parameter(names = {"--name", "-n"}, description = "Plan name", required = true) + private String name; + + @Parameter(names = {"--description", "-d"}, description = "Description") + private String description; + + @Parameter(names = {"--initialVersion", "-v"}, description = "Initial version", required = true) + private String initialVersion; + + @Inject + public PlanCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Creating {}", this::getModelName); + + final Plan plan = new Plan( + name, + description, + initialVersion); + + // create + final PlanApi planClient = getManagerConfig() + .buildServerApiClient(PlanApi.class, getManagerConfig().getServerVersion()); + ManagementApiUtil.invokeAndCheckResponse(() -> planClient.create(orgName, plan)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java new file mode 100644 index 0000000..81004b0 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java @@ -0,0 +1,54 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.plan.PlanApi; +import io.apiman.cli.managerapi.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 javax.inject.Inject; +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "List Plans") +public class PlanListCommand extends AbstractPlanCommand { + private static final Logger LOGGER = LogManager.getLogger(PlanListCommand.class); + + @Inject + public PlanListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Listing {}", this::getModelName); + + final List plans = getManagerConfig() + .buildServerApiClient(PlanApi.class, getManagerConfig().getServerVersion()) + .list(orgName); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(plans)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanLockCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanLockCommand.java new file mode 100644 index 0000000..18cfe2c --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanLockCommand.java @@ -0,0 +1,60 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.common.ActionApi; +import io.apiman.cli.managerapi.command.common.util.ServerActionUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * Lock plan + * + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Lock Plan") +public class PlanLockCommand extends AbstractPlanCommand { + private static final Logger LOGGER = LogManager.getLogger(PlanLockCommand.class); + + @Parameter(names = { "--name", "-n"}, description = "Plan name", required = true) + private String name; + + @Parameter(names = { "--version", "-v"}, description = "Plan version", required = true) + private String version; + + @Inject + public PlanLockCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Locking {}", this::getModelName); + ServerActionUtil.lockPlan(orgName, + name, + version, + getManagerConfig().buildServerApiClient(ActionApi.class)); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyAddCommand.java new file mode 100644 index 0000000..737b891 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyAddCommand.java @@ -0,0 +1,92 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.common.io.CharStreams; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.exception.ExitWithCodeException; +import io.apiman.cli.managerapi.command.plan.PlanApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Add policy to API") +public class PlanPolicyAddCommand extends AbstractPlanCommand { + private static final Logger LOGGER = LogManager.getLogger(PlanPolicyAddCommand.class); + + @Parameter(names = { "--name", "-n" }, description = "Plan name", required = true) + private String name; + + @Parameter(names = { "--version", "-v" }, description = "Plan version", required = true) + private String version; + + @Parameter(names = { "--policyName", "-p" }, description = "Policy name", required = true) + private String policyName; + + @Parameter(names = { "--configStdIn", "-i" }, description = "Read policy configuration from STDIN") // TODO forbids -f + private boolean configStdIn; + + @Parameter(names = { "--configFile", "-f" }, description = "Policy configuration file") // TODO forbids i + private Path configFile; + + @Inject + public PlanPolicyAddCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + if (!configStdIn && null == configFile) { + throw new ExitWithCodeException(1, "Policy configuration must be provided", true); + } + + // read configuration from STDIN or file + String policyConfig; + try (InputStream is = (configStdIn ? System.in : Files.newInputStream(configFile))) { + policyConfig = CharStreams.toString(new InputStreamReader(is)); + + } catch (IOException e) { + throw new CommandException(e); + } + + LOGGER.debug("Adding policy '{}' to Plan '{}' with configuration: {}", + () -> policyName, this::getModelName, () -> policyConfig); + + final ApiPolicy apiPolicy = new ApiPolicy(policyName); + apiPolicy.setDefinitionId(policyName); + + ManagementApiUtil.invokeAndCheckResponse(() -> + getManagerConfig() + .buildServerApiClient(PlanApi.class, getManagerConfig().getServerVersion()) + .addPolicy(orgName, name, version, apiPolicy)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyCommand.java new file mode 100644 index 0000000..6b4b3f9 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanPolicyCommand.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 JBoss Inc + * + * 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.managerapi.command.plan.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.AbstractManagerCommand; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * @author Marc Savy {@literal } + */ + +@Parameters(commandDescription = "Manage Plan policies") +public class PlanPolicyCommand extends AbstractManagerCommand { + @Inject + public PlanPolicyCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("add", PlanPolicyAddCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/plugin/command/PluginCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plugin/command/PluginCommand.java index 8a4de80..45b4986 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plugin/command/PluginCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plugin/command/PluginCommand.java @@ -18,7 +18,7 @@ import com.beust.jcommander.Parameters; import io.apiman.cli.command.core.Command; -import io.apiman.cli.managerapi.command.api.command.AbstractManagerCommand; +import io.apiman.cli.managerapi.AbstractManagerCommand; import io.apiman.cli.managerapi.service.ManagementApiService; import javax.inject.Inject; diff --git a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java index ac9b6e6..c4b1f98 100644 --- a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java @@ -16,7 +16,6 @@ package io.apiman.cli.managerapi.declarative.command; -import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; import com.beust.jcommander.ParametersDelegate; import io.apiman.cli.command.declarative.command.AbstractApplyCommand; @@ -37,9 +36,6 @@ public class ManagerApplyCommand extends AbstractApplyCommand { private static final Logger LOGGER = LogManager.getLogger(ManagerApplyCommand.class); - @Parameter(names = {"--serverVersion", "-sv"}, description = "Management API server version") - private ManagementApiVersion serverVersion = ManagementApiVersion.DEFAULT_VERSION; - @ParametersDelegate private final ManagerCommon managerCommon; private final DeclarativeService declarativeService; @@ -75,7 +71,7 @@ protected void applyDeclaration(BaseDeclaration declaration) { declarativeService.applyOrg(org); ofNullable(org.getApis()).ifPresent(apis -> - declarativeService.applyApis(serverVersion, apis, org.getName())); + declarativeService.applyApis(managerCommon.getServerVersion(), apis, org.getName())); }); LOGGER.info("Applied declaration"); @@ -86,6 +82,6 @@ public void setServerAddress(String serverAddress) { } public void setServerVersion(ManagementApiVersion serverVersion) { - this.serverVersion = serverVersion; + this.managerCommon.setServerVersion(serverVersion); } } diff --git a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java index 6f22567..24a4e3c 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java +++ b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java @@ -21,10 +21,13 @@ import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; import io.apiman.cli.managerapi.command.api.factory.Version11XManagementApiFactoryImpl; import io.apiman.cli.managerapi.command.api.factory.Version12XManagementApiFactoryImpl; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.command.client.Version2xClientFactoryImpl; import io.apiman.cli.managerapi.command.common.ActionApi; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import io.apiman.cli.managerapi.command.gateway.GatewayApi; import io.apiman.cli.managerapi.command.org.OrgApi; +import io.apiman.cli.managerapi.command.plan.PlanApi; import io.apiman.cli.managerapi.command.plugin.PluginApi; import io.apiman.cli.managerapi.management.api.StatusApi; import io.apiman.cli.managerapi.management.binding.ManagementApiBindings; @@ -67,12 +70,13 @@ protected void configure() { .annotatedWith(ManagementApiBindings.boundTo(VersionAgnosticApi.class, ManagementApiVersion.v12x)) .to(Version12XManagementApiFactoryImpl.class).in(Singleton.class); + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(ClientApi.class, ManagementApiVersion.v12x)) + .to(Version2xClientFactoryImpl.class).in(Singleton.class); + bind(ManagementApiFactory.class) .annotatedWith(ManagementApiBindings.boundTo(PlanApi.class)) .toInstance(new SimpleManagementApiFactoryImpl<>(PlanApi.class)); - - bind(ManagementApiFactory.class) - .annotatedWith(ManagementApiBindings.boundTo(ClientApi.class)) - .toInstance(new SimpleManagementApiFactoryImpl<>(ClientApi.class)); } + } diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java b/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java index 6908a1c..e6d3a76 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/AbstractManagementApiFactory.java @@ -18,17 +18,11 @@ import io.apiman.cli.util.AuthUtil; import retrofit.RestAdapter; -import retrofit.converter.ConversionException; -import retrofit.converter.Converter; import retrofit.converter.JacksonConverter; -import retrofit.mime.TypedInput; -import retrofit.mime.TypedOutput; import static io.apiman.cli.util.AuthUtil.HEADER_AUTHORIZATION; import static io.apiman.cli.util.MappingUtil.JSON_MAPPER; -import java.lang.reflect.Type; - /** * Builds a Management API client proxy for a given API interface. * @@ -44,31 +38,9 @@ public abstract class AbstractManagementApiFactory implements ManagementAp * @param debugLogging whether debug logging should be enabled * @return an API client for the given Class */ - protected A buildClient(Class apiClass, String endpoint, String username, String password, boolean debugLogging, PostConverter postConverter) { - final JacksonConverter jacksonConverter = new JacksonConverter(JSON_MAPPER); - final Converter converter; - if (postConverter == null) { - converter = jacksonConverter; - } else { - converter = new Converter() { - - @Override - public Object fromBody(TypedInput body, Type type) throws ConversionException { - final Object o = jacksonConverter.fromBody(body, type); - postConverter.postConvert(o); - return o; - } - - @Override - public TypedOutput toBody(Object object) { - return jacksonConverter.toBody(object); - } - - }; - } - - final RestAdapter.Builder builder = new RestAdapter.Builder() // - .setConverter(converter) + protected A buildClient(Class apiClass, String endpoint, String username, String password, boolean debugLogging) { + final RestAdapter.Builder builder = new RestAdapter.Builder() + .setConverter(new JacksonConverter(JSON_MAPPER)) .setEndpoint(endpoint) .setRequestInterceptor(request -> { request.addHeader(HEADER_AUTHORIZATION, AuthUtil.buildAuthString(username, password)); diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java index 0dbf283..e226c97 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java @@ -16,6 +16,8 @@ package io.apiman.cli.managerapi.management.factory; +import io.apiman.cli.management.factory.PostConverter; + /** * Builds a Management API client proxy for a given API interface. * @@ -30,5 +32,5 @@ public interface ManagementApiFactory { * @param postConverter the PostConverter if needs * @return an API client for the given Class */ - T build(String endpoint, String username, String password, boolean debugLogging, PostConverter postConverter); + T build(String endpoint, String username, String password, boolean debugLogging); } diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java index 4db82f4..7954f5b 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/SimpleManagementApiFactoryImpl.java @@ -30,8 +30,7 @@ public SimpleManagementApiFactoryImpl(Class apiClass) { @Override - public T build(String endpoint, String username, String password, boolean debugLogging, - PostConverter postConverter) { - return buildClient(apiClass, endpoint, username, password, debugLogging, postConverter); + public T build(String endpoint, String username, String password, boolean debugLogging) { + return buildClient(apiClass, endpoint, username, password, debugLogging); } } diff --git a/src/main/java/io/apiman/cli/util/LogUtil.java b/src/main/java/io/apiman/cli/util/LogUtil.java index da23a3c..d5da40c 100644 --- a/src/main/java/io/apiman/cli/util/LogUtil.java +++ b/src/main/java/io/apiman/cli/util/LogUtil.java @@ -70,7 +70,8 @@ public static void configureLogging(boolean logDebug) { appender = context.getConfiguration().getAppender("ConsoleTerse"); } - rootLogger.addAppender(appender, null, null); + if (appender != null) + rootLogger.addAppender(appender, null, null); context.updateLoggers(); } diff --git a/src/main/java/io/apiman/cli/util/MappingUtil.java b/src/main/java/io/apiman/cli/util/MappingUtil.java index 8d87df1..f062375 100644 --- a/src/main/java/io/apiman/cli/util/MappingUtil.java +++ b/src/main/java/io/apiman/cli/util/MappingUtil.java @@ -37,7 +37,9 @@ import java.io.IOException; import java.net.URL; +import java.util.ArrayList; import java.util.Collection; +import java.util.StringTokenizer; /** * Shared POJO/JSON/YAML mapping utility methods. diff --git a/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java b/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java index 1f6ed44..a9c3b60 100644 --- a/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java +++ b/src/test/java/io/apiman/cli/command/GatewayDeclarativeTest.java @@ -53,7 +53,7 @@ public void setUp() { command.setLogDebug(LOG_DEBUG); LogUtil.configureLogging(LOG_DEBUG); // Stub Gateway API Factory - when(mGatewayApiFactory.build("http://localhost:8080/apiman-gateway-api", "apimanager", "apiman123!", true, null)) + when(mGatewayApiFactory.build("http://localhost:8080/apiman-gateway-api", "apimanager", "apiman123!", true)) .thenReturn(mGatewayApi); // Bake in OK status SystemStatus okStatus = new SystemStatus(); From af24fc8d9784e9ccdee8b54a95200bff9799d625 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sat, 7 Apr 2018 14:28:07 +0100 Subject: [PATCH 03/15] Add support for declarative Clients and Plans --- .../{ApiVersion.java => EntityVersion.java} | 4 +- .../declarative/model/DeclarativeClient.java | 56 +++++ .../declarative/model/DeclarativeOrg.java | 7 +- .../declarative/model/DeclarativePlan.java | 6 + .../cli/managerapi/command/api/PolicyApi.java | 24 ++ .../command/api/Version11xServerApi.java | 7 +- .../command/api/Version12xServerApi.java | 4 +- .../command/api/VersionAgnosticApi.java | 19 +- .../command/api/command/ApiCommand.java | 1 - .../Version11XManagementApiFactoryImpl.java | 4 +- .../Version12XManagementApiFactoryImpl.java | 4 +- .../managerapi/command/client/ClientApi.java | 10 +- .../command/client/ClientApiVersion1x.java | 51 ++-- .../command/client/ClientApiVersion2x.java | 24 ++ .../client/Version1xClientFactoryImpl.java | 100 ++++++++ .../client/Version2xClientFactoryImpl.java | 26 ++ .../cli/managerapi/command/plan/PlanApi.java | 5 +- .../command/ManagerApplyCommand.java | 6 + .../ManagementApiFactoryModule.java | 5 + .../cli/managerapi/service/ClientService.java | 51 ++++ .../managerapi/service/ClientServiceImpl.java | 99 ++++++++ .../service/DeclarativeService.java | 22 ++ .../service/DeclarativeServiceImpl.java | 223 +++++++++++++++--- .../cli/managerapi/service/PolicyService.java | 5 +- .../managerapi/service/PolicyServiceImpl.java | 25 +- .../cli/managerapi/service/ServiceModule.java | 1 + 26 files changed, 708 insertions(+), 81 deletions(-) rename src/main/java/io/apiman/cli/command/api/model/{ApiVersion.java => EntityVersion.java} (94%) create mode 100644 src/main/java/io/apiman/cli/command/declarative/model/DeclarativeClient.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/api/PolicyApi.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/Version1xClientFactoryImpl.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/ClientService.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java diff --git a/src/main/java/io/apiman/cli/command/api/model/ApiVersion.java b/src/main/java/io/apiman/cli/command/api/model/EntityVersion.java similarity index 94% rename from src/main/java/io/apiman/cli/command/api/model/ApiVersion.java rename to src/main/java/io/apiman/cli/command/api/model/EntityVersion.java index 71f8401..b690431 100644 --- a/src/main/java/io/apiman/cli/command/api/model/ApiVersion.java +++ b/src/main/java/io/apiman/cli/command/api/model/EntityVersion.java @@ -27,7 +27,7 @@ */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public class ApiVersion { +public class EntityVersion { @JsonProperty private String version; @@ -37,7 +37,7 @@ public class ApiVersion { @JsonProperty final private boolean clone = false; - public ApiVersion(String version) { + public EntityVersion(String version) { this.version = version; } } diff --git a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeClient.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeClient.java new file mode 100644 index 0000000..356aedd --- /dev/null +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeClient.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.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.client.model.Client; + +import java.util.List; + +/** + * Declarative API representation. + * + * @author Pete Cornish {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeclarativeClient extends Client { + @JsonProperty + private boolean registered; + + @JsonProperty + private List policies; + + public boolean isRegistered() { + return registered; + } + + public void setPublished(boolean registered) { + this.registered = registered; + } + + public List getPolicies() { + return policies; + } + + public void setPolicies(List policies) { + this.policies = policies; + } + +} 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 9f7d817..56c329e 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 @@ -19,7 +19,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.org.model.Org; import java.util.List; @@ -48,7 +47,7 @@ public DeclarativeOrg(String name, String description) { private List plans; @JsonProperty - private List clients; + private List clients; public List getApis() { return apis; @@ -66,11 +65,11 @@ public void setPlans(List plans) { this.plans = plans; } - public List getClients() { + public List getClients() { return clients; } - public void setClients(List clients) { + public void setClients(List clients) { this.clients = clients; } } 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 index 8af73ee..a2cff7f 100644 --- a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java @@ -32,6 +32,9 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class DeclarativePlan extends Plan { + @JsonProperty + private boolean locked; + @JsonProperty private List policies; @@ -43,4 +46,7 @@ public void setPolicies(List policies) { this.policies = policies; } + public boolean isLocked() { + return locked; + } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/PolicyApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/PolicyApi.java new file mode 100644 index 0000000..2069474 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/api/PolicyApi.java @@ -0,0 +1,24 @@ +package io.apiman.cli.managerapi.command.api; + +import io.apiman.cli.command.api.model.ApiPolicy; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public interface PolicyApi { + + Response addPolicy(String orgName, String entityName, + String version, ApiPolicy policyConfig); + + ApiPolicy fetchPolicy(String orgName, String entityName, + String version, Long policyId); + + Response configurePolicy(String orgName, String entityName, + String apiVersion, Long policyId, ApiPolicy policyConfig); + + List fetchPolicies(String orgName, String entityName, + String version); +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java index b4839fd..b1f3e84 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/Version11xServerApi.java @@ -19,7 +19,7 @@ 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 io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.api.model.ServiceConfig; import retrofit.client.Response; import retrofit.http.Body; @@ -42,7 +42,7 @@ public interface Version11xServerApi { Response create(@Path("orgName") String orgName, @Body Api api); @POST("/organizations/{orgName}/services/{serviceName}/versions") - Response createVersion(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Body ApiVersion apiVersion); + Response createVersion(@Path("orgName") String orgName, @Path("serviceName") String serviceName, @Body EntityVersion apiVersion); @GET("/organizations/{orgName}/services") List list(@Path("orgName") String orgName); @@ -77,9 +77,10 @@ List fetchPolicies(@Path("orgName") String orgName, @Path("serviceNam @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); + @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/managerapi/command/api/Version12xServerApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java index 88b61bd..2aeb27b 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/Version12xServerApi.java @@ -19,7 +19,7 @@ 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 io.apiman.cli.command.api.model.EntityVersion; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.GET; @@ -41,7 +41,7 @@ public interface Version12xServerApi { Response create(@Path("orgName") String orgName, @Body Api api); @POST("/organizations/{orgName}/apis/{apiName}/versions") - Response createVersion(@Path("orgName") String orgName, @Path("apiName") String apiName, @Body ApiVersion apiVersion); + Response createVersion(@Path("orgName") String orgName, @Path("apiName") String apiName, @Body EntityVersion apiVersion); @GET("/organizations/{orgName}/apis") List list(@Path("orgName") String orgName); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java index 43dd386..96b4890 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java @@ -18,7 +18,7 @@ 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 io.apiman.cli.command.api.model.EntityVersion; import retrofit.client.Response; import retrofit.mime.TypedString; @@ -27,10 +27,10 @@ /** * @author Pete Cornish {@literal } */ -public interface VersionAgnosticApi { +public interface VersionAgnosticApi extends PolicyApi { Response create(String orgName, Api api); - Response createVersion(String orgName, String apiName, ApiVersion apiVersion); + Response createVersion(String orgName, String apiName, EntityVersion apiVersion); List list(String orgName); @@ -45,18 +45,25 @@ public interface VersionAgnosticApi { Response configure(String orgName, String apiName, String version, ApiConfig config); - Response addPolicy(String orgName, String apiName, - String version, ApiPolicy policyConfig); Response setDefinition(String orgName, String apiName, + String version, String definitionType, TypedString definition); + + @Override + Response addPolicy(String orgName, String apiName, + String version, ApiPolicy policyConfig); + + @Override List fetchPolicies(String orgName, String serviceName, String version); - + + @Override ApiPolicy fetchPolicy(String orgName, String apiName, String version, Long policyId); + @Override Response configurePolicy(String orgName, String apiName, String apiVersion, Long policyId, ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java index b23af71..2d498d1 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java @@ -41,7 +41,6 @@ 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); commandMap.put("definition", ApiDefinitionCommand.class); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java index 07afc59..fc73acb 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version11XManagementApiFactoryImpl.java @@ -19,7 +19,7 @@ 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 io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.api.model.ServiceConfig; import io.apiman.cli.managerapi.command.api.Version11xServerApi; import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; @@ -51,7 +51,7 @@ public Response create(String orgName, Api api) { } @Override - public Response createVersion(String orgName, String apiName, ApiVersion apiVersion) { + public Response createVersion(String orgName, String apiName, EntityVersion apiVersion) { return delegate.createVersion(orgName, apiName, apiVersion); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java index d69c10e..e83569b 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/factory/Version12XManagementApiFactoryImpl.java @@ -19,7 +19,7 @@ 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 io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.managerapi.command.api.Version12xServerApi; import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; import io.apiman.cli.managerapi.management.factory.AbstractManagementApiFactory; @@ -46,7 +46,7 @@ public Response create(String orgName, Api api) { } @Override - public Response createVersion(String orgName, String apiName, ApiVersion apiVersion) { + public Response createVersion(String orgName, String apiName, EntityVersion apiVersion) { return delegate.createVersion(orgName, apiName, apiVersion); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java index d60fb4b..25136e1 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java @@ -16,11 +16,12 @@ package io.apiman.cli.managerapi.command.client; +import io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.client.model.ApiKey; import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.client.model.Contract; +import io.apiman.cli.managerapi.command.api.PolicyApi; import io.apiman.manager.api.beans.clients.ClientVersionBean; -import io.apiman.manager.api.beans.clients.NewClientVersionBean; import retrofit.client.Response; import retrofit.http.Path; @@ -29,7 +30,7 @@ /** * @author Jean-Charles Quantin {@literal } */ -public interface ClientApi { +public interface ClientApi extends PolicyApi { List list(String orgName); // Hack to display only name, seemingly. @@ -39,7 +40,7 @@ public interface ClientApi { Client fetch(String orgName, String clientName); - Client createVersion(String orgName, String clientName, NewClientVersionBean client); + Client createVersion(String orgName, String clientName, EntityVersion client); ClientVersionBean fetchVersion(String orgName, String clientName, String version); @@ -48,4 +49,7 @@ public interface ClientApi { Response createContract(String orgName, String clientName, String version, Contract contract); List listContracts(String orgName, String clientName, String version); + + + } diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java index a055560..8397776 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java @@ -1,5 +1,7 @@ package io.apiman.cli.managerapi.command.client; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.client.model.ApiKey; import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.client.model.Contract; @@ -9,6 +11,7 @@ import retrofit.http.Body; import retrofit.http.GET; import retrofit.http.POST; +import retrofit.http.PUT; import retrofit.http.Path; import java.util.List; @@ -21,32 +24,52 @@ public interface ClientApiVersion1x { @GET("/organizations/{orgName}/applications") List list(@Path("orgName") String orgName); - @GET("/organizations/{orgName}/applications/{clientName}/versions") - List listVersions(@Path("orgName") String orgName, @Path("clientName") String clientName); + @GET("/organizations/{orgName}/applications/{applicationName}/versions") + List listVersions(@Path("orgName") String orgName, @Path("applicationName") String applicationName); @POST("/organizations/{orgName}/applications") Response create(@Path("orgName") String orgName, @Body Client client); - @GET("/organizations/{orgName}/applications/{clientName}") - Client fetch(@Path("orgName") String orgName, @Path("clientName") String clientName); + @GET("/organizations/{orgName}/applications/{applicationName}") + Client fetch(@Path("orgName") String orgName, @Path("applicationName") String applicationName); - @POST("/organizations/{orgName}/applications/{clientName}/versions") - Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @POST("/organizations/{orgName}/applications/{applicationName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("applicationName") String applicationName, @Body NewClientVersionBean client); - @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}") - ClientVersionBean fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @POST("/organizations/{orgName}/applications/{applicationName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Body EntityVersion service); + + @GET("/organizations/{orgName}/applications/{applicationName}/versions/{version}") + ClientVersionBean fetchVersion(@Path("orgName") String orgName, @Path("applicationName") String applicationName, @Path("version") String version); - @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}/apikey") - ApiKey getApiKey(@Path("orgName") String orgName, @Path("clientName") String clientName, + @GET("/organizations/{orgName}/applications/{applicationName}/versions/{version}/apikey") + ApiKey getApiKey(@Path("orgName") String orgName, @Path("applicationName") String applicationName, @Path("version") String version); - @POST("/organizations/{orgName}/applications/{clientName}/versions/{version}/contracts") - Response createContract(@Path("orgName") String orgName, @Path("clientName") String clientName, + @POST("/organizations/{orgName}/applications/{applicationName}/versions/{version}/contracts") + Response createContract(@Path("orgName") String orgName, @Path("applicationName") String applicationName, @Path("version") String version, @Body Contract contract); - @GET("/organizations/{orgName}/applications/{clientName}/versions/{version}/contracts") - List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, + @GET("/organizations/{orgName}/applications/{applicationName}/versions/{version}/contracts") + List listContracts(@Path("orgName") String orgName, @Path("applicationName") String applicationName, @Path("version") String version); + + @POST("/organizations/{orgName}/applications/{applicationName}/versions/{version}/policies") + Response addPolicy(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Path("version") String version, @Body ApiPolicy policyConfig); + + @GET("/organizations/{orgName}/applications/{applicationName}/versions/{version}/policies") + List fetchPolicies(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Path("version") String version); + + @GET("/organizations/{orgName}/applications/{applicationName}/versions/{version}/policies/{policyId}") + ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Path("version") String version, @Path("policyId") Long policyId); + + @PUT("/organizations/{orgName}/applications/{applicationName}/versions/{version}/policies/{policyId}") + Response configurePolicy(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Path("version") String version, @Path("policyId") Long policyId, @Body ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java index e4734d1..c4d121c 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java @@ -1,5 +1,7 @@ package io.apiman.cli.managerapi.command.client; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.client.model.ApiKey; import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.client.model.Contract; @@ -9,6 +11,7 @@ import retrofit.http.Body; import retrofit.http.GET; import retrofit.http.POST; +import retrofit.http.PUT; import retrofit.http.Path; import java.util.List; @@ -34,6 +37,10 @@ public interface ClientApiVersion2x { Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, @Body NewClientVersionBean client); + @POST("/organizations/{orgName}/clients/{clientName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Body EntityVersion client); + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}") ClientVersionBean fetchVersion(@Path("orgName") String orgName, @Path("clientName") String clientName, @Path("version") String version); @@ -49,4 +56,21 @@ Response createContract(@Path("orgName") String orgName, @Path("clientName") Str @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/contracts") List listContracts(@Path("orgName") String orgName, @Path("clientName") String clientName, @Path("version") String version); + + + @POST("/organizations/{orgName}/clients/{clientName}/versions/{version}/policies") + Response addPolicy(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Body ApiPolicy policyConfig); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/policies") + List fetchPolicies(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version); + + @GET("/organizations/{orgName}/clients/{clientName}/versions/{version}/policies/{policyId}") + ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Path("policyId") Long policyId); + + @PUT("/organizations/{orgName}/clients/{clientName}/versions/{version}/policies/{policyId}") + Response configurePolicy(@Path("orgName") String orgName, @Path("clientName") String clientName, + @Path("version") String version, @Path("policyId") Long policyId, @Body ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/Version1xClientFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/client/Version1xClientFactoryImpl.java new file mode 100644 index 0000000..90b7425 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/Version1xClientFactoryImpl.java @@ -0,0 +1,100 @@ +package io.apiman.cli.managerapi.command.client; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.EntityVersion; +import io.apiman.cli.command.client.model.ApiKey; +import io.apiman.cli.command.client.model.Client; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.cli.managerapi.management.factory.AbstractManagementApiFactory; +import io.apiman.cli.managerapi.management.factory.ManagementApiFactory; +import io.apiman.manager.api.beans.clients.ClientVersionBean; +import io.apiman.manager.api.beans.clients.NewClientVersionBean; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public class Version1xClientFactoryImpl + extends AbstractManagementApiFactory + implements ManagementApiFactory { + + @Override + public ClientApi build(String endpoint, String username, String password, boolean debugLogging) { + final ClientApiVersion1x delegate = buildClient(ClientApiVersion1x.class, endpoint, username, password, debugLogging); + + return new ClientApi() { + + @Override + public Response addPolicy(String orgName, String entityName, String version, ApiPolicy policyConfig) { + return delegate.addPolicy(orgName, entityName, version, policyConfig); + } + + @Override + public ApiPolicy fetchPolicy(String orgName, String entityName, String version, Long policyId) { + return delegate.fetchPolicy(orgName, entityName, version, policyId); + } + + @Override + public Response configurePolicy(String orgName, String entityName, String apiVersion, Long policyId, ApiPolicy policyConfig) { + return delegate.configurePolicy(orgName, entityName, apiVersion, policyId, policyConfig); + } + + @Override + public List fetchPolicies(String orgName, String entityName, String version) { + return delegate.fetchPolicies(orgName, entityName, version); + } + + @Override + public List list(String orgName) { + return delegate.list(orgName); + } + + @Override + public List listVersions(String orgName, String clientName) { + return delegate.listVersions(orgName, clientName); + } + + @Override + public Response create(String orgName, Client client) { + return delegate.create(orgName, client); + } + + @Override + public Client fetch(String orgName, String clientName) { + return delegate.fetch(orgName, clientName); + } + + @Override + public Client createVersion(String orgName, String clientName, EntityVersion client) { + return delegate.createVersion(orgName, clientName, client); + } + + public Client createVersion(String orgName, String clientName, NewClientVersionBean client) { + return delegate.createVersion(orgName, clientName, client); + } + + @Override + public ClientVersionBean fetchVersion(String orgName, String clientName, String version) { + return delegate.fetchVersion(orgName, clientName, version); + } + + @Override + public ApiKey getApiKey(String orgName, String clientName, String version) { + return delegate.getApiKey(orgName, clientName, version); + } + + @Override + public Response createContract(String orgName, String clientName, String version, Contract contract) { + return delegate.createContract(orgName, clientName, version, contract); + } + + @Override + public List listContracts(String orgName, String clientName, String version) { + return delegate.listContracts(orgName, clientName, version); + } + }; + + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java b/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java index 6075d4e..b0e0ac6 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.java @@ -1,5 +1,7 @@ package io.apiman.cli.managerapi.command.client; +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.client.model.ApiKey; import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.client.model.Contract; @@ -24,6 +26,26 @@ public ClientApi build(String endpoint, String username, String password, boolea return new ClientApi() { + @Override + public Response addPolicy(String orgName, String entityName, String version, ApiPolicy policyConfig) { + return delegate.addPolicy(orgName, entityName, version, policyConfig); + } + + @Override + public ApiPolicy fetchPolicy(String orgName, String entityName, String version, Long policyId) { + return delegate.fetchPolicy(orgName, entityName, version, policyId); + } + + @Override + public Response configurePolicy(String orgName, String entityName, String apiVersion, Long policyId, ApiPolicy policyConfig) { + return delegate.configurePolicy(orgName, entityName, apiVersion, policyId, policyConfig); + } + + @Override + public List fetchPolicies(String orgName, String entityName, String version) { + return delegate.fetchPolicies(orgName, entityName, version); + } + @Override public List list(String orgName) { return delegate.list(orgName); @@ -45,6 +67,10 @@ public Client fetch(String orgName, String clientName) { } @Override + public Client createVersion(String orgName, String clientName, EntityVersion client) { + return delegate.createVersion(orgName, clientName, client); + } + public Client createVersion(String orgName, String clientName, NewClientVersionBean client) { return delegate.createVersion(orgName, clientName, client); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java index d61fbae..6f16a29 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java @@ -20,6 +20,7 @@ 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 io.apiman.cli.managerapi.command.api.PolicyApi; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.GET; @@ -31,7 +32,7 @@ /** * @author Jean-Charles Quantin {@literal } */ -public interface PlanApi { +public interface PlanApi extends PolicyApi { @POST("/organizations/{orgName}/plans") Response create(@Path("orgName") String orgName, @Body Plan plan); @@ -55,10 +56,12 @@ public interface PlanApi { Response addPolicy(@Path("orgName") String orgName, @Path("planName") String apiName, @Path("version") String version, @Body ApiPolicy policyConfig); + @Override @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies") List fetchPolicies(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version); + @Override @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies/{policyId}") ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version, @Path("policyId") Long policyId); diff --git a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java index c4b1f98..a7783f3 100644 --- a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java @@ -72,6 +72,12 @@ protected void applyDeclaration(BaseDeclaration declaration) { ofNullable(org.getApis()).ifPresent(apis -> declarativeService.applyApis(managerCommon.getServerVersion(), apis, org.getName())); + + ofNullable(org.getClients()).ifPresent(clients -> + declarativeService.applyClients(managerCommon.getServerVersion(), clients, org.getName())); + + ofNullable(org.getPlans()).ifPresent(plans -> + declarativeService.applyPlans(managerCommon.getServerVersion(), plans, org.getName())); }); LOGGER.info("Applied declaration"); diff --git a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java index 24a4e3c..2b3047e 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java +++ b/src/main/java/io/apiman/cli/managerapi/management/ManagementApiFactoryModule.java @@ -22,6 +22,7 @@ import io.apiman.cli.managerapi.command.api.factory.Version11XManagementApiFactoryImpl; import io.apiman.cli.managerapi.command.api.factory.Version12XManagementApiFactoryImpl; import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.command.client.Version1xClientFactoryImpl; import io.apiman.cli.managerapi.command.client.Version2xClientFactoryImpl; import io.apiman.cli.managerapi.command.common.ActionApi; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; @@ -70,6 +71,10 @@ protected void configure() { .annotatedWith(ManagementApiBindings.boundTo(VersionAgnosticApi.class, ManagementApiVersion.v12x)) .to(Version12XManagementApiFactoryImpl.class).in(Singleton.class); + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(ClientApi.class, ManagementApiVersion.v11x)) + .to(Version1xClientFactoryImpl.class).in(Singleton.class); + bind(ManagementApiFactory.class) .annotatedWith(ManagementApiBindings.boundTo(ClientApi.class, ManagementApiVersion.v12x)) .to(Version2xClientFactoryImpl.class).in(Singleton.class); diff --git a/src/main/java/io/apiman/cli/managerapi/service/ClientService.java b/src/main/java/io/apiman/cli/managerapi/service/ClientService.java new file mode 100644 index 0000000..4575400 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/ClientService.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.managerapi.service; + +import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; + +/** + * Manages APIs. + * + * @author Pete Cornish {@literal } + */ +public interface ClientService { + String STATE_READY = "READY"; + String STATE_REGISTERED = "REGISTERED"; + String STATE_UNREGISTERED = "UNREGISTERED"; + + /** + * 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 register(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion); +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java new file mode 100644 index 0000000..a74fafa --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java @@ -0,0 +1,99 @@ +/* + * 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.managerapi.service; + +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.command.common.ActionApi; +import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; +import io.apiman.cli.managerapi.command.common.util.ServerActionUtil; +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 ClientServiceImpl implements ClientService { + private static final Logger LOGGER = LogManager.getLogger(ClientServiceImpl.class); + + private ManagementApiService managementApiService; + + @Inject + public ClientServiceImpl(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } + + /** + * {@inheritDoc} + */ + @Override + public String fetchCurrentState(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { + final ClientApi apiClient = managementApiService.buildServerApiClient(ClientApi.class, serverVersion); + return ofNullable(apiClient.fetchVersion(orgName, apiName, apiVersion).getStatus().name()).orElse(""); + } + + /** + * {@inheritDoc} + */ + @Override + public void register(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: + performRegister(serverVersion, orgName, apiName, apiVersion); + break; + + case STATE_REGISTERED: + switch (serverVersion) { + case v11x: + LOGGER.info("Client '{}' already published - skipping republish", apiName); + break; + + case v12x: + LOGGER.info("Republishing API: {}", apiName); + performRegister(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 performRegister(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { + LOGGER.info("Registering Client: {}", apiName); + ServerActionUtil.registerClient(orgName, apiName, apiVersion, serverVersion, + managementApiService.buildServerApiClient(ActionApi.class)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeService.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeService.java index d41fb9e..a626f12 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeService.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeService.java @@ -17,8 +17,10 @@ package io.apiman.cli.managerapi.service; import io.apiman.cli.command.declarative.model.DeclarativeApi; +import io.apiman.cli.command.declarative.model.DeclarativeClient; import io.apiman.cli.command.declarative.model.DeclarativeGateway; import io.apiman.cli.command.declarative.model.DeclarativeOrg; +import io.apiman.cli.command.declarative.model.DeclarativePlan; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import java.util.List; @@ -51,4 +53,24 @@ public interface DeclarativeService { * @param orgName the name of the organisation. */ void applyApis(ManagementApiVersion serverVersion, List apis, String orgName); + + + /** + * Add Clients to the specified organisation, if they are not present, then configure them. + * + * @param serverVersion the management server version. + * @param clients the Clients to add. + * @param orgName the name of the organisation. + */ + void applyClients(ManagementApiVersion serverVersion, List clients, String orgName); + + + /** + * Add Plans to the specified organisation, if they are not present, then configure them. + * + * @param serverVersion the management server version. + * @param plans the APIs to add. + * @param orgName the name of the organisation. + */ + void applyPlans(ManagementApiVersion serverVersion, List plans, String orgName); } diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index d31c716..aeaccbc 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -20,17 +20,26 @@ 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 io.apiman.cli.command.api.model.EndpointProperties; +import io.apiman.cli.command.api.model.EntityVersion; +import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.declarative.model.DeclarativeApi; +import io.apiman.cli.command.declarative.model.DeclarativeClient; import io.apiman.cli.command.declarative.model.DeclarativeGateway; import io.apiman.cli.command.declarative.model.DeclarativeOrg; +import io.apiman.cli.command.declarative.model.DeclarativePlan; +import io.apiman.cli.command.declarative.model.DeclarativePolicy; import io.apiman.cli.command.gateway.model.Gateway; import io.apiman.cli.command.org.model.Org; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.command.plan.model.PlanVersion; +import io.apiman.cli.managerapi.command.api.PolicyApi; import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; +import io.apiman.cli.managerapi.command.client.ClientApi; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import io.apiman.cli.managerapi.command.gateway.GatewayApi; import io.apiman.cli.managerapi.command.org.OrgApi; +import io.apiman.cli.managerapi.command.plan.PlanApi; import io.apiman.cli.managerapi.management.ManagementApiUtil; import io.apiman.cli.util.MappingUtil; import org.apache.commons.lang3.StringUtils; @@ -60,15 +69,19 @@ public class DeclarativeServiceImpl implements DeclarativeService { private static final Logger LOGGER = LogManager.getLogger(DeclarativeServiceImpl.class); - private ManagementApiService managementApiService; - private ApiService apiService; - private PolicyService policyService; + private final ManagementApiService managementApiService; + private final ClientService clientService; + private final ApiService apiService; + private final PolicyService policyService; @Inject public DeclarativeServiceImpl(ManagementApiService managementApiService, - ApiService apiService, PolicyService policyService) { + ClientService clientService, + ApiService apiService, + PolicyService policyService) { this.managementApiService = managementApiService; + this.clientService = clientService; this.apiService = apiService; this.policyService = policyService; } @@ -141,7 +154,7 @@ public void applyApis(ManagementApiVersion serverVersion, List a applyDefinition(apiClient, declarativeApi, orgName, apiName, apiVersion); // add policies - applyPolicies(serverVersion, declarativeApi, orgName, apiName, apiVersion); + applyApiPolicies(apiClient, serverVersion, declarativeApi, orgName, apiName, apiVersion); // publish API if (declarativeApi.isPublished()) { @@ -150,16 +163,155 @@ public void applyApis(ManagementApiVersion serverVersion, List a }); } + @Override + public void applyClients(ManagementApiVersion serverVersion, List clients, String orgName) { + LOGGER.debug("Applying Clients"); + + clients.forEach(declarativeClient -> { + final ClientApi clientApi = managementApiService.buildServerApiClient(ClientApi.class, serverVersion); + final String clientName = declarativeClient.getName(); + + // determine the version of the API being configured + ofNullable(declarativeClient.getInitialVersion()).ifPresent(v -> + LOGGER.warn("Use of 'initialVersion' is deprecated and will be removed in future - use 'version' instead.")); + + final String apiVersion = ofNullable(declarativeClient.getVersion()).orElse(declarativeClient.getInitialVersion()); + + // create and configure Client + applyClient(clientApi, declarativeClient, orgName, clientName, apiVersion); + + // add policies + applyClientPolicies(clientApi, serverVersion, declarativeClient, orgName, clientName, apiVersion); + + // publish Client + if (declarativeClient.isRegistered()) { + clientService.register(serverVersion, orgName, clientName, apiVersion); + } + }); + } + + @Override + public void applyPlans(ManagementApiVersion serverVersion, List plans, String orgName) { + LOGGER.debug("Applying Clients"); + + plans.forEach(declarativePlan -> { + final PlanApi clientApi = managementApiService.buildServerApiClient(PlanApi.class); + final String clientName = declarativePlan.getName(); + + // determine the version of the API being configured + ofNullable(declarativePlan.getInitialVersion()).ifPresent(v -> + LOGGER.warn("Use of 'initialVersion' is deprecated and will be removed in future - use 'version' instead.")); + + final String apiVersion = ofNullable(declarativePlan.getVersion()).orElse(declarativePlan.getInitialVersion()); + + // create and configure API + applyPlan(clientApi, declarativePlan, orgName, clientName, apiVersion); + + // add policies + applyPlanPolicies(clientApi, serverVersion, declarativePlan, orgName, clientName, apiVersion); + + // publish Client + if (declarativePlan.isLocked()) { + clientService.register(serverVersion, orgName, clientName, apiVersion); + } + }); + } + /** * Add the API, if it is not present, then configure it. * * @param apiClient - * @param declarativeApi + * @param declarativeClient * @param orgName - * @param apiName - * @param apiVersion + * @param clientName + * @param clientVersion * @return the state of the API */ + private void applyClient(ClientApi apiClient, + DeclarativeClient declarativeClient, String orgName, String clientName, String clientVersion) { + + LOGGER.debug("Applying Client: {}", clientName); + + // base Client + of(ManagementApiUtil.checkExists(() -> apiClient.fetch(orgName, clientName))) + .ifPresent(existing -> { + LOGGER.info("Client '{}' already exists", clientName); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding '{}' Client", clientName); + final Client client = MappingUtil.map(declarativeClient, Client.class); + + // IMPORTANT: don't include version in the creation request + client.setInitialVersion(null); + client.setVersion(null); + + // create Client *without* version + apiClient.create(orgName, client); + }); + + // Client version + of(ManagementApiUtil.checkExists(() -> apiClient.fetchVersion(orgName, clientName, clientVersion))) + .ifPresent(existing -> { + LOGGER.info("Client '{}' version '{}' already exists", clientName, clientVersion); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding Client '{}' version '{}'", clientName, clientVersion); + + // create version + final EntityVersion apiVersionWrapper = new EntityVersion(clientVersion); + Client client = apiClient.createVersion(orgName, clientName, apiVersionWrapper); + + // Apply contracts + applyContracts(apiClient, orgName, client); + }); + } + + private void applyContracts(ClientApi api, String orgName, Client client) { + ofNullable(client.getContracts()).ifPresent(contracts -> { + LOGGER.debug("Applying contracts to Client: {}", client.getName()); + + contracts.forEach(contract -> { + api.createContract(orgName, client.getVersion(), client.getVersion(), contract); + }); + }); + } + + private void applyPlan(PlanApi planClient, + DeclarativePlan declarativeClient, String orgName, String clientName, String clientVersion) { + + LOGGER.debug("Applying Client: {}", clientName); + + // base API + of(ManagementApiUtil.checkExists(() -> planClient.fetch(orgName, clientName))) + .ifPresent(existing -> { + LOGGER.info("Plan '{}' already exists", clientName); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding '{}' Plan", clientName); + final Plan client = MappingUtil.map(declarativeClient, Plan.class); + + // IMPORTANT: don't include version in the creation request + client.setInitialVersion(null); + client.setVersion(null); + + // create API *without* version + planClient.create(orgName, client); + }); + + // API version + of(ManagementApiUtil.checkExists(() -> planClient.fetchVersion(orgName, clientName, clientVersion))) + .ifPresent(existing -> { + LOGGER.info("Plan '{}' version '{}' already exists", clientName, clientVersion); + }) + .ifNotPresent(() -> { + LOGGER.info("Adding Client '{}' version '{}'", clientName, clientVersion); + + // create version + final PlanVersion planVersion = new PlanVersion(clientVersion); + planClient.createVersion(orgName, clientName, planVersion); + }); + } + private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi apiClient, DeclarativeApi declarativeApi, String orgName, String apiName, String apiVersion) { @@ -191,7 +343,7 @@ private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi api LOGGER.info("Adding API '{}' version '{}'", apiName, apiVersion); // create version - final ApiVersion apiVersionWrapper = new ApiVersion(apiVersion); + final EntityVersion apiVersionWrapper = new EntityVersion(apiVersion); apiClient.createVersion(orgName, apiName, apiVersionWrapper); if (v11x.equals(serverVersion)) { @@ -238,12 +390,6 @@ private void configureApi(DeclarativeApi declarativeApi, VersionAgnosticApi apiC /** * Adds a definition to the API. - * - * @param apiClient - * @param declarativeApi - * @param orgName - * @param apiName - * @param apiVersion */ private void applyDefinition(VersionAgnosticApi apiClient, DeclarativeApi declarativeApi, String orgName, String apiName, String apiVersion) { @@ -272,22 +418,45 @@ private void applyDefinition(VersionAgnosticApi apiClient, DeclarativeApi declar }); } + private void applyPlanPolicies(PolicyApi policyApi, + ManagementApiVersion serverVersion, + DeclarativePlan declarativePlan, + String orgName, + String apiName, + String apiVersion) { + + applyPolicies(policyApi, serverVersion, orgName, apiName, apiVersion, declarativePlan.getPolicies()); + } + + private void applyApiPolicies(PolicyApi policyApi, + ManagementApiVersion serverVersion, + DeclarativeApi declarativeApi, + String orgName, + String apiName, + String apiVersion) { + + applyPolicies(policyApi, serverVersion, orgName, apiName, apiVersion, declarativeApi.getPolicies()); + } + + private void applyClientPolicies(PolicyApi policyApi, + ManagementApiVersion serverVersion, + DeclarativeClient declarativeClient, + String orgName, + String apiName, + String apiVersion) { + + applyPolicies(policyApi, serverVersion, orgName, apiName, apiVersion, declarativeClient.getPolicies()); + } + /** * 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 -> { + private void applyPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion, List policies) { + ofNullable(policies).ifPresent(declarativePolicies -> { LOGGER.debug("Applying policies to API: {}", apiName); // existing policies for the API - final List apiPolicies = policyService.fetchPolicies(serverVersion, orgName, apiName, apiVersion); + final List apiPolicies = policyService.fetchPolicies(policyApi, serverVersion, orgName, apiName, apiVersion); declarativePolicies.forEach(declarativePolicy -> { final String policyName = declarativePolicy.getName(); @@ -295,7 +464,7 @@ private void applyPolicies(ManagementApiVersion serverVersion, DeclarativeApi de final ApiPolicy apiPolicy = new ApiPolicy( MappingUtil.safeWriteValueAsJson(declarativePolicy.getConfig())); - policyService.applyPolicies(serverVersion, orgName, apiName, apiVersion, apiPolicies, policyName, apiPolicy); + policyService.applyPolicies(policyApi, serverVersion, orgName, apiName, apiVersion, apiPolicies, policyName, apiPolicy); }); }); } diff --git a/src/main/java/io/apiman/cli/managerapi/service/PolicyService.java b/src/main/java/io/apiman/cli/managerapi/service/PolicyService.java index ffea469..26dd5fe 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/PolicyService.java +++ b/src/main/java/io/apiman/cli/managerapi/service/PolicyService.java @@ -17,6 +17,7 @@ package io.apiman.cli.managerapi.service; import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.managerapi.command.api.PolicyApi; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import java.util.List; @@ -36,7 +37,7 @@ public interface PolicyService { * @param apiVersion the API version * @return the policies */ - List fetchPolicies(ManagementApiVersion serverVersion, String orgName, + List fetchPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion); /** @@ -50,7 +51,7 @@ List fetchPolicies(ManagementApiVersion serverVersion, String orgName * @param policyName the policy name * @param apiPolicy the policy to apply */ - void applyPolicies(ManagementApiVersion serverVersion, String orgName, + void applyPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion, List apiPolicies, String policyName, ApiPolicy apiPolicy); } diff --git a/src/main/java/io/apiman/cli/managerapi/service/PolicyServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/PolicyServiceImpl.java index aeb9680..4533855 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/PolicyServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/PolicyServiceImpl.java @@ -17,7 +17,7 @@ package io.apiman.cli.managerapi.service; import io.apiman.cli.command.api.model.ApiPolicy; -import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; +import io.apiman.cli.managerapi.command.api.PolicyApi; import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -47,22 +47,23 @@ public PolicyServiceImpl(ManagementApiService managementApiService) { * {@inheritDoc} */ @Override - public List fetchPolicies(ManagementApiVersion serverVersion, String orgName, + public List fetchPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { - - final VersionAgnosticApi apiClient = managementApiService.buildServerApiClient(VersionAgnosticApi.class, serverVersion); - return apiClient.fetchPolicies(orgName, apiName, apiVersion); + return policyApi.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); + public void applyPolicies(PolicyApi policyApi, + ManagementApiVersion serverVersion, + String orgName, + String apiName, + String apiVersion, + List apiPolicies, + String policyName, + ApiPolicy apiPolicy) { // determine if the policy already exists for this API final Optional existingPolicy = apiPolicies.stream() @@ -75,7 +76,7 @@ public void applyPolicies(ManagementApiVersion serverVersion, String orgName, LOGGER.info("Updating existing policy '{}' configuration for API: {}", policyName, apiName); final Long policyId = existingPolicy.get().getId(); - apiClient.configurePolicy(orgName, apiName, apiVersion, policyId, apiPolicy); + policyApi.configurePolicy(orgName, apiName, apiVersion, policyId, apiPolicy); } else { LOGGER.info("Policy '{}' already exists for API '{}' - skipping configuration update", policyName, apiName); @@ -86,7 +87,7 @@ public void applyPolicies(ManagementApiVersion serverVersion, String orgName, LOGGER.info("Adding policy '{}' to API: {}", policyName, apiName); apiPolicy.setDefinitionId(policyName); - apiClient.addPolicy(orgName, apiName, apiVersion, apiPolicy); + policyApi.addPolicy(orgName, apiName, apiVersion, apiPolicy); } } } diff --git a/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java b/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java index 8d0634c..c8e624d 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java @@ -28,6 +28,7 @@ public class ServiceModule extends AbstractModule { @Override protected void configure() { bind(ManagementApiService.class).to(ManagementApiServiceImpl.class).in(Singleton.class); + bind(ClientService.class).to(ClientServiceImpl.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); From 0c9b13d16a1c6be3d51b7761b37491cac254366d Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sat, 7 Apr 2018 17:30:14 +0100 Subject: [PATCH 04/15] Add plan to API --- .../command/api/VersionAgnosticApi.java | 1 - .../command/api/command/ApiCommand.java | 1 + .../api/command/ApiPlanAddCommand.java | 59 +++++++++++++++++++ .../command/api/command/ApiPlanCommand.java | 29 +++++++++ .../api/command/ApiPolicyAddCommand.java | 2 +- .../command/api/command/ApiPolicyCommand.java | 2 +- 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanCommand.java diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java index 96b4890..e6fba46 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/VersionAgnosticApi.java @@ -50,7 +50,6 @@ Response setDefinition(String orgName, String apiName, String version, String definitionType, TypedString definition); - @Override Response addPolicy(String orgName, String apiName, String version, ApiPolicy policyConfig); diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java index 2d498d1..492d529 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCommand.java @@ -43,6 +43,7 @@ protected void populateCommands(Map> commandMap commandMap.put("list", ApiListCommand.class); commandMap.put("publish", ApiPublishCommand.class); commandMap.put("policy", ApiPolicyCommand.class); + commandMap.put("plan", ApiPlanCommand.class); commandMap.put("definition", ApiDefinitionCommand.class); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java new file mode 100644 index 0000000..95ed53e --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java @@ -0,0 +1,59 @@ +package io.apiman.cli.managerapi.command.api.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.api.model.ApiConfig; +import io.apiman.cli.command.api.model.ApiPlan; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.api.ApiMixin; +import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Add Plan to API") +public class ApiPlanAddCommand extends AbstractApiCommand implements ApiMixin { + private static final Logger LOGGER = LogManager.getLogger(ApiPlanAddCommand.class); + + @Parameter(names = { "--name", "-n" }, description = "API name", required = true) + private String apiName; + + @Parameter(names = { "--version", "-v" }, description = "API version", required = true) + private String apiVersion; + + @Parameter(names = { "--planName", "-p" }, description = "Plan name", required = true) + private String planName; + + @Parameter(names = { "--planVersion", "-w" }, description = "Plan Version", required = true) + private String planVersion; + + @Inject + public ApiPlanAddCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Adding Plan '{}' to API '{}'", () -> planName, this::getModelName); + + VersionAgnosticApi api = getManagerConfig() + .buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()); + + ManagementApiUtil.invokeAndCheckResponse(() -> { + ApiConfig conf = api.fetchVersionConfig(orgName, apiName, apiVersion); + + // Add the plan + conf.getPlans().add(new ApiPlan(planName, planVersion)); + + return api.configure(orgName, apiName, apiVersion, conf); + }); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanCommand.java new file mode 100644 index 0000000..a049795 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanCommand.java @@ -0,0 +1,29 @@ +package io.apiman.cli.managerapi.command.api.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.AbstractManagerCommand; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Manage Plans available on APIs") +public class ApiPlanCommand extends AbstractManagerCommand { + + @Inject + public ApiPlanCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("add", ApiPlanAddCommand.class); + //commandMap.put("remove", ApiPlanRemoveCommand.class); + //commandMap.put("list", ApiPlanListCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java index f985b5b..ddc4e96 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyAddCommand.java @@ -44,7 +44,7 @@ */ @Parameters(commandDescription = "Add policy to API") public class ApiPolicyAddCommand extends AbstractApiCommand implements ApiMixin { - private static final Logger LOGGER = LogManager.getLogger(ApiPolicyAddCommand.class); + private static final Logger LOGGER = LogManager.getLogger(ApiPlanAddCommand.class); @Parameter(names = { "--name", "-n" }, description = "API name", required = true) private String name; diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java index 5fc16a3..e7c2323 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java @@ -39,7 +39,7 @@ public ApiPolicyCommand(ManagementApiService managementApiService) { @Override protected void populateCommands(Map> commandMap) { - commandMap.put("add", ApiPolicyAddCommand.class); + commandMap.put("add", ApiPlanAddCommand.class); } } From e005d402ce6e8a965f0852dbf274769f609e3611 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sat, 7 Apr 2018 21:00:37 +0100 Subject: [PATCH 05/15] Work around Retrofit limitations. --- .../api/command/ApiPlanAddCommand.java | 4 +- .../managerapi/command/client/ClientApi.java | 12 +++-- .../client/command/ClientCreateCommand.java | 3 -- .../cli/managerapi/command/plan/PlanApi.java | 10 +++-- .../plan/command/AbstractPlanCommand.java | 16 ++++--- .../plan/command/PlanCreateCommand.java | 3 +- .../command/plan/command/PlanListCommand.java | 2 +- .../service/DeclarativeServiceImpl.java | 11 +++-- .../service/delegates/ApiPolicyDelegate.java | 45 +++++++++++++++++++ .../delegates/ClientPolicyDelegate.java | 45 +++++++++++++++++++ .../service/delegates/PlanPolicyDelegate.java | 45 +++++++++++++++++++ 11 files changed, 172 insertions(+), 24 deletions(-) create mode 100644 src/main/java/io/apiman/cli/managerapi/service/delegates/ApiPolicyDelegate.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/delegates/ClientPolicyDelegate.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/delegates/PlanPolicyDelegate.java diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java index 95ed53e..5fc910a 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java @@ -28,10 +28,10 @@ public class ApiPlanAddCommand extends AbstractApiCommand implements ApiMixin { @Parameter(names = { "--version", "-v" }, description = "API version", required = true) private String apiVersion; - @Parameter(names = { "--planName", "-p" }, description = "Plan name", required = true) + @Parameter(names = { "--planName", "-pn" }, description = "Plan name", required = true) private String planName; - @Parameter(names = { "--planVersion", "-w" }, description = "Plan Version", required = true) + @Parameter(names = { "--planVersion", "-pv" }, description = "Plan Version", required = true) private String planVersion; @Inject diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java index 25136e1..dacc826 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java @@ -16,11 +16,11 @@ package io.apiman.cli.managerapi.command.client; +import io.apiman.cli.command.api.model.ApiPolicy; import io.apiman.cli.command.api.model.EntityVersion; import io.apiman.cli.command.client.model.ApiKey; import io.apiman.cli.command.client.model.Client; import io.apiman.cli.command.client.model.Contract; -import io.apiman.cli.managerapi.command.api.PolicyApi; import io.apiman.manager.api.beans.clients.ClientVersionBean; import retrofit.client.Response; import retrofit.http.Path; @@ -30,11 +30,11 @@ /** * @author Jean-Charles Quantin {@literal } */ -public interface ClientApi extends PolicyApi { +public interface ClientApi { List list(String orgName); // Hack to display only name, seemingly. - List listVersions(@Path("orgName") String orgName, @Path("clientName") String clientName); // Hack to display only version, seemingly. + List listVersions( String orgName, @Path("clientName") String clientName); // Hack to display only version, seemingly. Response create(String orgName, Client client); @@ -50,6 +50,12 @@ public interface ClientApi extends PolicyApi { List listContracts(String orgName, String clientName, String version); + // Policy + Response addPolicy(String orgName, String apiName, String version, ApiPolicy policyConfig); + List fetchPolicies(String orgName, String planName, String version); + ApiPolicy fetchPolicy(String orgName, String planName, String version, Long policyId); + + Response configurePolicy(String orgName, String planName, String version, Long policyId, ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java index a78ff2c..461441c 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java @@ -31,9 +31,6 @@ import javax.inject.Inject; /** - * Create an API. - * - * @author Pete Cornish {@literal } */ @Parameters(commandDescription = "Create a Client") public class ClientCreateCommand extends AbstractClientCommand { diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java index 6f16a29..70767ef 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java @@ -20,11 +20,11 @@ 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 io.apiman.cli.managerapi.command.api.PolicyApi; import retrofit.client.Response; import retrofit.http.Body; import retrofit.http.GET; import retrofit.http.POST; +import retrofit.http.PUT; import retrofit.http.Path; import java.util.List; @@ -32,7 +32,7 @@ /** * @author Jean-Charles Quantin {@literal } */ -public interface PlanApi extends PolicyApi { +public interface PlanApi { @POST("/organizations/{orgName}/plans") Response create(@Path("orgName") String orgName, @Body Plan plan); @@ -56,13 +56,15 @@ public interface PlanApi extends PolicyApi { Response addPolicy(@Path("orgName") String orgName, @Path("planName") String apiName, @Path("version") String version, @Body ApiPolicy policyConfig); - @Override @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies") List fetchPolicies(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version); - @Override @GET("/organizations/{orgName}/plans/{planName}/versions/{version}/policies/{policyId}") ApiPolicy fetchPolicy(@Path("orgName") String orgName, @Path("planName") String planName, @Path("version") String version, @Path("policyId") Long policyId); + + @PUT("/organizations/{orgName}/plans/{planName}/versions/{version}/policies/{policyId}") + Response configurePolicy(@Path("orgName") String orgName, @Path("planName") String planName, + @Path("version") String version, @Path("policyId") Long policyId, @Body ApiPolicy policyConfig); } diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java index 53e317e..0328291 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.java @@ -17,21 +17,27 @@ package io.apiman.cli.managerapi.command.plan.command; import com.beust.jcommander.Parameter; -import io.apiman.cli.command.api.model.Api; -import io.apiman.cli.managerapi.command.api.ApiMixin; -import io.apiman.cli.managerapi.command.api.Version12xServerApi; +import io.apiman.cli.command.plan.model.Plan; import io.apiman.cli.managerapi.command.common.command.AbstractManagerModelCommand; +import io.apiman.cli.managerapi.command.plan.PlanApi; import io.apiman.cli.managerapi.service.ManagementApiService; /** * @author Marc Savy {@literal } */ -public abstract class AbstractPlanCommand extends AbstractManagerModelCommand - implements ApiMixin { +public abstract class AbstractPlanCommand extends AbstractManagerModelCommand { @Parameter(names = { "--orgName", "-o"}, description = "Organisation name", required = true) protected String orgName; public AbstractPlanCommand(ManagementApiService managementApiService) { super(managementApiService); } + + public Class getModelClass() { + return Plan.class; + } + + public Class getApiClass() { + return PlanApi.class; + } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java index 1461b47..d25b7fe 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java @@ -60,8 +60,7 @@ public void performFinalAction(JCommander parser) throws CommandException { initialVersion); // create - final PlanApi planClient = getManagerConfig() - .buildServerApiClient(PlanApi.class, getManagerConfig().getServerVersion()); + final PlanApi planClient = getManagerConfig().buildServerApiClient(PlanApi.class); ManagementApiUtil.invokeAndCheckResponse(() -> planClient.create(orgName, plan)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java index 81004b0..6123c2c 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanListCommand.java @@ -47,7 +47,7 @@ public void performFinalAction(JCommander parser) throws CommandException { LOGGER.debug("Listing {}", this::getModelName); final List plans = getManagerConfig() - .buildServerApiClient(PlanApi.class, getManagerConfig().getServerVersion()) + .buildServerApiClient(PlanApi.class) .list(orgName); LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(plans)); } diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index aeaccbc..2633bfd 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -41,6 +41,8 @@ import io.apiman.cli.managerapi.command.org.OrgApi; import io.apiman.cli.managerapi.command.plan.PlanApi; import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.delegates.ClientPolicyDelegate; +import io.apiman.cli.managerapi.service.delegates.PlanPolicyDelegate; import io.apiman.cli.util.MappingUtil; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; @@ -181,7 +183,7 @@ public void applyClients(ManagementApiVersion serverVersion, List LOGGER.debug("Applying Clients"); plans.forEach(declarativePlan -> { - final PlanApi clientApi = managementApiService.buildServerApiClient(PlanApi.class); + final PlanApi planApi = managementApiService.buildServerApiClient(PlanApi.class); final String clientName = declarativePlan.getName(); // determine the version of the API being configured @@ -205,10 +207,10 @@ public void applyPlans(ManagementApiVersion serverVersion, List final String apiVersion = ofNullable(declarativePlan.getVersion()).orElse(declarativePlan.getInitialVersion()); // create and configure API - applyPlan(clientApi, declarativePlan, orgName, clientName, apiVersion); + applyPlan(planApi, declarativePlan, orgName, clientName, apiVersion); // add policies - applyPlanPolicies(clientApi, serverVersion, declarativePlan, orgName, clientName, apiVersion); + applyPlanPolicies(PlanPolicyDelegate.wrap(planApi), serverVersion, declarativePlan, orgName, clientName, apiVersion); // publish Client if (declarativePlan.isLocked()) { @@ -468,4 +470,5 @@ private void applyPolicies(PolicyApi policyApi, ManagementApiVersion serverVersi }); }); } + } diff --git a/src/main/java/io/apiman/cli/managerapi/service/delegates/ApiPolicyDelegate.java b/src/main/java/io/apiman/cli/managerapi/service/delegates/ApiPolicyDelegate.java new file mode 100644 index 0000000..d868a4f --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/delegates/ApiPolicyDelegate.java @@ -0,0 +1,45 @@ +package io.apiman.cli.managerapi.service.delegates; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.managerapi.command.api.PolicyApi; +import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ + +public class ApiPolicyDelegate implements PolicyApi { + + private final VersionAgnosticApi api; + + public ApiPolicyDelegate(VersionAgnosticApi api) { + this.api = api; + } + + public static ApiPolicyDelegate wrap(VersionAgnosticApi api) { + return new ApiPolicyDelegate(api); + } + + @Override + public Response addPolicy(String orgName, String entityName, String version, ApiPolicy policyConfig) { + return api.addPolicy(orgName, entityName, version, policyConfig); + } + + @Override + public ApiPolicy fetchPolicy(String orgName, String entityName, String version, Long policyId) { + return api.fetchPolicy(orgName, entityName, version, policyId); + } + + @Override + public Response configurePolicy(String orgName, String entityName, String apiVersion, Long policyId, ApiPolicy policyConfig) { + return api.configurePolicy(orgName, entityName, apiVersion, policyId, policyConfig); + } + + @Override + public List fetchPolicies(String orgName, String entityName, String version) { + return api.fetchPolicies(orgName, entityName, version); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/delegates/ClientPolicyDelegate.java b/src/main/java/io/apiman/cli/managerapi/service/delegates/ClientPolicyDelegate.java new file mode 100644 index 0000000..bdabf44 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/delegates/ClientPolicyDelegate.java @@ -0,0 +1,45 @@ +package io.apiman.cli.managerapi.service.delegates; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.managerapi.command.api.PolicyApi; +import io.apiman.cli.managerapi.command.client.ClientApi; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ + +public class ClientPolicyDelegate implements PolicyApi { + + private final ClientApi api; + + public ClientPolicyDelegate(ClientApi api) { + this.api = api; + } + + public static ClientPolicyDelegate wrap(ClientApi clientApi) { + return new ClientPolicyDelegate(clientApi); + } + + @Override + public Response addPolicy(String orgName, String entityName, String version, ApiPolicy policyConfig) { + return api.addPolicy(orgName, entityName, version, policyConfig); + } + + @Override + public ApiPolicy fetchPolicy(String orgName, String entityName, String version, Long policyId) { + return api.fetchPolicy(orgName, entityName, version, policyId); + } + + @Override + public Response configurePolicy(String orgName, String entityName, String apiVersion, Long policyId, ApiPolicy policyConfig) { + return api.configurePolicy(orgName, entityName, apiVersion, policyId, policyConfig); + } + + @Override + public List fetchPolicies(String orgName, String entityName, String version) { + return api.fetchPolicies(orgName, entityName, version); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/delegates/PlanPolicyDelegate.java b/src/main/java/io/apiman/cli/managerapi/service/delegates/PlanPolicyDelegate.java new file mode 100644 index 0000000..89d405d --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/delegates/PlanPolicyDelegate.java @@ -0,0 +1,45 @@ +package io.apiman.cli.managerapi.service.delegates; + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.managerapi.command.api.PolicyApi; +import io.apiman.cli.managerapi.command.plan.PlanApi; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ + +public class PlanPolicyDelegate implements PolicyApi { + + private final PlanApi api; + + public PlanPolicyDelegate(PlanApi api) { + this.api = api; + } + + public static PlanPolicyDelegate wrap(PlanApi planApi) { + return new PlanPolicyDelegate(planApi); + } + + @Override + public Response addPolicy(String orgName, String entityName, String version, ApiPolicy policyConfig) { + return api.addPolicy(orgName, entityName, version, policyConfig); + } + + @Override + public ApiPolicy fetchPolicy(String orgName, String entityName, String version, Long policyId) { + return api.fetchPolicy(orgName, entityName, version, policyId); + } + + @Override + public Response configurePolicy(String orgName, String entityName, String apiVersion, Long policyId, ApiPolicy policyConfig) { + return api.configurePolicy(orgName, entityName, apiVersion, policyId, policyConfig); + } + + @Override + public List fetchPolicies(String orgName, String entityName, String version) { + return api.fetchPolicies(orgName, entityName, version); + } +} From 41be5432fce76c999ad4ef86bd9872b9783be6ed Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sun, 8 Apr 2018 12:38:20 +0100 Subject: [PATCH 06/15] Add support for creating and listing contracts on Clients. --- .../command/client/command/ClientCommand.java | 1 + .../client/command/ClientContractCommand.java | 27 ++++++++ .../command/ClientContractCreateCommand.java | 63 +++++++++++++++++++ .../command/ClientContractListCommand.java | 44 +++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCreateCommand.java create mode 100644 src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java index 6e2644e..4e4876f 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java @@ -39,6 +39,7 @@ public ClientCommand(ManagementApiService managementApiService) { @Override protected void populateCommands(Map> commandMap) { commandMap.put("create", ClientCreateCommand.class); + commandMap.put("contract", ClientContractCommand.class); commandMap.put("list", ClientListCommand.class); commandMap.put("register", ClientRegisterCommand.class); commandMap.put("policy", ClientPolicyCommand.class); diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCommand.java new file mode 100644 index 0000000..7063a83 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCommand.java @@ -0,0 +1,27 @@ +package io.apiman.cli.managerapi.command.client.command; + +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.core.Command; +import io.apiman.cli.managerapi.service.ManagementApiService; + +import javax.inject.Inject; +import java.util.Map; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Manage client contracts (APIs client is subscribed to)") +public class ClientContractCommand extends AbstractManagerCommand { + + @Inject + public ClientContractCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + protected void populateCommands(Map> commandMap) { + commandMap.put("create", ClientContractCreateCommand.class); + commandMap.put("list", ClientContractListCommand.class); + } + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCreateCommand.java new file mode 100644 index 0000000..a1b0155 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractCreateCommand.java @@ -0,0 +1,63 @@ +package io.apiman.cli.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.ManagerCommon; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.management.ManagementApiUtil; +import io.apiman.cli.managerapi.service.ManagementApiService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +/** + * @author Marc Savy {@literal } + */ +@Parameters(commandDescription = "Establish a contract between Client and an API via a Plan (subscribe to API)") +public class ClientContractCreateCommand extends AbstractClientCommand { + private static final Logger LOGGER = LogManager.getLogger(ClientCreateCommand.class); + + @Parameter(names = {"--name", "-n"}, description = "Client name", required = true) + private String name; + + @Parameter(names = {"--version", "-v"}, description = "Client version", required = true) + private String version; + + @Parameter(names = {"--apiOrg", "-ao"}, description = "Organization of API to subscribe to") + private String apiOrg; + + @Parameter(names = {"--apiName", "-an"}, description = "API to subscribe to", required = true) + private String apiName; + + @Parameter(names = {"--apiVersion", "-av"}, description = "API Version to subscribe to", required = true) + private String apiVersion; + + @Parameter(names = {"--planName", "-pn"}, description = "Name of Plan to subscribe to", required = true) + private String planName; + + private final ManagerCommon manager; + + @Inject + public ClientContractCreateCommand(ManagementApiService managementApiService) { + super(managementApiService); + manager = getManagerConfig(); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Creating {}", this::getModelName); + + final Contract contract = new Contract(); + contract.setApiId(apiName); + contract.setApiOrgId(apiOrg == null ? orgName : apiOrg); // If no API org provided, then assume all in same org. + contract.setApiVersion(apiVersion); + contract.setPlanId(planName); + + ClientApi clientApi = manager.buildServerApiClient(ClientApi.class, manager.getServerVersion()); + ManagementApiUtil.invokeAndCheckResponse(() -> clientApi.createContract(orgName, name, version , contract)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java new file mode 100644 index 0000000..4fd1dfc --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java @@ -0,0 +1,44 @@ +package io.apiman.cli.managerapi.command.client.command; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import io.apiman.cli.command.client.model.Contract; +import io.apiman.cli.exception.CommandException; +import io.apiman.cli.managerapi.command.client.ClientApi; +import io.apiman.cli.managerapi.command.plan.command.PlanListCommand; +import io.apiman.cli.managerapi.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 javax.inject.Inject; +import java.util.List; + +/** + * @author Marc Savy {@literal } + */ +public class ClientContractListCommand extends AbstractClientCommand { + private static final Logger LOGGER = LogManager.getLogger(PlanListCommand.class); + + @Parameter(names = {"--name", "-n"}, description = "Client name", required = true) + private String clientName; + + @Parameter(names = {"--version", "-v"}, description = "Client version", required = true) + private String clientVersion; + + @Inject + public ClientContractListCommand(ManagementApiService managementApiService) { + super(managementApiService); + } + + @Override + public void performFinalAction(JCommander parser) throws CommandException { + LOGGER.debug("Listing {}", this::getModelName); + + final List plans = getManagerConfig() + .buildServerApiClient(ClientApi.class, getManagerConfig().getServerVersion()) + .listContracts(orgName, clientName, clientVersion); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(plans)); + } +} From dd66ce4d3c2384f5ca74216a33e2cf39b64b2010 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Sun, 8 Apr 2018 12:48:30 +0100 Subject: [PATCH 07/15] Catch error Signed-off-by: Marc Savy --- .../client/command/ClientContractListCommand.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java index 4fd1dfc..9ff529f 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java @@ -4,6 +4,7 @@ import com.beust.jcommander.Parameter; import io.apiman.cli.command.client.model.Contract; import io.apiman.cli.exception.CommandException; +import io.apiman.cli.gatewayapi.GatewayHelper; import io.apiman.cli.managerapi.command.client.ClientApi; import io.apiman.cli.managerapi.command.plan.command.PlanListCommand; import io.apiman.cli.managerapi.service.ManagementApiService; @@ -18,7 +19,7 @@ /** * @author Marc Savy {@literal } */ -public class ClientContractListCommand extends AbstractClientCommand { +public class ClientContractListCommand extends AbstractClientCommand implements GatewayHelper { private static final Logger LOGGER = LogManager.getLogger(PlanListCommand.class); @Parameter(names = {"--name", "-n"}, description = "Client name", required = true) @@ -36,9 +37,13 @@ public ClientContractListCommand(ManagementApiService managementApiService) { public void performFinalAction(JCommander parser) throws CommandException { LOGGER.debug("Listing {}", this::getModelName); - final List plans = getManagerConfig() - .buildServerApiClient(ClientApi.class, getManagerConfig().getServerVersion()) - .listContracts(orgName, clientName, clientVersion); + ClientApi clientApi = getManagerConfig() + .buildServerApiClient(ClientApi.class, getManagerConfig().getServerVersion()); + + List plans = callAndCatch(() -> { + return clientApi.listContracts(orgName, clientName, clientVersion); + }); + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(plans)); } } From 27ac39a570aa80292553502deacb2d4f18c863e3 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Mon, 9 Apr 2018 14:39:55 +0100 Subject: [PATCH 08/15] Fix issue with Jackson ser/deser Behaviour seemed to have changed for some reason, so took opportunity to align dependencies with Apiman main project use the ser/deser feature to fix. Signed-off-by: Marc Savy --- build.gradle | 4 +- .../declarative/model/DeclarativePolicy.java | 53 +++++++++++++------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index bd3699b..f1a7cce 100644 --- a/build.gradle +++ b/build.gradle @@ -46,8 +46,8 @@ ext { version_log4j = '2.8.2' version_guava = '19.0' version_retrofit = '1.9.0' - version_jackson = '1.9.0' - version_jackson_yaml = '2.7.3' + version_jackson = '2.9.2' + version_jackson_yaml = '2.9.2' version_modelmapper = '0.7.5' version_commons_lang = '3.4' version_guice = '4.0' 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 e7549ef..4a4d6ea 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 @@ -16,15 +16,22 @@ package io.apiman.cli.command.declarative.model; -import java.io.IOException; - import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.IOException; /** * Declarative policy representation. @@ -41,10 +48,11 @@ public class DeclarativePolicy { @JsonProperty private String name; - @JsonProperty private String plugin; - @JsonProperty + @JsonProperty("config") + @JsonSerialize(using = JsonNodeToStringSerializer.class, as = String.class) + @JsonDeserialize(using = StringToJsonNodeDeserializer.class) private JsonNode config; public String getId() { @@ -62,17 +70,10 @@ public void setName(String name) { public JsonNode getConfig() { return config; } - - public void setConfig(String jsonConfig) { - ObjectMapper mapper = new ObjectMapper(); - JsonNode actualObj = null; - try { - actualObj = mapper.readTree(jsonConfig); - } catch (IOException e) { - e.printStackTrace(); - } - this.config = actualObj; - } + + public void setConfig(JsonNode config) { + this.config = config; + } public String getPlugin() { return plugin; @@ -90,4 +91,24 @@ public void setId(String id) { this.id = id; } + + public static final class JsonNodeToStringSerializer extends JsonSerializer { + + @Override + public void serialize(JsonNode tmpNode, + JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeObject(tmpNode.toString()); + } + } + + public static final class StringToJsonNodeDeserializer extends JsonDeserializer { + public StringToJsonNodeDeserializer() {} + + @Override + public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return p.readValueAsTree(); + } + } } From ea3a5e04e68d700d226a501e01d5479a5fbfdf88 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Mon, 9 Apr 2018 23:31:47 +0100 Subject: [PATCH 09/15] Fix declarative plans Signed-off-by: Marc Savy --- .../cli/management/factory/PostConverter.java | 6 --- .../factory/ManagementApiFactory.java | 2 - .../managerapi/service/ClientServiceImpl.java | 10 ++--- .../service/DeclarativeServiceImpl.java | 21 ++++++----- .../cli/managerapi/service/PlanService.java | 32 ++++++++++++++++ .../managerapi/service/PlanServiceImpl.java | 37 +++++++++++++++++++ .../cli/managerapi/service/ServiceModule.java | 1 + 7 files changed, 87 insertions(+), 22 deletions(-) delete mode 100644 src/main/java/io/apiman/cli/management/factory/PostConverter.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/PlanService.java create mode 100644 src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java diff --git a/src/main/java/io/apiman/cli/management/factory/PostConverter.java b/src/main/java/io/apiman/cli/management/factory/PostConverter.java deleted file mode 100644 index c78e4b2..0000000 --- a/src/main/java/io/apiman/cli/management/factory/PostConverter.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.apiman.cli.management.factory; - -public interface PostConverter { - public void postConvert(Object o); - -} diff --git a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java index e226c97..c12bc31 100644 --- a/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java +++ b/src/main/java/io/apiman/cli/managerapi/management/factory/ManagementApiFactory.java @@ -16,8 +16,6 @@ package io.apiman.cli.managerapi.management.factory; -import io.apiman.cli.management.factory.PostConverter; - /** * Builds a Management API client proxy for a given API interface. * diff --git a/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java index a74fafa..b31e381 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ClientServiceImpl.java @@ -29,7 +29,7 @@ import static java.util.Optional.ofNullable; /** - * Manages APIs. + * Manages Clients. * * @author Pete Cornish {@literal } */ @@ -57,7 +57,7 @@ public String fetchCurrentState(ManagementApiVersion serverVersion, String orgNa */ @Override public void register(ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion) { - LOGGER.debug("Attempting to publish API: {}", apiName); + LOGGER.debug("Attempting to publish Client: {}", apiName); final String apiState = fetchCurrentState(serverVersion, orgName, apiName, apiVersion); switch (apiState.toUpperCase()) { @@ -68,11 +68,11 @@ public void register(ManagementApiVersion serverVersion, String orgName, String case STATE_REGISTERED: switch (serverVersion) { case v11x: - LOGGER.info("Client '{}' already published - skipping republish", apiName); + LOGGER.info("Client '{}' already register - skipping republish", apiName); break; case v12x: - LOGGER.info("Republishing API: {}", apiName); + LOGGER.info("Registering Client: {}", apiName); performRegister(serverVersion, orgName, apiName, apiVersion); break; } @@ -80,7 +80,7 @@ public void register(ManagementApiVersion serverVersion, String orgName, String default: throw new CommandException(String.format( - "Unable to publish API '%s' in state: %s", apiName, apiState)); + "Unable to publish Client '%s' in state: %s", apiName, apiState)); } } diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index 2633bfd..3a5cb79 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -74,17 +74,20 @@ public class DeclarativeServiceImpl implements DeclarativeService { private final ManagementApiService managementApiService; private final ClientService clientService; private final ApiService apiService; + private final PlanService planService; private final PolicyService policyService; @Inject public DeclarativeServiceImpl(ManagementApiService managementApiService, ClientService clientService, ApiService apiService, + PlanService planService, PolicyService policyService) { this.managementApiService = managementApiService; this.clientService = clientService; this.apiService = apiService; + this.planService = planService; this.policyService = policyService; } @@ -194,27 +197,27 @@ public void applyClients(ManagementApiVersion serverVersion, List plans, String orgName) { - LOGGER.debug("Applying Clients"); + LOGGER.debug("Applying Plans"); plans.forEach(declarativePlan -> { final PlanApi planApi = managementApiService.buildServerApiClient(PlanApi.class); - final String clientName = declarativePlan.getName(); + final String planName = declarativePlan.getName(); // determine the version of the API being configured ofNullable(declarativePlan.getInitialVersion()).ifPresent(v -> LOGGER.warn("Use of 'initialVersion' is deprecated and will be removed in future - use 'version' instead.")); - final String apiVersion = ofNullable(declarativePlan.getVersion()).orElse(declarativePlan.getInitialVersion()); + final String planVersion = ofNullable(declarativePlan.getVersion()).orElse(declarativePlan.getInitialVersion()); // create and configure API - applyPlan(planApi, declarativePlan, orgName, clientName, apiVersion); + applyPlan(planApi, declarativePlan, orgName, planName, planVersion); // add policies - applyPlanPolicies(PlanPolicyDelegate.wrap(planApi), serverVersion, declarativePlan, orgName, clientName, apiVersion); + applyPlanPolicies(PlanPolicyDelegate.wrap(planApi), serverVersion, declarativePlan, orgName, planName, planVersion); - // publish Client + // lock plan if (declarativePlan.isLocked()) { - clientService.register(serverVersion, orgName, clientName, apiVersion); + planService.lock(orgName, planName, planVersion); } }); } @@ -281,7 +284,7 @@ private void applyContracts(ClientApi api, String orgName, Client client) { private void applyPlan(PlanApi planClient, DeclarativePlan declarativeClient, String orgName, String clientName, String clientVersion) { - LOGGER.debug("Applying Client: {}", clientName); + LOGGER.debug("Applying Plan: {}", clientName); // base API of(ManagementApiUtil.checkExists(() -> planClient.fetch(orgName, clientName))) @@ -306,7 +309,7 @@ private void applyPlan(PlanApi planClient, LOGGER.info("Plan '{}' version '{}' already exists", clientName, clientVersion); }) .ifNotPresent(() -> { - LOGGER.info("Adding Client '{}' version '{}'", clientName, clientVersion); + LOGGER.info("Adding Plan '{}' version '{}'", clientName, clientVersion); // create version final PlanVersion planVersion = new PlanVersion(clientVersion); diff --git a/src/main/java/io/apiman/cli/managerapi/service/PlanService.java b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java new file mode 100644 index 0000000..7498788 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java @@ -0,0 +1,32 @@ +package io.apiman.cli.managerapi.service; + +/** + * Manages APIs. + * + * @author Pete Cornish {@literal } + */ +public interface PlanService { + String STATE_READY = "READY"; + String STATE_CREATED = "CREATED"; + String STATE_LOCKED = "LOCKED"; + + /** + * Return the current state of the API. + * + * @param orgName the organisation name + * @param planName the API name + * @param planVersion the API version + * @return the API state + */ + String fetchCurrentState(String orgName, String planName, String planVersion); + + /** + * Lock the plan, if it is in the 'Ready' state. + * + * @param orgName the organisation name + * @param planName the API name + * @param planVersion the API version + * @return the API state + */ + void lock(String orgName, String planName, String planVersion); +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java new file mode 100644 index 0000000..4ee2873 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java @@ -0,0 +1,37 @@ +package io.apiman.cli.managerapi.service; + +import io.apiman.cli.managerapi.command.common.ActionApi; +import io.apiman.cli.managerapi.command.common.util.ServerActionUtil; +import io.apiman.cli.managerapi.command.plan.PlanApi; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.inject.Inject; + +import static java.util.Optional.ofNullable; + +public class PlanServiceImpl implements PlanService { + private static final Logger LOGGER = LogManager.getLogger(PlanServiceImpl.class); + + private ManagementApiService managementApiService; + + @Inject + public PlanServiceImpl(ManagementApiService managementApiService) { + this.managementApiService = managementApiService; + } + + @Override + public String fetchCurrentState(String orgName, String planName, String planVersion) { + final PlanApi planClient = managementApiService.buildServerApiClient(PlanApi.class); + final String planState = ofNullable(planClient.fetchVersion(orgName, planName, planVersion).getStatus()).orElse(""); + LOGGER.debug("Plan '{}' state: {}", planName, planState); + return planState; + } + + @Override + public void lock(String orgName, String planName, String planVersion) { + LOGGER.info("Locking Plan: {}", planName); + ServerActionUtil.lockPlan(orgName, planName, planVersion, + managementApiService.buildServerApiClient(ActionApi.class)); + } +} diff --git a/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java b/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java index c8e624d..087b246 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java @@ -30,6 +30,7 @@ protected void configure() { bind(ManagementApiService.class).to(ManagementApiServiceImpl.class).in(Singleton.class); bind(ClientService.class).to(ClientServiceImpl.class).in(Singleton.class); bind(ApiService.class).to(ApiServiceImpl.class).in(Singleton.class); + bind(PlanService.class).to(PlanServiceImpl.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); From 18e96bc834ac5684a77bcf16b2d68eceafd447e2 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Wed, 11 Apr 2018 15:21:42 +0100 Subject: [PATCH 10/15] Fix snapshot build and ordering issues Signed-off-by: Marc Savy --- build.gradle | 13 ++++++-- .../apiman/cli/command/api/model/ApiPlan.java | 4 ++- .../model/DeclarativeContract.java | 32 +++++++++++++++++++ .../managerapi/command/client/ClientApi.java | 3 +- .../command/ManagerApplyCommand.java | 5 +-- .../service/DeclarativeServiceImpl.java | 11 +++++-- .../cli/managerapi/service/PlanService.java | 3 -- 7 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 src/main/java/io/apiman/cli/command/declarative/model/DeclarativeContract.java diff --git a/build.gradle b/build.gradle index f1a7cce..e02e846 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,9 @@ version '0.3.0-SNAPSHOT' buildscript { repositories { + maven { + url "https://oss.sonatype.org/content/repositories/snapshots/" + } jcenter() maven { url "https://plugins.gradle.org/m2/" @@ -34,6 +37,9 @@ apply plugin: 'com.github.johnrengelman.shadow' repositories { mavenCentral() + maven { + url "https://oss.sonatype.org/content/repositories/snapshots/" + } } compileJava { @@ -46,12 +52,12 @@ ext { version_log4j = '2.8.2' version_guava = '19.0' version_retrofit = '1.9.0' - version_jackson = '2.9.2' - version_jackson_yaml = '2.9.2' + version_jackson = '2.9.5' + version_jackson_yaml = '2.9.5' version_modelmapper = '0.7.5' version_commons_lang = '3.4' version_guice = '4.0' - version_apiman = '1.3.1.Final' + version_apiman = '1.3.2-SNAPSHOT' // test dependencies version_junit = '4.12' @@ -68,6 +74,7 @@ dependencies { compile "com.google.guava:guava:$version_guava" compile "com.squareup.retrofit:retrofit:$version_retrofit" compile "com.squareup.retrofit:converter-jackson:$version_retrofit" + compile "com.fasterxml.jackson.core:jackson-annotations:$version_jackson" compile "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$version_jackson_yaml" compile "org.modelmapper:modelmapper:$version_modelmapper" compile "org.apache.commons:commons-lang3:$version_commons_lang" 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 index 1d39ec1..d862b10 100644 --- a/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java @@ -16,6 +16,7 @@ package io.apiman.cli.command.api.model; +import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -26,7 +27,8 @@ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class ApiPlan { - @JsonProperty + + @JsonAlias({"name", "planId"}) private String planId; @JsonProperty diff --git a/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeContract.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeContract.java new file mode 100644 index 0000000..20884f6 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeContract.java @@ -0,0 +1,32 @@ +/* + * 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; +import io.apiman.cli.command.client.model.Contract; + +/** + * Declarative policy representation. + * + * @author Pete Cornish {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeclarativeContract extends Contract { + +} diff --git a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java index dacc826..cf7a381 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java @@ -23,7 +23,6 @@ import io.apiman.cli.command.client.model.Contract; import io.apiman.manager.api.beans.clients.ClientVersionBean; import retrofit.client.Response; -import retrofit.http.Path; import java.util.List; @@ -34,7 +33,7 @@ public interface ClientApi { List list(String orgName); // Hack to display only name, seemingly. - List listVersions( String orgName, @Path("clientName") String clientName); // Hack to display only version, seemingly. + List listVersions( String orgName, String clientName); // Hack to display only version, seemingly. Response create(String orgName, Client client); diff --git a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java index a7783f3..7d84980 100644 --- a/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/declarative/command/ManagerApplyCommand.java @@ -70,14 +70,15 @@ protected void applyDeclaration(BaseDeclaration declaration) { ofNullable(declaration.getOrg()).ifPresent(org -> { declarativeService.applyOrg(org); + ofNullable(org.getPlans()).ifPresent(plans -> + declarativeService.applyPlans(managerCommon.getServerVersion(), plans, org.getName())); + ofNullable(org.getApis()).ifPresent(apis -> declarativeService.applyApis(managerCommon.getServerVersion(), apis, org.getName())); ofNullable(org.getClients()).ifPresent(clients -> declarativeService.applyClients(managerCommon.getServerVersion(), clients, org.getName())); - ofNullable(org.getPlans()).ifPresent(plans -> - declarativeService.applyPlans(managerCommon.getServerVersion(), plans, org.getName())); }); LOGGER.info("Applied declaration"); diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index 3a5cb79..f33ef4b 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -217,7 +217,14 @@ public void applyPlans(ManagementApiVersion serverVersion, List // lock plan if (declarativePlan.isLocked()) { - planService.lock(orgName, planName, planVersion); + String state = planService.fetchCurrentState(orgName, planName, planVersion); + + if (state.equalsIgnoreCase(PlanService.STATE_READY) || state.equalsIgnoreCase(PlanService.STATE_CREATED)) { + planService.lock(orgName, planName, planVersion); + } else if (state.equalsIgnoreCase(PlanService.STATE_LOCKED)) { + LOGGER.info("Plan {} {} already locked.", + declarativePlan.getName(), declarativePlan.getVersion()); + } } }); } @@ -458,7 +465,7 @@ private void applyClientPolicies(PolicyApi policyApi, */ private void applyPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion, List policies) { ofNullable(policies).ifPresent(declarativePolicies -> { - LOGGER.debug("Applying policies to API: {}", apiName); + LOGGER.debug("Applying policies to Entity: {}", apiName); // existing policies for the API final List apiPolicies = policyService.fetchPolicies(policyApi, serverVersion, orgName, apiName, apiVersion); diff --git a/src/main/java/io/apiman/cli/managerapi/service/PlanService.java b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java index 7498788..f8ef957 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/PlanService.java +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java @@ -1,9 +1,6 @@ package io.apiman.cli.managerapi.service; /** - * Manages APIs. - * - * @author Pete Cornish {@literal } */ public interface PlanService { String STATE_READY = "READY"; From deddb67dc1f054ba2d786f58591df77aeee46b67 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Wed, 11 Apr 2018 21:37:35 +0100 Subject: [PATCH 11/15] Rejig plan code into helper service Signed-off-by: Marc Savy --- .../managerapi/service/DeclarativeServiceImpl.java | 13 +++---------- .../cli/managerapi/service/PlanServiceImpl.java | 13 ++++++++++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index f33ef4b..5a7a007 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -188,7 +188,7 @@ public void applyClients(ManagementApiVersion serverVersion, List // lock plan if (declarativePlan.isLocked()) { - String state = planService.fetchCurrentState(orgName, planName, planVersion); - - if (state.equalsIgnoreCase(PlanService.STATE_READY) || state.equalsIgnoreCase(PlanService.STATE_CREATED)) { - planService.lock(orgName, planName, planVersion); - } else if (state.equalsIgnoreCase(PlanService.STATE_LOCKED)) { - LOGGER.info("Plan {} {} already locked.", - declarativePlan.getName(), declarativePlan.getVersion()); - } + planService.lock(orgName, planName, planVersion); } }); } @@ -367,7 +360,7 @@ private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi api 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())) { + if (ApiService.STATE_RETIRED.equalsIgnoreCase(apiState)) { LOGGER.warn("API '{}' is retired - skipping configuration", apiName); } else { diff --git a/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java index 4ee2873..5dbd92d 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java @@ -30,8 +30,15 @@ public String fetchCurrentState(String orgName, String planName, String planVers @Override public void lock(String orgName, String planName, String planVersion) { - LOGGER.info("Locking Plan: {}", planName); - ServerActionUtil.lockPlan(orgName, planName, planVersion, - managementApiService.buildServerApiClient(ActionApi.class)); + String state = fetchCurrentState(orgName, planName, planVersion); + // Only lock if in valid state + if (state.equalsIgnoreCase(PlanService.STATE_READY) || state.equalsIgnoreCase(PlanService.STATE_CREATED)) { + LOGGER.info("Locking Plan: {}", planName); + ServerActionUtil.lockPlan(orgName, planName, planVersion, + managementApiService.buildServerApiClient(ActionApi.class)); + } else if (state.equalsIgnoreCase(PlanService.STATE_LOCKED)) { + LOGGER.info("Plan {} {} already locked.", + planName, planVersion); + } } } From fe64f5832afc3d9392e5ab7f43e2ee11c033763e Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Wed, 11 Apr 2018 21:49:52 +0100 Subject: [PATCH 12/15] Ensure private APIs handled correctly. Signed-off-by: Marc Savy --- .../managerapi/service/DeclarativeServiceImpl.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index 5a7a007..17e4ca3 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -359,12 +359,20 @@ private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi api if (v12x.equals(serverVersion)) { // The v1.2.x API supports configuration of the API even if published (but not retired) + // but only if a public API final String apiState = apiService.fetchCurrentState(serverVersion, orgName, apiName, apiVersion); + + // If retired, then skip if (ApiService.STATE_RETIRED.equalsIgnoreCase(apiState)) { LOGGER.warn("API '{}' is retired - skipping configuration", apiName); - } else { - configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); + // If it's a public API or any API in ready state, then it's safe to configure. + if (declarativeApi.getConfig().isPublicApi() || ApiService.STATE_READY.equalsIgnoreCase(apiState)) { + configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); + } else { + // Otherwise it's a private API and in a non-modifiable state. + LOGGER.warn("API '{}' is not in a modifiable state {} - skipping configuration", apiName, apiState); + } } } } From fef3679fd72fb2417353f84773ae690788c126dc Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Wed, 11 Apr 2018 22:02:49 +0100 Subject: [PATCH 13/15] Revert accidental refactor Signed-off-by: Marc Savy --- .../cli/managerapi/command/api/command/ApiPolicyCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java index e7c2323..5fc16a3 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPolicyCommand.java @@ -39,7 +39,7 @@ public ApiPolicyCommand(ManagementApiService managementApiService) { @Override protected void populateCommands(Map> commandMap) { - commandMap.put("add", ApiPlanAddCommand.class); + commandMap.put("add", ApiPolicyAddCommand.class); } } From 4fa8b2ed2d5a84545cdd4367fe7a14c037de945d Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Thu, 12 Apr 2018 16:54:43 +0100 Subject: [PATCH 14/15] Ensure created state is OK for configuration of APIs Signed-off-by: Marc Savy --- .../java/io/apiman/cli/managerapi/service/ApiService.java | 5 +++++ .../cli/managerapi/service/DeclarativeServiceImpl.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/apiman/cli/managerapi/service/ApiService.java b/src/main/java/io/apiman/cli/managerapi/service/ApiService.java index 22a4057..47c2cb0 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ApiService.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ApiService.java @@ -25,9 +25,14 @@ */ public interface ApiService { String STATE_READY = "READY"; + String STATE_CREATED = "CREATED"; String STATE_PUBLISHED = "PUBLISHED"; String STATE_RETIRED = "RETIRED"; + default boolean isUnpublished(String state) { + return state.equalsIgnoreCase(STATE_READY) || state.equalsIgnoreCase(STATE_CREATED); + } + /** * Return the current state of the API. * diff --git a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java index 17e4ca3..5b0caa2 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -367,7 +367,7 @@ private void applyApi(ManagementApiVersion serverVersion, VersionAgnosticApi api LOGGER.warn("API '{}' is retired - skipping configuration", apiName); } else { // If it's a public API or any API in ready state, then it's safe to configure. - if (declarativeApi.getConfig().isPublicApi() || ApiService.STATE_READY.equalsIgnoreCase(apiState)) { + if (declarativeApi.getConfig().isPublicApi() || apiService.isUnpublished(apiState)) { configureApi(declarativeApi, apiClient, orgName, apiName, apiVersion); } else { // Otherwise it's a private API and in a non-modifiable state. From b8f43a09be465e65d6007908e43cfb0601292a35 Mon Sep 17 00:00:00 2001 From: Marc Savy Date: Thu, 12 Apr 2018 18:09:09 +0100 Subject: [PATCH 15/15] Allow arbitrary endpoint properties to be set. Signed-off-by: Marc Savy --- .../command/api/model/EndpointProperties.java | 22 +++++++++++++++---- .../command/api/command/ApiCreateCommand.java | 16 ++++++++++++++ .../cli/managerapi/service/ClientService.java | 8 ++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java b/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java index f5e91d9..73a68d9 100644 --- a/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java +++ b/src/main/java/io/apiman/cli/command/api/model/EndpointProperties.java @@ -16,15 +16,16 @@ package io.apiman.cli.command.api.model; +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.lang.reflect.Field; import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - /** * @author Pete Cornish {@literal } */ @@ -43,6 +44,8 @@ public class EndpointProperties { @JsonProperty("basic-auth.password") private String password; + private Map arbitraryFields; + public void setAuthorizationType(String authorizationType) { this.authorizationType = authorizationType; } @@ -73,4 +76,15 @@ public Map toMap() { } return map; } + + @JsonAnyGetter + public Map getArbitraryFields() { + return arbitraryFields; + } + + @JsonAnyGetter + public EndpointProperties setArbitraryFields(Map arbitraryFields) { + this.arbitraryFields = arbitraryFields; + return this; + } } diff --git a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java index cee2c31..094d222 100644 --- a/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java +++ b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java @@ -16,6 +16,7 @@ package io.apiman.cli.managerapi.command.api.command; +import com.beust.jcommander.DynamicParameter; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameters; @@ -23,6 +24,7 @@ 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.model.EndpointProperties; import io.apiman.cli.exception.CommandException; import io.apiman.cli.managerapi.command.api.ApiMixin; import io.apiman.cli.managerapi.command.api.VersionAgnosticApi; @@ -32,6 +34,9 @@ import org.apache.logging.log4j.Logger; import javax.inject.Inject; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; /** * Create an API. @@ -63,6 +68,10 @@ public class ApiCreateCommand extends AbstractApiCommand implements ApiMixin { @Parameter(names = {"--gateway", "-g"}, description = "Gateway") private String gateway = "TheGateway"; + @DynamicParameter(names = {"--endpointProperty", "-ep"}, + description = "Endpoint properties (-ep foo=bar -ep fizz=buzz)") + private Map endpointProperties = new LinkedHashMap<>(); + @Inject public ApiCreateCommand(ManagementApiService managementApiService) { super(managementApiService); @@ -83,6 +92,13 @@ public void performFinalAction(JCommander parser) throws CommandException { publicApi, Lists.newArrayList(new ApiGateway(gateway))); + if (!endpointProperties.isEmpty()) { + EndpointProperties endpointProperties = Optional.ofNullable(config.getEndpointProperties()) + .orElse(new EndpointProperties()); + endpointProperties.setArbitraryFields(this.endpointProperties); + config.setEndpointProperties(endpointProperties); + } + // create final VersionAgnosticApi apiClient = getManagerConfig() .buildServerApiClient(VersionAgnosticApi.class, getManagerConfig().getServerVersion()); diff --git a/src/main/java/io/apiman/cli/managerapi/service/ClientService.java b/src/main/java/io/apiman/cli/managerapi/service/ClientService.java index 4575400..f9b92ff 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ClientService.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ClientService.java @@ -19,15 +19,17 @@ import io.apiman.cli.managerapi.command.common.model.ManagementApiVersion; /** - * Manages APIs. - * - * @author Pete Cornish {@literal } */ public interface ClientService { String STATE_READY = "READY"; + String STATE_CREATED = "CREATED"; String STATE_REGISTERED = "REGISTERED"; String STATE_UNREGISTERED = "UNREGISTERED"; + default boolean isUnpublished(String state) { + return state.equalsIgnoreCase(STATE_READY) || state.equalsIgnoreCase(STATE_CREATED); + } + /** * Return the current state of the API. *