diff --git a/build.gradle b/build.gradle index bd3699b..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 = '1.9.0' - version_jackson_yaml = '2.7.3' + 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/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/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..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; @@ -46,6 +47,12 @@ public class ApiConfig { @JsonProperty private List gateways; + @JsonProperty + private List plans; + + @JsonIgnore + private boolean hasPlans; + public ApiConfig() { } @@ -54,6 +61,15 @@ 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 +92,14 @@ public void setGateways(ArrayList gateways) { this.gateways = gateways; } + public List getPlans() { + return plans; + } + + public void setPlans(ArrayList plans) { + this.plans = plans; + } + public void setPublicApi(boolean publicApi) { this.publicApi = publicApi; } @@ -87,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/command/api/model/ApiPlan.java b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java new file mode 100644 index 0000000..d862b10 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/api/model/ApiPlan.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.api.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +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 { + + @JsonAlias({"name", "planId"}) + 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; + } + +} 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/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/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/client/model/ApiKey.java b/src/main/java/io/apiman/cli/command/client/model/ApiKey.java new file mode 100644 index 0000000..fd5cf62 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/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.command.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/command/client/model/Client.java b/src/main/java/io/apiman/cli/command/client/model/Client.java new file mode 100644 index 0000000..895c38b --- /dev/null +++ b/src/main/java/io/apiman/cli/command/client/model/Client.java @@ -0,0 +1,106 @@ +/* + * 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.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 + private String name; + + @JsonProperty + private String description; + + @JsonProperty + private String initialVersion; + + @JsonProperty + private String version; + + @JsonProperty + private String apiKey; + + @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; + } + + 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; + } + + public String getInitialVersion() { + return initialVersion; + } + + public Client setInitialVersion(String initialVersion) { + this.initialVersion = initialVersion; + return this; + } +} diff --git a/src/main/java/io/apiman/cli/command/client/model/Contract.java b/src/main/java/io/apiman/cli/command/client/model/Contract.java new file mode 100644 index 0000000..bf0d5fe --- /dev/null +++ b/src/main/java/io/apiman/cli/command/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.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 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/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/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/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/command/declarative/model/DeclarativeOrg.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativeOrg.java index cf9c8d9..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 @@ -31,9 +31,24 @@ @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; } @@ -41,4 +56,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/DeclarativePlan.java b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java new file mode 100644 index 0000000..a2cff7f --- /dev/null +++ b/src/main/java/io/apiman/cli/command/declarative/model/DeclarativePlan.java @@ -0,0 +1,52 @@ +package io.apiman.cli.command.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.command.plan.model.Plan; + +import java.util.List; + +/** + * Declarative Plan representation. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeclarativePlan extends Plan { + + @JsonProperty + private boolean locked; + + @JsonProperty + private List policies; + + public List getPolicies() { + return policies; + } + + public void setPolicies(List policies) { + this.policies = policies; + } + + public boolean isLocked() { + return locked; + } +} 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..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,13 +16,22 @@ package io.apiman.cli.command.declarative.model; -import java.util.Map; - 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.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. @@ -39,11 +48,12 @@ public class DeclarativePolicy { @JsonProperty private String name; - @JsonProperty private String plugin; - @JsonProperty - private Map config; + @JsonProperty("config") + @JsonSerialize(using = JsonNodeToStringSerializer.class, as = String.class) + @JsonDeserialize(using = StringToJsonNodeDeserializer.class) + private JsonNode config; public String getId() { return id; @@ -57,11 +67,11 @@ public void setName(String name) { this.name = name; } - public Map getConfig() { + public JsonNode getConfig() { return config; } - public void setConfig(Map config) { + public void setConfig(JsonNode config) { this.config = config; } @@ -76,4 +86,29 @@ public void setPlugin(String plugin) { public boolean isPlugin() { return !(plugin == null || plugin.isEmpty()); } + + 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(); + } + } } diff --git a/src/main/java/io/apiman/cli/command/org/model/Bean.java b/src/main/java/io/apiman/cli/command/org/model/Bean.java new file mode 100644 index 0000000..9d0d648 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/org/model/Bean.java @@ -0,0 +1,109 @@ +package io.apiman.cli.command.org.model; + +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 java.util.HashMap; +import java.util.Map; + +@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); +} + +} diff --git a/src/main/java/io/apiman/cli/command/org/model/Filter.java b/src/main/java/io/apiman/cli/command/org/model/Filter.java new file mode 100644 index 0000000..0b8838e --- /dev/null +++ b/src/main/java/io/apiman/cli/command/org/model/Filter.java @@ -0,0 +1,70 @@ +package io.apiman.cli.command.org.model; + +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 java.util.HashMap; +import java.util.Map; + +@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); +} + +} 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..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 @@ -45,4 +45,8 @@ public Org(String name, String description) { public String getName() { return name; } + + public String getDescription() { + return description; + } } diff --git a/src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java b/src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java new file mode 100644 index 0000000..a4aaa98 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/org/model/OrgSearchIn.java @@ -0,0 +1,100 @@ +package io.apiman.cli.command.org.model; + +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({ +"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); +} + +} diff --git a/src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java b/src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java new file mode 100644 index 0000000..9f9952a --- /dev/null +++ b/src/main/java/io/apiman/cli/command/org/model/OrgSearchOut.java @@ -0,0 +1,60 @@ +package io.apiman.cli.command.org.model; + +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@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/command/plan/model/Plan.java b/src/main/java/io/apiman/cli/command/plan/model/Plan.java new file mode 100644 index 0000000..d5711a8 --- /dev/null +++ b/src/main/java/io/apiman/cli/command/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.command.plan.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Models a Plan. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Plan { + @JsonProperty + private String name; + + @JsonProperty + private String description; + + @JsonProperty + private String organizationName; + + /** + * Note: use {@link #version} instead for declarative API configuration. + */ + @JsonProperty + private String initialVersion; + + @JsonProperty + private String version; + + @JsonProperty + private String status; + + public Plan() { + } + + public Plan(String name, String description, String initialVersion) { + this.name = name; + this.description = description; + this.initialVersion = initialVersion; + } + + public String 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; + } +} diff --git a/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java new file mode 100644 index 0000000..768865e --- /dev/null +++ b/src/main/java/io/apiman/cli/command/plan/model/PlanVersion.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Jean-Charles Quantin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.apiman.cli.command.plan.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Models an Plan version. + * + * @author Jean-Charles Quantin {@literal } + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class PlanVersion { + @JsonProperty + private String version; + + /** + * Never clone a previous version when creating a new version. + */ + @JsonProperty + final private boolean clone = false; + + public PlanVersion(String version) { + this.version = version; + } +} diff --git a/src/main/java/io/apiman/cli/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/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/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/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 5bc3101..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 @@ -17,8 +17,9 @@ 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.EntityVersion; import io.apiman.cli.command.api.model.ServiceConfig; import retrofit.client.Response; import retrofit.http.Body; @@ -41,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); @@ -52,6 +53,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,7 +75,12 @@ 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..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); @@ -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..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 @@ -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,29 +27,42 @@ /** * @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); - Api fetch(String orgName, String apiName); + 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); - 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/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("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/ApiCreateCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiCreateCommand.java index dc5e9f7..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,8 +92,16 @@ 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, 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/ApiPlanAddCommand.java b/src/main/java/io/apiman/cli/managerapi/command/api/command/ApiPlanAddCommand.java new file mode 100644 index 0000000..5fc910a --- /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", "-pn" }, description = "Plan name", required = true) + private String planName; + + @Parameter(names = { "--planVersion", "-pv" }, 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 8ae1b6f..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; @@ -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 27e3798..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; @@ -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); @@ -49,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); } @@ -67,6 +69,16 @@ 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 +102,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..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); } @@ -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/client/ClientApi.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java new file mode 100644 index 0000000..cf7a381 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApi.java @@ -0,0 +1,60 @@ +/* + * 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.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.manager.api.beans.clients.ClientVersionBean; +import retrofit.client.Response; + +import java.util.List; + +/** + * @author Jean-Charles Quantin {@literal } + */ +public interface ClientApi { + + List list(String orgName); // Hack to display only name, seemingly. + + List listVersions( String orgName, 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, EntityVersion 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); + + // 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/ClientApiVersion1x.java b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java new file mode 100644 index 0000000..8397776 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion1x.java @@ -0,0 +1,75 @@ +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.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.PUT; +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/{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/{applicationName}") + Client fetch(@Path("orgName") String orgName, @Path("applicationName") String applicationName); + + @POST("/organizations/{orgName}/applications/{applicationName}/versions") + Client createVersion(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Body NewClientVersionBean client); + + @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/{applicationName}/versions/{version}/apikey") + ApiKey getApiKey(@Path("orgName") String orgName, @Path("applicationName") String applicationName, + @Path("version") String version); + + @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/{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 new file mode 100644 index 0000000..c4d121c --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/ClientApiVersion2x.java @@ -0,0 +1,76 @@ +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.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.PUT; +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); + + @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); + + @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); + + + @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 new file mode 100644 index 0000000..b0e0ac6 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/Version2xClientFactoryImpl.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 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 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/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..4e4876f --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCommand.java @@ -0,0 +1,48 @@ +/* + * 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("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..9ff529f --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientContractListCommand.java @@ -0,0 +1,49 @@ +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.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; +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 implements GatewayHelper { + 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); + + ClientApi clientApi = getManagerConfig() + .buildServerApiClient(ClientApi.class, getManagerConfig().getServerVersion()); + + List plans = callAndCatch(() -> { + return clientApi.listContracts(orgName, clientName, clientVersion); + }); + + LogUtil.OUTPUT.info(MappingUtil.safeWriteValueAsJson(plans)); + } +} 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..461441c --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/client/command/ClientCreateCommand.java @@ -0,0 +1,68 @@ +/* + * 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; + +/** + */ +@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 5e19b94..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 @@ -64,4 +64,61 @@ 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, + 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, + orgName, + clientName, + clientVersion + ); + + return actionClient.doAction(action); + }); + } } 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 48a714d..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,9 +28,13 @@ * @author Pete Cornish {@literal } */ public interface OrgApi { + @POST("/organizations") Response create(@Body Org organisation); @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/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/managerapi/command/plan/PlanApi.java b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java new file mode 100644 index 0000000..70767ef --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/PlanApi.java @@ -0,0 +1,70 @@ + +/* + * 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.plan; + + +import io.apiman.cli.command.api.model.ApiPolicy; +import io.apiman.cli.command.plan.model.Plan; +import io.apiman.cli.command.plan.model.PlanVersion; +import retrofit.client.Response; +import retrofit.http.Body; +import retrofit.http.GET; +import retrofit.http.POST; +import retrofit.http.PUT; +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); + + @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); + + @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 new file mode 100644 index 0000000..0328291 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/AbstractPlanCommand.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.Parameter; +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 { + @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/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..d25b7fe --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/command/plan/command/PlanCreateCommand.java @@ -0,0 +1,66 @@ +/* + * 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); + 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..6123c2c --- /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) + .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..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 @@ -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; @@ -74,8 +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(serverVersion, apis, org.getName())); + declarativeService.applyApis(managerCommon.getServerVersion(), apis, org.getName())); + + ofNullable(org.getClients()).ifPresent(clients -> + declarativeService.applyClients(managerCommon.getServerVersion(), clients, org.getName())); + }); LOGGER.info("Applied declaration"); @@ -86,6 +89,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 c90d312..2b3047e 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,14 @@ 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.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; 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; @@ -66,5 +70,18 @@ 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(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); + + bind(ManagementApiFactory.class) + .annotatedWith(ManagementApiBindings.boundTo(PlanApi.class)) + .toInstance(new SimpleManagementApiFactoryImpl<>(PlanApi.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..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 @@ -39,7 +39,7 @@ public abstract class AbstractManagementApiFactory implements ManagementAp * @return an API client for the given Class */ protected A buildClient(Class apiClass, String endpoint, String username, String password, boolean debugLogging) { - final RestAdapter.Builder builder = new RestAdapter.Builder() // + final RestAdapter.Builder builder = new RestAdapter.Builder() .setConverter(new JacksonConverter(JSON_MAPPER)) .setEndpoint(endpoint) .setRequestInterceptor(request -> { 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..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 @@ -27,6 +27,7 @@ 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); 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..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 @@ -28,8 +28,9 @@ 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) { + return buildClient(apiClass, endpoint, username, password, debugLogging); + } } 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/ClientService.java b/src/main/java/io/apiman/cli/managerapi/service/ClientService.java new file mode 100644 index 0000000..f9b92ff --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/ClientService.java @@ -0,0 +1,53 @@ +/* + * 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; + +/** + */ +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. + * + * @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..b31e381 --- /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 Clients. + * + * @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 Client: {}", 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 register - skipping republish", apiName); + break; + + case v12x: + LOGGER.info("Registering Client: {}", apiName); + performRegister(serverVersion, orgName, apiName, apiVersion); + break; + } + break; + + default: + throw new CommandException(String.format( + "Unable to publish Client '%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..5b0caa2 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java +++ b/src/main/java/io/apiman/cli/managerapi/service/DeclarativeServiceImpl.java @@ -20,18 +20,29 @@ 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.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; @@ -60,16 +71,23 @@ 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 PlanService planService; + private final PolicyService policyService; @Inject public DeclarativeServiceImpl(ManagementApiService managementApiService, - ApiService apiService, PolicyService policyService) { + ClientService clientService, + ApiService apiService, + PlanService planService, + PolicyService policyService) { this.managementApiService = managementApiService; + this.clientService = clientService; this.apiService = apiService; + this.planService = planService; this.policyService = policyService; } @@ -141,7 +159,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 +168,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(ClientPolicyDelegate.wrap(clientApi), serverVersion, declarativeClient, orgName, clientName, apiVersion); + + // Register Client + if (declarativeClient.isRegistered()) { + clientService.register(serverVersion, orgName, clientName, apiVersion); + } + }); + } + + @Override + public void applyPlans(ManagementApiVersion serverVersion, List plans, String orgName) { + LOGGER.debug("Applying Plans"); + + plans.forEach(declarativePlan -> { + final PlanApi planApi = managementApiService.buildServerApiClient(PlanApi.class); + 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 planVersion = ofNullable(declarativePlan.getVersion()).orElse(declarativePlan.getInitialVersion()); + + // create and configure API + applyPlan(planApi, declarativePlan, orgName, planName, planVersion); + + // add policies + applyPlanPolicies(PlanPolicyDelegate.wrap(planApi), serverVersion, declarativePlan, orgName, planName, planVersion); + + // lock plan + if (declarativePlan.isLocked()) { + planService.lock(orgName, planName, planVersion); + } + }); + } + /** * 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 Plan: {}", 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 Plan '{}' 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 +348,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)) { @@ -202,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 (ApiService.STATE_RETIRED.equals(apiState.toUpperCase())) { - LOGGER.warn("API '{}' is retired - skipping configuration", apiName); + // 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.isUnpublished(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); + } } } } @@ -238,12 +403,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 +431,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 -> { - LOGGER.debug("Applying policies to API: {}", apiName); + private void applyPolicies(PolicyApi policyApi, ManagementApiVersion serverVersion, String orgName, String apiName, String apiVersion, List policies) { + ofNullable(policies).ifPresent(declarativePolicies -> { + LOGGER.debug("Applying policies to Entity: {}", 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,8 +477,9 @@ 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/PlanService.java b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java new file mode 100644 index 0000000..f8ef957 --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanService.java @@ -0,0 +1,29 @@ +package io.apiman.cli.managerapi.service; + +/** + */ +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..5dbd92d --- /dev/null +++ b/src/main/java/io/apiman/cli/managerapi/service/PlanServiceImpl.java @@ -0,0 +1,44 @@ +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) { + 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); + } + } +} 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..087b246 100644 --- a/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java +++ b/src/main/java/io/apiman/cli/managerapi/service/ServiceModule.java @@ -28,7 +28,9 @@ 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(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); 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); + } +} 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 6041357..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. @@ -197,6 +199,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; });