From 59270644351f3d84924787d52c5e4b19b347ee73 Mon Sep 17 00:00:00 2001 From: ayyoob Date: Wed, 18 Jan 2017 01:48:07 +0530 Subject: [PATCH] apim seperation --- ...ApiApplicationRegistrationServiceImpl.java | 26 +- .../api/util/RegistrationProfile.java | 28 - .../pom.xml | 4 + .../APIManagementProviderService.java | 10 +- .../APIManagementRestProviderServiceImpl.java | 151 + ...ApplicationManagerExtensionDataHolder.java | 11 + ...ationManagerExtensionServiceComponent.java | 20 +- .../pom.xml | 159 + .../client/IntegrationClientServiceImpl.java | 43 + .../client/OAuthRequestInterceptor.java | 111 + .../integration/client/PublisherClient.java | 92 + .../integration/client/StoreClient.java | 103 + .../client/configs/APIMConfig.java | 90 + .../client/configs/APIMConfigReader.java | 94 + .../client/exception/APIMClientException.java | 58 + .../exception/APIMClientOAuthException.java | 58 + .../InvalidConfigurationStateException.java | 78 + .../APIIntegrationClientDataHolder.java | 45 + .../APIIntegrationClientServiceComponent.java | 77 + .../client/model/ClientProfile.java | 96 + .../integration/client/model/DCRClient.java | 36 + .../client/model/OAuthApplication.java | 103 + .../service/IntegrationClientService.java | 41 + .../client/util/PropertyUtils.java | 41 + .../pom.xml | 173 ++ .../src/main/resources/publisher-api.yaml | 2747 +++++++++++++++++ .../pom.xml | 176 ++ .../src/main/resources/store-api.yaml | 2098 +++++++++++++ .../webapp/publisher/APIPublisherService.java | 15 - components/apimgt-extensions/pom.xml | 3 + .../pom.xml | 145 + .../src/main/resources/build.properties | 1 + .../main/resources/conf/apim-integration.xml | 28 + .../src/main/resources/p2.inf | 2 + features/apimgt-extensions/pom.xml | 1 + pom.xml | 72 +- 36 files changed, 6961 insertions(+), 75 deletions(-) create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementRestProviderServiceImpl.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/IntegrationClientServiceImpl.java create mode 100755 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/PublisherClient.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/StoreClient.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfig.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfigReader.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientException.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientOAuthException.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/InvalidConfigurationStateException.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientDataHolder.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientServiceComponent.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/ClientProfile.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/DCRClient.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/OAuthApplication.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/service/IntegrationClientService.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/PropertyUtils.java create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/pom.xml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/src/main/resources/publisher-api.yaml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/pom.xml create mode 100644 components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/src/main/resources/store-api.yaml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/build.properties create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/conf/apim-integration.xml create mode 100644 features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/p2.inf diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java index a69ae339f2..bc75a9febe 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/ApiApplicationRegistrationServiceImpl.java @@ -104,27 +104,11 @@ public class ApiApplicationRegistrationServiceImpl implements ApiApplicationRegi } else { validityPeriod = registrationProfile.getValidityPeriod(); } - if (registrationProfile.isMappingAnExistingOAuthApp()) { - JSONObject jsonStringObject = new JSONObject(); - jsonStringObject.put(ApiApplicationConstants.JSONSTRING_USERNAME_TAG, username); - jsonStringObject.put(ApiApplicationConstants.JSONSTRING_KEY_TYPE_TAG, - ApiApplicationConstants.DEFAULT_TOKEN_TYPE); - jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_ID, registrationProfile.getConsumerKey()); - jsonStringObject.put(ApiApplicationConstants.OAUTH_CLIENT_SECRET, - registrationProfile.getConsumerSecret()); - jsonStringObject.put(ApiApplicationConstants.JSONSTRING_VALIDITY_PERIOD_TAG, validityPeriod); - apiManagementProviderService.registerExistingOAuthApplicationToAPIApplication( - jsonStringObject.toJSONString(), registrationProfile.getApplicationName(), - registrationProfile.getConsumerKey(), username, registrationProfile.isAllowedToAllDomains(), - ApiApplicationConstants.DEFAULT_TOKEN_TYPE, registrationProfile.getTags()); - return Response.status(Response.Status.ACCEPTED).entity("true").build(); - } else { - ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( - registrationProfile.getApplicationName(), registrationProfile.getTags(), - ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, - registrationProfile.isAllowedToAllDomains(), validityPeriod); - return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build(); - } + ApiApplicationKey apiApplicationKey = apiManagementProviderService.generateAndRetrieveApplicationKeys( + registrationProfile.getApplicationName(), registrationProfile.getTags(), + ApiApplicationConstants.DEFAULT_TOKEN_TYPE, username, + registrationProfile.isAllowedToAllDomains(), validityPeriod); + return Response.status(Response.Status.CREATED).entity(apiApplicationKey.toString()).build(); } catch (APIManagerException e) { String msg = "Error occurred while registering an application '" + registrationProfile.getApplicationName() + "'"; diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java index b1634923f3..ef63946fd3 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/src/main/java/org/wso2/carbon/apimgt/application/extension/api/util/RegistrationProfile.java @@ -37,10 +37,6 @@ public class RegistrationProfile { private String tags[]; @XmlElement(required = true) private boolean isAllowedToAllDomains; - @XmlElement(required = true) - private boolean isMappingAnExistingOAuthApp; - private String consumerKey; - private String consumerSecret; @XmlElement(required = false) private String validityPeriod; @@ -68,30 +64,6 @@ public class RegistrationProfile { this.isAllowedToAllDomains = isAllowedToAllDomains; } - public boolean isMappingAnExistingOAuthApp() { - return isMappingAnExistingOAuthApp; - } - - public void setIsMappingAnExistingOAuthApp(boolean isMappingAnExistingOAuthApp) { - this.isMappingAnExistingOAuthApp = isMappingAnExistingOAuthApp; - } - - public String getConsumerKey() { - return consumerKey; - } - - public void setConsumerKey(String consumerKey) { - this.consumerKey = consumerKey; - } - - public String getConsumerSecret() { - return consumerSecret; - } - - public void setConsumerSecret(String consumerSecret) { - this.consumerSecret = consumerSecret; - } - public String getValidityPeriod() { return validityPeriod; } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml index 9d36ef9b70..758d77636e 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml @@ -51,6 +51,10 @@ org.wso2.carbon org.wso2.carbon.logging + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.integration.client + org.wso2.carbon.apimgt org.wso2.carbon.apimgt.impl diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java index 7e04924dc4..8cad8b016f 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderService.java @@ -41,15 +41,7 @@ public interface APIManagementProviderService { */ ApiApplicationKey generateAndRetrieveApplicationKeys(String apiApplicationName, String tags[], String keyType, String username, boolean isAllowedAllDomains, - String validityTime) - throws APIManagerException; - - /** - * Register existing Oauth application as apim application. - */ - void registerExistingOAuthApplicationToAPIApplication(String jsonString, String applicationName, String clientId, - String username, boolean isAllowedAllDomains, String keyType, - String tags[]) throws APIManagerException; + String validityTime) throws APIManagerException; /** * Remove APIM Application. diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementRestProviderServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementRestProviderServiceImpl.java new file mode 100644 index 0000000000..bea5cfcf3f --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementRestProviderServiceImpl.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.application.extension; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants; +import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; +import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; +import org.wso2.carbon.apimgt.application.extension.internal.APIApplicationManagerExtensionDataHolder; +import org.wso2.carbon.apimgt.application.extension.util.APIManagerUtil; +import org.wso2.carbon.apimgt.integration.client.StoreClient; +import org.wso2.carbon.apimgt.store.client.model.APIInfo; +import org.wso2.carbon.apimgt.store.client.model.APIList; +import org.wso2.carbon.apimgt.store.client.model.Application; +import org.wso2.carbon.apimgt.store.client.model.ApplicationInfo; +import org.wso2.carbon.apimgt.store.client.model.ApplicationKey; +import org.wso2.carbon.apimgt.store.client.model.ApplicationKeyGenerateRequest; +import org.wso2.carbon.apimgt.store.client.model.ApplicationList; +import org.wso2.carbon.apimgt.store.client.model.Subscription; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class represents an implementation of APIManagementProviderService. + */ +public class APIManagementRestProviderServiceImpl implements APIManagementProviderService { + + private static final Log log = LogFactory.getLog(APIManagementRestProviderServiceImpl.class); + private static final String CONTENT_TYPE = "application/json"; + private static final int MAX_API_PER_TAG = 200; + + @Override + public void removeAPIApplication(String applicationName, String username) throws APIManagerException { + + StoreClient storeClient = APIApplicationManagerExtensionDataHolder.getInstance().getIntegrationClientService() + .getStoreClient(); + ApplicationList applicationList = storeClient.getApplications() + .applicationsGet("", applicationName, 1, 0, CONTENT_TYPE, null); + if (applicationList.getList() != null && applicationList.getList().size() > 0) { + ApplicationInfo applicationInfo = applicationList.getList().get(0); + storeClient.getIndividualApplication().applicationsApplicationIdDelete(applicationInfo.getApplicationId(), + null, null); + } + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized ApiApplicationKey generateAndRetrieveApplicationKeys(String applicationName, String tags[], + String keyType, String username, + boolean isAllowedAllDomains, String validityTime) + throws APIManagerException { + StoreClient storeClient = APIApplicationManagerExtensionDataHolder.getInstance().getIntegrationClientService() + .getStoreClient(); + ApplicationList applicationList = storeClient.getApplications() + .applicationsGet("", applicationName, 1, 0, CONTENT_TYPE, null); + Application application; + if (applicationList == null || applicationList.getList() == null || applicationList.getList().size() == 0) { + //create application; + application = new Application(); + application.setName(applicationName); + application.setSubscriber(username); + application.setDescription(""); + application.setThrottlingTier(ApiApplicationConstants.DEFAULT_TIER); + application.setGroupId(""); + application = storeClient.getIndividualApplication().applicationsPost(application, CONTENT_TYPE); + } else { + ApplicationInfo applicationInfo = applicationList.getList().get(0); + application = storeClient.getIndividualApplication() + .applicationsApplicationIdGet(applicationInfo.getApplicationId(), CONTENT_TYPE, null, null); + } + if (application == null) { + throw new APIManagerException ( + "Api application creation failed for " + applicationName + " to the user " + username); + } + // subscribe to apis. + if (tags != null && tags.length > 0) { + for (String tag: tags) { + APIList apiList = storeClient.getApis().apisGet(MAX_API_PER_TAG, 0, null, "tag:" + tag, CONTENT_TYPE, null); + if (apiList.getList() != null && apiList.getList().size() == 0) { + apiList = storeClient.getApis().apisGet(MAX_API_PER_TAG, 0 + , MultitenantConstants.SUPER_TENANT_DOMAIN_NAME, "tag:" + tag, CONTENT_TYPE, null); + } + + if (apiList.getList() != null && apiList.getList().size() > 0) { + for (APIInfo apiInfo :apiList.getList()) { + Subscription subscription = new Subscription(); + subscription.setApiIdentifier(apiInfo.getId()); + subscription.setApplicationId(application.getApplicationId()); + subscription.tier(ApiApplicationConstants.DEFAULT_TIER); + storeClient.getIndividualSubscription().subscriptionsPost(subscription, CONTENT_TYPE); + } + + } + } + } + //end of subscription + + List applicationKeys = application.getKeys(); + if (applicationKeys != null) { + for (ApplicationKey applicationKey : applicationKeys) { + if (keyType.equals(applicationKey.getKeyType())) { + ApiApplicationKey apiApplicationKey = new ApiApplicationKey(); + apiApplicationKey.setConsumerKey(applicationKey.getConsumerKey()); + apiApplicationKey.setConsumerSecret(applicationKey.getConsumerSecret()); + return apiApplicationKey; + } + } + } + + ApplicationKeyGenerateRequest applicationKeyGenerateRequest = new ApplicationKeyGenerateRequest(); + List allowedDomains = new ArrayList<>(); + if (isAllowedAllDomains) { + allowedDomains.add(ApiApplicationConstants.ALLOWED_DOMAINS); + } else { + allowedDomains.add(APIManagerUtil.getTenantDomain()); + } + applicationKeyGenerateRequest.setAccessAllowDomains(allowedDomains); + applicationKeyGenerateRequest.setCallbackUrl(""); + applicationKeyGenerateRequest.setKeyType(ApplicationKeyGenerateRequest.KeyTypeEnum.PRODUCTION); + applicationKeyGenerateRequest.setValidityTime(validityTime); + + ApplicationKey applicationKey = storeClient.getIndividualApplication().applicationsGenerateKeysPost( + application.getApplicationId(), applicationKeyGenerateRequest, CONTENT_TYPE, null, null); + ApiApplicationKey apiApplicationKey = new ApiApplicationKey(); + apiApplicationKey.setConsumerKey(applicationKey.getConsumerKey()); + apiApplicationKey.setConsumerSecret(applicationKey.getConsumerSecret()); + return apiApplicationKey; + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java index 6beb0bbb62..cf7cbadea4 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionDataHolder.java @@ -18,6 +18,7 @@ package org.wso2.carbon.apimgt.application.extension.internal; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; +import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.user.core.service.RealmService; @@ -30,6 +31,7 @@ public class APIApplicationManagerExtensionDataHolder { private TenantManager tenantManager; private TenantRegistryLoader tenantRegistryLoader; private TenantIndexingLoader indexLoader; + private IntegrationClientService integrationClientService; private APIApplicationManagerExtensionDataHolder() { } @@ -86,4 +88,13 @@ public class APIApplicationManagerExtensionDataHolder { public TenantIndexingLoader getIndexLoaderService(){ return indexLoader; } + + public IntegrationClientService getIntegrationClientService() { + return integrationClientService; + } + + public void setIntegrationClientService( + IntegrationClientService integrationClientService) { + this.integrationClientService = integrationClientService; + } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java index 27104c13bd..079b119c65 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/internal/APIApplicationManagerExtensionServiceComponent.java @@ -23,6 +23,8 @@ import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext;; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderServiceImpl; +import org.wso2.carbon.apimgt.application.extension.APIManagementRestProviderServiceImpl; +import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; import org.wso2.carbon.registry.core.service.TenantRegistryLoader; import org.wso2.carbon.registry.indexing.service.TenantIndexingLoader; import org.wso2.carbon.user.core.service.RealmService; @@ -48,6 +50,11 @@ import org.wso2.carbon.user.core.service.RealmService; * policy="dynamic" * bind="setRealmService" * unbind="unsetRealmService" + * interface="org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService" + * cardinality="1..1" + * policy="dynamic" + * bind="setIntegrationClientService" + * unbind="unsetIntegrationClientService" */ public class APIApplicationManagerExtensionServiceComponent { @@ -57,7 +64,7 @@ public class APIApplicationManagerExtensionServiceComponent { if (log.isDebugEnabled()) { log.debug("Initializing device extension bundle"); } - APIManagementProviderService apiManagementProviderService = new APIManagementProviderServiceImpl(); + APIManagementProviderService apiManagementProviderService = new APIManagementRestProviderServiceImpl(); APIApplicationManagerExtensionDataHolder.getInstance().setAPIManagementProviderService(apiManagementProviderService); BundleContext bundleContext = componentContext.getBundleContext(); bundleContext.registerService(APIManagementProviderService.class.getName(), apiManagementProviderService, null); @@ -86,6 +93,17 @@ public class APIApplicationManagerExtensionServiceComponent { APIApplicationManagerExtensionDataHolder.getInstance().setIndexLoaderService(null); } + protected void setIntegrationClientService(IntegrationClientService integrationClientService) { + if (integrationClientService != null && log.isDebugEnabled()) { + log.debug("integrationClientService initialized"); + } + APIApplicationManagerExtensionDataHolder.getInstance().setIntegrationClientService(integrationClientService); + } + + protected void unsetIntegrationClientService(IntegrationClientService integrationClientService) { + APIApplicationManagerExtensionDataHolder.getInstance().setIntegrationClientService(null); + } + /** * Sets Realm Service. * diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml new file mode 100644 index 0000000000..4efa8dfc22 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml @@ -0,0 +1,159 @@ + + + + + + apimgt-extensions + org.wso2.carbon.devicemgt + 2.0.8-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.apimgt.integration.client + 2.0.8-SNAPSHOT + bundle + WSO2 Carbon - API Management Integration Client + WSO2 Carbon - API Management Integration Client + http://wso2.org + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + 1.4.0 + true + + + ${project.artifactId} + ${project.artifactId} + ${project.version} + APIM Integration + org.wso2.carbon.apimgt.integration.client.internal + + org.wso2.carbon.apimgt.integration.client.*, + !org.wso2.carbon.apimgt.integration.client.internal + + + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.logging, + io.swagger, + junit, + feign, + feign.jackson, + feign.codec, + com.google.gson, + feign.auth, + feign.gson, + feign.slf4j, + feign.jaxrs, + com.fasterxml.jackson.core, + org.wso2.carbon.apimgt.publisher.client.*, + org.wso2.carbon.apimgt.store.client.*, + + + javax.ws.rs-api + + + + + + + + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + + com.google.code.gson + gson + + + javax.ws.rs + jsr311-api + + + + io.swagger + swagger-annotations + + + junit + junit + + + io.github.openfeign + feign-core + + + io.github.openfeign + feign-jaxrs + + + io.github.openfeign + feign-jackson + + + io.github.openfeign + feign-gson + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + + + + org.testng + testng + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.publisher.client + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.store.client + + + org.wso2.carbon.devicemgt + org.wso2.carbon.identity.jwt.client.extension + + + javax.ws.rs + jsr311-api + + + + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/IntegrationClientServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/IntegrationClientServiceImpl.java new file mode 100644 index 0000000000..b2c997e57a --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/IntegrationClientServiceImpl.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client; + +import feign.RequestInterceptor; +import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; + +public class IntegrationClientServiceImpl implements IntegrationClientService { + + private static StoreClient storeClient; + private static PublisherClient publisherClient; + + public IntegrationClientServiceImpl() { + RequestInterceptor oAuthRequestInterceptor = new OAuthRequestInterceptor(); + storeClient = new StoreClient(oAuthRequestInterceptor); + publisherClient = new PublisherClient(oAuthRequestInterceptor); + } + @Override + public StoreClient getStoreClient() { + return storeClient; + } + + @Override + public PublisherClient getPublisherClient() { + return publisherClient; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java new file mode 100755 index 0000000000..1c421c46f1 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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 org.wso2.carbon.apimgt.integration.client; + +import feign.Feign; +import feign.RequestInterceptor; +import feign.RequestTemplate; +import feign.auth.BasicAuthRequestInterceptor; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.jaxrs.JAXRSContract; +import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; +import org.wso2.carbon.apimgt.integration.client.exception.APIMClientOAuthException; +import org.wso2.carbon.apimgt.integration.client.internal.APIIntegrationClientDataHolder; +import org.wso2.carbon.apimgt.integration.client.model.ClientProfile; +import org.wso2.carbon.apimgt.integration.client.model.DCRClient; +import org.wso2.carbon.apimgt.integration.client.model.OAuthApplication; +import org.wso2.carbon.apimgt.integration.client.util.PropertyUtils; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.identity.jwt.client.extension.JWTClient; +import org.wso2.carbon.identity.jwt.client.extension.dto.AccessTokenInfo; +import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientException; +import org.wso2.carbon.user.api.UserStoreException; + +import java.util.HashMap; +import java.util.Map; + +/** + * This is a request interceptor to add oauth token header. + */ +public class OAuthRequestInterceptor implements RequestInterceptor { + + private static final String APPLICATION_NAME = "api_integration_client"; + private static final String GRANT_TYPES = "password refresh_token urn:ietf:params:oauth:grant-type:jwt-bearer"; + private static final String REQUIRED_SCOPE = + "apim:api_create apim:api_view apim:api_publish apim:subscribe apim:tier_view apim:tier_manage " + + "apim:subscription_view apim:subscription_block"; + private static final long DEFAULT_REFRESH_TIME_OFFSET_IN_MILLIS = 100000; + private DCRClient dcrClient; + private static OAuthApplication oAuthApplication; + private static Map tenantTokenMap = new HashMap<>(); + + /** + * Creates an interceptor that authenticates all requests. + */ + public OAuthRequestInterceptor() { + String username = APIMConfigReader.getInstance().getConfig().getUsername(); + String password = APIMConfigReader.getInstance().getConfig().getPassword(); + dcrClient = Feign.builder().requestInterceptor( + new BasicAuthRequestInterceptor(username, password)) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) + .target(DCRClient.class, PropertyUtils.replaceProperties( + APIMConfigReader.getInstance().getConfig().getDcrEndpoint())); + } + + @Override + public void apply(RequestTemplate template) { + if (oAuthApplication == null) { + //had to do on demand initialization due to start up error. + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setClientName(APPLICATION_NAME); + clientProfile.setCallbackUrl(""); + clientProfile.setGrantType(GRANT_TYPES); + clientProfile.setOwner(APIMConfigReader.getInstance().getConfig().getUsername()); + clientProfile.setSaasApp(true); + oAuthApplication = dcrClient.register(clientProfile); + } + String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + AccessTokenInfo tenantBasedAccessTokenInfo = tenantTokenMap.get(tenantDomain); + + if ((tenantBasedAccessTokenInfo == null || + ((System.currentTimeMillis() + DEFAULT_REFRESH_TIME_OFFSET_IN_MILLIS) > + tenantBasedAccessTokenInfo.getExpiresIn()))) { + try { + JWTClient jwtClient = APIIntegrationClientDataHolder.getInstance().getJwtClientManagerService() + .getJWTClient(); + String username = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm() + .getRealmConfiguration().getAdminUserName() + "@" + tenantDomain; + + tenantBasedAccessTokenInfo = jwtClient.getAccessToken(oAuthApplication.getClientId(), + oAuthApplication.getClientSecret(), username, + REQUIRED_SCOPE); + tenantBasedAccessTokenInfo.setExpiresIn( + System.currentTimeMillis() + (tenantBasedAccessTokenInfo.getExpiresIn() * 1000)); + tenantTokenMap.put(tenantDomain, tenantBasedAccessTokenInfo); + } catch (JWTClientException e) { + throw new APIMClientOAuthException("failed to retrieve oauth token using jwt", e); + } catch (UserStoreException e) { + throw new APIMClientOAuthException("failed to retrieve tenant admin username", e); + } + + } + if (tenantBasedAccessTokenInfo.getAccessToken() != null) { + String headerValue = "Bearer " + tenantBasedAccessTokenInfo.getAccessToken(); + template.header("Authorization", headerValue); + } + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/PublisherClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/PublisherClient.java new file mode 100644 index 0000000000..5754f07edd --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/PublisherClient.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.integration.client; + +import feign.Feign; +import feign.RequestInterceptor; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.jaxrs.JAXRSContract; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; +import org.wso2.carbon.apimgt.publisher.client.api.APIDocumentApi; +import org.wso2.carbon.apimgt.publisher.client.api.APIsApi; +import org.wso2.carbon.apimgt.publisher.client.api.ApplicationsApi; +import org.wso2.carbon.apimgt.publisher.client.api.EnvironmentsApi; +import org.wso2.carbon.apimgt.publisher.client.api.SubscriptionsApi; +import org.wso2.carbon.apimgt.publisher.client.api.TiersApi; +import org.wso2.carbon.apimgt.publisher.client.invoker.ApiClient; + +/** + * Publisher client generated using swagger. + */ +public class PublisherClient { + + private static final org.apache.commons.logging.Log log = LogFactory.getLog(PublisherClient.class); + private APIsApi api = null; + private APIDocumentApi document = null; + private ApplicationsApi application = null; + private EnvironmentsApi environments = null; + private SubscriptionsApi subscriptions = null; + private TiersApi tiers = null; + + + /** + * PublisherClient constructor - Initialize a PublisherClient instance + * + */ + public PublisherClient(RequestInterceptor requestInterceptor) { + Feign.Builder builder = Feign.builder().requestInterceptor(requestInterceptor) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()); + + ApiClient client = new ApiClient(); + client.setBasePath(APIMConfigReader.getInstance().getConfig().getPublisherEndpoint()); + client.setFeignBuilder(builder); + + api = client.buildClient(APIsApi.class); + document = client.buildClient(APIDocumentApi.class); + application = client.buildClient(ApplicationsApi.class); + environments = client.buildClient(EnvironmentsApi.class); + subscriptions = client.buildClient(SubscriptionsApi.class); + tiers = client.buildClient(TiersApi.class); + } + + public APIsApi getApi() { + return api; + } + + public APIDocumentApi getDocument() { + return document; + } + + public ApplicationsApi getApplication() { + return application; + } + + public EnvironmentsApi getEnvironments() { + return environments; + } + + public SubscriptionsApi getSubscriptions() { + return subscriptions; + } + + public TiersApi getTiers() { + return tiers; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/StoreClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/StoreClient.java new file mode 100644 index 0000000000..f7957ea147 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/StoreClient.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.integration.client; + +import feign.Feign; +import feign.RequestInterceptor; +import feign.gson.GsonDecoder; +import feign.gson.GsonEncoder; +import feign.jaxrs.JAXRSContract; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; +import org.wso2.carbon.apimgt.store.client.api.*; +import org.wso2.carbon.apimgt.store.client.invoker.ApiClient; + +/** + * API Store client, created using swagger gen. + */ +public class StoreClient { + + private static final org.apache.commons.logging.Log log = LogFactory.getLog(StoreClient.class); + private ApisAPIApi apis = null; + private APIindividualApi individualApi = null; + private ApplicationCollectionApi applications = null; + private ApplicationindividualApi individualApplication = null; + private SubscriptionCollectionApi subscriptions = null; + private SubscriptionindividualApi individualSubscription = null; + private TierindividualApi individualTier = null; + private TagCollectionApi tags = null; + private TierCollectionApi tiers = null; + + + public StoreClient(RequestInterceptor requestInterceptor) { + + Feign.Builder builder = Feign.builder().requestInterceptor(requestInterceptor) + .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()); + + ApiClient client = new ApiClient(); + client.setBasePath(APIMConfigReader.getInstance().getConfig().getStoreEndpoint()); + client.setFeignBuilder(builder); + + apis = client.buildClient(ApisAPIApi.class); + individualApi = client.buildClient(APIindividualApi.class); + applications = client.buildClient(ApplicationCollectionApi.class); + individualApplication = client.buildClient(ApplicationindividualApi.class); + subscriptions = client.buildClient(SubscriptionCollectionApi.class); + individualSubscription = client.buildClient(SubscriptionindividualApi.class); + tags = client.buildClient(TagCollectionApi.class); + tiers = client.buildClient(TierCollectionApi.class); + individualTier = client.buildClient(TierindividualApi.class); + + } + + public ApisAPIApi getApis() { + return apis; + } + + public APIindividualApi getIndividualApi() { + return individualApi; + } + + public ApplicationCollectionApi getApplications() { + return applications; + } + + public ApplicationindividualApi getIndividualApplication() { + return individualApplication; + } + + public SubscriptionCollectionApi getSubscriptions() { + return subscriptions; + } + + public SubscriptionindividualApi getIndividualSubscription() { + return individualSubscription; + } + + public TierindividualApi getIndividualTier() { + return individualTier; + } + + public TagCollectionApi getTags() { + return tags; + } + + public TierCollectionApi getTiers() { + return tiers; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfig.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfig.java new file mode 100644 index 0000000000..1e3d34c746 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfig.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.configs; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * This holds the configuration api manager integration. + */ +@XmlRootElement(name = "APIMConfiguration") +public class APIMConfig { + + String dcrEndpoint; + String tokenEndpoint; + String publisherEndpoint; + String storeEndpoint; + String username; + String password; + + @XmlElement(name = "DCREndpoint", required = true) + public String getDcrEndpoint() { + return dcrEndpoint; + } + + public void setDcrEndpoint(String dcrEndpoint) { + this.dcrEndpoint = dcrEndpoint; + } + + @XmlElement(name = "TokenEndpoint", required = true) + public String getTokenEndpoint() { + return tokenEndpoint; + } + + public void setTokenEndpoint(String tokenEndpoint) { + this.tokenEndpoint = tokenEndpoint; + } + + @XmlElement(name = "PublisherEndpoint", required = true) + public String getPublisherEndpoint() { + return publisherEndpoint; + } + + public void setPublisherEndpoint(String publisherEndpoint) { + this.publisherEndpoint = publisherEndpoint; + } + + @XmlElement(name = "StoreEndpoint", required = true) + public String getStoreEndpoint() { + return storeEndpoint; + } + + public void setStoreEndpoint(String storeEndpoint) { + this.storeEndpoint = storeEndpoint; + } + + @XmlElement(name = "Username", required = true) + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @XmlElement(name = "Password", required = true) + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfigReader.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfigReader.java new file mode 100644 index 0000000000..8655a4d6a2 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/configs/APIMConfigReader.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.configs; + +import org.w3c.dom.Document; +import org.wso2.carbon.apimgt.integration.client.exception.APIMClientException; +import org.wso2.carbon.apimgt.integration.client.exception.InvalidConfigurationStateException; +import org.wso2.carbon.utils.CarbonUtils; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; + +/** + * This holds the configuration parser for api integration.xml + */ +public class APIMConfigReader { + + private static APIMConfig config; + private static APIMConfigReader configReader= new APIMConfigReader(); + private static boolean isInitialized = false; + private static final String API_INTEGRATION_CONFIG_PATH = + CarbonUtils.getCarbonConfigDirPath() + File.separator + "apim-integration.xml"; + + private APIMConfigReader() { + + } + + private static String apimIntegrationXmlFilePath = ""; + + //TOD file may be a part of another file + public static APIMConfigReader getInstance() { + if (!isInitialized) { + try { + init(); + } catch (APIMClientException e) { + throw new InvalidConfigurationStateException("Webapp Authenticator Configuration is not " + + "initialized properly"); + } + } + return configReader; + } + + public static void init() throws APIMClientException { + try { + File apimConfigFile = new File(API_INTEGRATION_CONFIG_PATH); + Document doc = convertToDocument(apimConfigFile); + + JAXBContext ctx = JAXBContext.newInstance(APIMConfig.class); + Unmarshaller unmarshaller = ctx.createUnmarshaller(); + config = (APIMConfig) unmarshaller.unmarshal(doc); + isInitialized = true; + } catch (JAXBException e) { + throw new APIMClientException("Error occurred while un-marshalling APIMConfig", e); + } + } + + private static Document convertToDocument(File file) throws APIMClientException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + try { + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + DocumentBuilder docBuilder = factory.newDocumentBuilder(); + return docBuilder.parse(file); + } catch (Exception e) { + throw new APIMClientException("Error occurred while parsing file 'apim-integration.xml' to a org.w3c.dom.Document", e); + } + } + + public APIMConfig getConfig() { + return config; + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientException.java new file mode 100644 index 0000000000..f893f6d276 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientException.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.exception; + +/** + * This holds api client exception. + */ +public class APIMClientException extends Exception { + + private static final long serialVersionUID = -3976392476319079281L; + private String responseReason; + private int responseStatus; + private String methodKey; + + APIMClientException(String methodKey, String reason, int status) { + super("Exception occured while invoking " + methodKey + " status = " + status + " reason = " + reason); + this.methodKey = methodKey; + this.responseReason = reason; + this.responseStatus = status; + } + + APIMClientException(String message) { + super(message); + } + + public APIMClientException(String message, Exception e) { + super(message, e); + } + + public String getResponseReason() { + return responseReason; + } + + public int getResponseStatus() { + return responseStatus; + } + + public String getMethodKey() { + return methodKey; + } + +} \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientOAuthException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientOAuthException.java new file mode 100644 index 0000000000..48f92d5abd --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/APIMClientOAuthException.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.exception; + +/** + * This holds api client exception. + */ +public class APIMClientOAuthException extends RuntimeException { + + private static final long serialVersionUID = -3976392476319079281L; + private String responseReason; + private int responseStatus; + private String methodKey; + + APIMClientOAuthException(String methodKey, String reason, int status) { + super("Exception occured while invoking " + methodKey + " status = " + status + " reason = " + reason); + this.methodKey = methodKey; + this.responseReason = reason; + this.responseStatus = status; + } + + APIMClientOAuthException(String message) { + super(message); + } + + public APIMClientOAuthException(String message, Exception e) { + super(message, e); + } + + public String getResponseReason() { + return responseReason; + } + + public int getResponseStatus() { + return responseStatus; + } + + public String getMethodKey() { + return methodKey; + } + +} \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/InvalidConfigurationStateException.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/InvalidConfigurationStateException.java new file mode 100644 index 0000000000..dedb63c4bd --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/exception/InvalidConfigurationStateException.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.carbon.apimgt.integration.client.exception; + +/** + * This error is thrown when there is an issue with the client. + */ +public class InvalidConfigurationStateException extends RuntimeException { + + private static final long serialVersionUID = -3151279311329070397L; + + private String errorMessage; + private int errorCode; + + public InvalidConfigurationStateException(int errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + + public InvalidConfigurationStateException(int errorCode, String message, Throwable cause) { + super(message, cause); + this.errorCode = errorCode; + } + + public int getErrorCode() { + return errorCode; + } + + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public InvalidConfigurationStateException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public InvalidConfigurationStateException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public InvalidConfigurationStateException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public InvalidConfigurationStateException() { + super(); + } + + public InvalidConfigurationStateException(Throwable cause) { + super(cause); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientDataHolder.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientDataHolder.java new file mode 100644 index 0000000000..a53572cf25 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientDataHolder.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.apimgt.integration.client.internal; + + +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +/** + * This holds the required service for this component + */ +public class APIIntegrationClientDataHolder { + private static APIIntegrationClientDataHolder thisInstance = new APIIntegrationClientDataHolder(); + private JWTClientManagerService jwtClientManagerService; + private APIIntegrationClientDataHolder() { + } + + + public static APIIntegrationClientDataHolder getInstance() { + return thisInstance; + } + + public void setJwtClientManagerService(JWTClientManagerService jwtClientManagerService) { + this.jwtClientManagerService = jwtClientManagerService; + } + + public JWTClientManagerService getJwtClientManagerService() { + return jwtClientManagerService; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientServiceComponent.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientServiceComponent.java new file mode 100644 index 0000000000..aaf178b718 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/internal/APIIntegrationClientServiceComponent.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.wso2.carbon.apimgt.integration.client.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.apimgt.integration.client.IntegrationClientServiceImpl; +import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; +import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; +import org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService; + +/** + * @scr.component name="org.wso2.carbon.api.integration.client" immediate="true" + * @scr.reference name="api.integration.client.service" + * interface="org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService" + * cardinality="1..1" + * policy="dynamic" + * bind="setJWTClientManagerService" + * unbind="unsetJWTClientManagerService" + */ +public class APIIntegrationClientServiceComponent { + + private static Log log = LogFactory.getLog(APIIntegrationClientServiceComponent.class); + + protected void activate(ComponentContext componentContext) { + try { + if (log.isDebugEnabled()) { + log.debug("Initializing apimgt client bundle"); + } + + /* Initializing webapp publisher configuration */ + APIMConfigReader.init(); + BundleContext bundleContext = componentContext.getBundleContext(); + bundleContext.registerService(IntegrationClientService.class.getName(), new IntegrationClientServiceImpl(), null); + + if (log.isDebugEnabled()) { + log.debug("apimgt client bundle has been successfully initialized"); + } + } catch (Throwable e) { + log.error("Error occurred while initializing apimgt client bundle", e); + } + } + + protected void deactivate(ComponentContext componentContext) { + //do nothing + } + + protected void setJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + if (jwtClientManagerService != null) { + log.debug("jwtClientManagerService service is initialized"); + } + APIIntegrationClientDataHolder.getInstance().setJwtClientManagerService(jwtClientManagerService); + } + + protected void unsetJWTClientManagerService(JWTClientManagerService jwtClientManagerService) { + APIIntegrationClientDataHolder.getInstance().setJwtClientManagerService(null); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/ClientProfile.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/ClientProfile.java new file mode 100644 index 0000000000..fe1821d3a4 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/ClientProfile.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.model; + +/** + * DTO fo DCR request. + */ +public class ClientProfile { + + private String clientName; + private String callbackUrl; + private String tokenScope; + private String owner; + private String grantType; + private boolean saasApp; + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + + public String getTokenScope() { + return tokenScope; + } + + public void setTokenScope(String tokenScope) { + this.tokenScope = tokenScope; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getGrantType() { + return grantType; + } + + public void setGrantType(String grantTypem) { + this.grantType = grantTypem; + } + + public boolean isSaasApp() { + return saasApp; + } + + public void setSaasApp(boolean saasApp) { + this.saasApp = saasApp; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{\n"); + + sb.append(" clientName: ").append(clientName).append("\n"); + sb.append(" callbackUrl: ").append("callbackUrl").append("\n"); + sb.append(" grantType: ").append(grantType).append("\n"); + sb.append(" tokenScope: ").append(tokenScope).append("\n"); + sb.append(" owner: ").append(owner).append("\n"); + sb.append(" saasApp: ").append(saasApp).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/DCRClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/DCRClient.java new file mode 100644 index 0000000000..2adcfa45ad --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/DCRClient.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.model; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +/** + * DCR Rest resource. + */ +@Path("/") +public interface DCRClient { + + // DCR APIs + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + OAuthApplication register(ClientProfile registrationProfile); + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/OAuthApplication.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/OAuthApplication.java new file mode 100644 index 0000000000..7f3bf458f4 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/model/OAuthApplication.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.apimgt.integration.client.model; + +public class OAuthApplication { + + private String jsonString; + private String appOwner; + private String clientName; + private String callBackURL; + private String isSaasApplication; + private String clientId; + private String clientSecret; + + public String getJsonString() { + return jsonString; + } + + public void setJsonString(String jsonString) { + this.jsonString = jsonString; + } + + public String getAppOwner() { + return appOwner; + } + + public void setAppOwner(String appOwner) { + this.appOwner = appOwner; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public String getCallBackURL() { + return callBackURL; + } + + public void setCallBackURL(String callBackURL) { + this.callBackURL = callBackURL; + } + + public String getIsSaasApplication() { + return isSaasApplication; + } + + public void setIsSaasApplication(String isSaasApplication) { + this.isSaasApplication = isSaasApplication; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class OAuthApplication {\n"); + + sb.append(" jsonString: ").append(jsonString).append("\n"); + sb.append(" appOwner: ").append(appOwner).append("\n"); + sb.append(" clientName: ").append(clientName).append("\n"); + sb.append(" callBackURL: ").append(callBackURL).append("\n"); + sb.append(" isSaasApplication: ").append(isSaasApplication).append("\n"); + sb.append(" clientId: ").append(isSaasApplication).append("\n"); + sb.append(" clientSecret: ").append(clientSecret).append("\n"); + sb.append("}\n"); + return sb.toString(); + } + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/service/IntegrationClientService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/service/IntegrationClientService.java new file mode 100644 index 0000000000..922aec75c3 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/service/IntegrationClientService.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.wso2.carbon.apimgt.integration.client.service; + + +import org.wso2.carbon.apimgt.integration.client.PublisherClient; +import org.wso2.carbon.apimgt.integration.client.StoreClient; + +/** + * This is a service that can be called upon to access store and publisher. + */ +public interface IntegrationClientService { + + /** + * + * @return API Store Client. + */ + StoreClient getStoreClient(); + + /** + * + * @return API Publisher Client. + */ + PublisherClient getPublisherClient(); + +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/PropertyUtils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/PropertyUtils.java new file mode 100644 index 0000000000..83d162fdb4 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/PropertyUtils.java @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +package org.wso2.carbon.apimgt.integration.client.util; + + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PropertyUtils { + + //This method is only used if the mb features are within DAS. + public static String replaceProperties(String text) { + String regex = "\\$\\{(.*?)\\}"; + Pattern pattern = Pattern.compile(regex); + Matcher matchPattern = pattern.matcher(text); + while (matchPattern.find()) { + String sysPropertyName = matchPattern.group(1); + String sysPropertyValue = System.getProperty(sysPropertyName); + if (sysPropertyValue != null && !sysPropertyName.isEmpty()) { + text = text.replaceAll("\\$\\{(" + sysPropertyName + ")\\}", sysPropertyValue); + } + } + return text; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/pom.xml new file mode 100644 index 0000000000..682bb05aeb --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/pom.xml @@ -0,0 +1,173 @@ + + + + + + apimgt-extensions + org.wso2.carbon.devicemgt + 2.0.8-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.apimgt.publisher.client + bundle + org.wso2.carbon.apimgt.publisher.client + + + + + io.swagger + swagger-codegen-maven-plugin + + + + generate + + + ${project.basedir}/src/main/resources/publisher-api.yaml + java + + ${project.artifactId}.api + ${project.artifactId}.model + ${project.artifactId}.invoker + + feign + + + + + + maven-antrun-plugin + + + copy + process-resources + + + + + + + + + + + + + + run + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${project.version} + APIM publisher client + + org.wso2.carbon.apimgt.publisher.client.model, + org.wso2.carbon.apimgt.publisher.client.api, + org.wso2.carbon.apimgt.publisher.client.invoker + + + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.logging, + io.swagger, + junit, + javax.ws.rs, + feign, + feign.jackson, + feign.codec, + feign.auth, + feign.gson, + feign.slf4j, + com.google.gson, + com.fasterxml.jackson.core, + com.fasterxml.jackson.annotation, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.datatype.joda, i + o.swagger.annotations, + javax.net.ssl, + org.apache.oltu.oauth2.client.*, + org.apache.oltu.oauth2.common.*, + org.junit;resolution:=optional + + + + + + + + + + + + + + io.swagger + swagger-annotations + + + junit + junit + + + io.github.openfeign + feign-core + + + io.github.openfeign + feign-jaxrs + + + io.github.openfeign + feign-gson + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + + + org.wso2.orbit.joda-time + joda-time + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + + + io.github.openfeign + feign-jackson + + + io.github.openfeign + feign-slf4j + + + + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/src/main/resources/publisher-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/src/main/resources/publisher-api.yaml new file mode 100644 index 0000000000..665d73ea53 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.publisher.client/src/main/resources/publisher-api.yaml @@ -0,0 +1,2747 @@ +swagger: '2.0' +###################################################### +# Prolog +###################################################### +info: + version: "0.10.0" + title: "WSO2 API Manager - Publisher API" + description: | + This document specifies a **RESTful API** for WSO2 **API Manager** - Publisher. + + It is written with [swagger 2](http://swagger.io/). + + contact: + name: "WSO2" + url: "http://wso2.com/products/api-manager/" + email: "architecture@wso2.com" + license: + name: "Apache 2.0" + url: "http://www.apache.org/licenses/LICENSE-2.0.html" + +###################################################### +# The fixed parts of the URLs of the API +###################################################### + +# The schemes supported by the API +schemes: + - https + +# The domain of the API. +# This is configured by the customer during deployment. +# The given host is just an example. +host: apis.wso2.com + +# The base path of the API. +# Will be prefixed to all paths. +basePath: /api/am/publisher/v0.10 + +# The following media types can be passed as input in message bodies of the API. +# The actual media type must be specified in the Content-Type header field of the request. +# The default is json, i.e. the Content-Type header is not needed to +# be set, but supporting it serves extensibility. +consumes: + - application/json + +# The following media types may be passed as output in message bodies of the API. +# The media type(s) consumable by the requestor is specified in the Accept header field +# of the corresponding request. +# The actual media type returned will be specfied in the Content-Type header field +# of the of the response. +# The default of the Accept header is json, i.e. there is not needed to +# set the value, but supporting it serves extensibility. +produces: + - application/json + + +x-wso2-security: + apim: + x-wso2-scopes: + - description: "" + roles: admin + name: apim:api_view + key: apim:api_view + - description: "" + roles: admin + name: apim:api_create + key: apim:api_create + - description: "" + roles: admin + name: apim:api_publish + key: apim:api_publish + - description: "" + roles: admin + name: apim:tier_view + key: apim:tier_view + - description: "" + roles: admin + name: apim:tier_manage + key: apim:tier_manage + - description: "" + roles: admin + name: apim:subscription_view + key: apim:subscription_view + - description: "" + roles: admin + name: apim:subscription_block + key: apim:subscription_block + +###################################################### +# The "API Collection" resource APIs +###################################################### +paths: + /apis: + +#----------------------------------------------------- +# Retrieving the list of all APIs qualifying under a given search condition +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"This sample API provides Account Status Validation\",\n \"name\": \"AccountVal\",\n \"context\": \"/account\",\n \"id\": \"2e81f147-c8a8-4f68-b4f0-69e0e7510b01\",\n \"status\": \"PUBLISHED\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": null,\n \"name\": \"api1\",\n \"context\": \"/api1\",\n \"id\": \"3e22d2fb-277a-4e9e-8c7e-1c0f7f73960e\",\n \"status\": \"PUBLISHED\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" + summary: | + Get all APIs + description: | + Get a list of available APIs qualifying under a given search condition. + parameters: + - $ref : '#/parameters/limit' + - $ref : '#/parameters/offset' + - name : query + in: query + description: | + **Search condition**. + + You can search in attributes by using an **"attribute:"** modifier. + + Eg. "provider:wso2" will match an API if the provider of the API contains "wso2". + + Supported attribute modifiers are [**version, context, status, + description, subcontext, doc, provider**] + + If no advanced attribute modifier has been specified, search will match the + given query string against API Name. + type: string + - $ref : "#/parameters/Accept" + - $ref : "#/parameters/If-None-Match" + tags: + - APIs + responses: + 200: + description: | + OK. + List of qualifying APIs is returned. + schema: + $ref: '#/definitions/APIList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Create a new API +#----------------------------------------------------- + post: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer 40e486e50ce43407181fb4c570d2cac7\" -H \"Content-Type: application/json\" -X POST -d @data.json http://127.0.0.1:9763/api/am/publisher/v0.10/apis" + x-wso2-request: "{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b\nContent-Type: application/json\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"890a4f4d-09eb-4877-a323-57f6ce2ed79b\",\n \"status\": \"CREATED\"\n}" + summary: Create a new API + description: | + Create a new API + parameters: + - in: body + name: body + description: | + API object that needs to be added + required: true + schema: + $ref: '#/definitions/API' + - $ref: '#/parameters/Content-Type' + tags: + - APIs + responses: + 201: + description: | + Created. + Successful response with the newly created object as entity in the body. + Location header contains URL of newly created entity. + schema: + $ref: '#/definitions/API' + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 415: + description: | + Unsupported Media Type. + The entity of the request was in a not supported format. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual API" resource APIs +###################################################### + /apis/{apiId}: + +#----------------------------------------------------- +# Retrieve the details of an API definition +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b" + x-wso2-response: "HTTP/1.1 200 OK\nDate: Mon, 22 Feb 2016 13:27:08 GMT\nContent-Type: application/json\nTransfer-Encoding: chunked\nServer: WSO2 Carbon Server\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"890a4f4d-09eb-4877-a323-57f6ce2ed79b\",\n \"status\": \"PUBLISHED\"\n}" + summary: Get API details + description: | + Get details of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Requested API is returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + schema: + $ref: '#/definitions/API' + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update the definition of an API +#----------------------------------------------------- + put: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d @data.json http://127.0.0.1:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060" + x-wso2-request: "{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"verification\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Use this API to verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" + x-wso2-response: "HTTP/1.1 200 OK\nDate: Mon, 22 Feb 2016 13:31:35 GMT\nContent-Type: application/json\nTransfer-Encoding: chunked\nServer: WSO2 Carbon Server\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"verification\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Use this API to verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" + summary: Update an existing API + description: | + Update an existing API + parameters: + - $ref: '#/parameters/apiId' + - in: body + name: body + description: | + API object that needs to be added + required: true + schema: + $ref: '#/definitions/API' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Successful response with updated API object + schema: + $ref: '#/definitions/API' + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete the definition of an API +#----------------------------------------------------- + delete: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X DELETE http://127.0.0.1:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Delete API + description: | + Delete an existing API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Resource successfully deleted. + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +################################################################ +# The swagger resource of "Individual API" resource APIs +################################################################ + + /apis/{apiId}/swagger: +#----------------------------------------------------- +# Retrieve the API swagger definition +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\nContent-Length: 329\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" + summary: Get API Definition + description: | + Get the swagger of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Requested swagger document of the API is returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update the API swagger definition +#----------------------------------------------------- + put: + consumes: + - multipart/form-data + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -F apiDefinition=\"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\" -X PUT \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger\"" + x-wso2-request: "{\n \"paths\": {\n \"\\/*\": {\n \"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\n \"200\": {\n \"description\": \"OK\"\n }\n }\n }\n }\n },\n \"x-wso2-security\": {\n \"apim\": {\n \"x-wso2-scopes\": []\n }\n },\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" + summary: Update API Definition + description: | + Update an existing swagger definition of an API + parameters: + - $ref: '#/parameters/apiId' + - in: formData + name: apiDefinition + description: Swagger definition of the API + type: string + required: true + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Successful response with updated Swagger definition + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +################################################################ +# The thumbnail resource of "Individual API" resource APIs +################################################################ + + /apis/{apiId}/thumbnail: +#------------------------------------------------------------------------------------------------- +# Downloads a thumbnail image of an API +#------------------------------------------------------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail > image.jpg" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\n\r\n[image content]" + summary: Get the thumbnail image + description: | + Downloads a thumbnail image of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Thumbnail image returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#---------------------------------------------------------------------------- +# Upload a thumbnail image to a certain API +#---------------------------------------------------------------------------- + post: + consumes: + - multipart/form-data + x-scope: apim:api_create + x-wso2-curl: "curl -X POST -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail -F file=@image.jpg" + x-wso2-response: "HTTP/1.1 201 Created\r\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail\r\nContent-Type: application/json\r\n\r\n{\r\n \"relativePath\": \"/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail\",\r\n \"mediaType\": \"image/jpeg\"\r\n}" + summary: Upload a thumbnail image + description: | + Upload a thumbnail image to an API. + parameters: + - $ref: '#/parameters/apiId' + - in: formData + name: file + description: Image to upload + type: file + required: true + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Image updated + schema: + $ref : '#/definitions/FileInfo' + headers: + Location: + description: | + The URL of the uploaded thumbnail image of the API. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Copy API" Processing Function resource API +###################################################### + /apis/copy-api: + +#----------------------------------------------------- +# Create a new API based on an already existing one +#----------------------------------------------------- + post: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/copy-api?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&newVersion=2.0.0\"" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060\nContent-Type: application/json\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" + summary: Copy API + description: | + Create a new API by copying an existing API + parameters: + - name: newVersion + description: Version of the new API. + type: string + in: query + required: true + - $ref: '#/parameters/apiId-Q' + tags: + - APIs + responses: + 201: + description: | + Created. + Successful response with the newly created API as entity in the body. Location header contains URL of newly created API. + headers: + Location: + description: | + The URL of the newly created API. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + API to copy does not exist. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Change Lifecycle" Processing Function resource API +###################################################### + /apis/change-lifecycle: + +#----------------------------------------------------- +# Change the lifecycle of an API +#----------------------------------------------------- + post: + x-scope: apim:api_publish + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/change-lifecycle?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&action=Publish\"" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Change API Status + description: | + Change the lifecycle of an API + parameters: + - name: action + description: | + The action to demote or promote the state of the API. + + Supported actions are [ **Publish, Deploy as a Prototype, Demote to Created, Demote to Prototyped, Block, Deprecate, Re-Publish, Retire **] + + in: query + type: string + required: true + enum: + - Publish + - Deploy as a Prototype + - Demote to Created + - Demote to Prototyped + - Block + - Deprecate + - Re-Publish + - Retire + - name: lifecycleChecklist + description: | + + You can specify additional checklist items by using an **"attribute:"** modifier. + + Eg: "Deprecate Old Versions:true" will deprecate older versions of a particular API when it is promoted to + Published state from Created state. Multiple checklist items can be given in "attribute1:true, attribute2:false" + format. + + Supported checklist items are as follows. + 1. **Deprecate Old Versions**: Setting this to true will deprecate older versions of a particular API when it is promoted to Published state from Created state. + 2. **Require Re-Subscription**: If you set this to true, users need to re subscribe to the API although they may have subscribed to an older version. + + type: string + in: query + - $ref: '#/parameters/apiId-Q' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - APIs + responses: + 200: + description: | + OK. + Lifecycle changed successfully. + headers: + ETag: + description: | + Entity Tag of the changed API. Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the API lifecycle has been modified the last time. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Document Collection" resource APIs +###################################################### + /apis/{apiId}/documents: + +#----------------------------------------------------- +# Retrieve the documents associated with an API that qualify under a search condition +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n },\n {\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"URL\",\n \"sourceUrl\": \"http://wiki.cdyne.com/index.php/Phone_Verification\",\n \"otherTypeName\": null,\n \"documentId\": \"4145df31-04f1-440c-8d08-68952874622c\",\n \"summary\": \"This is the URL for online documentation\",\n \"name\": \"Online Documentation\",\n \"type\": \"SAMPLES\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" + summary: Get API Documents + description: | + Get a list of documents belonging to an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - API Document + responses: + 200: + description: | + OK. + Document list is returned. + schema: + $ref: '#/definitions/DocumentList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Add a document to a certain API +#----------------------------------------------------- + post: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer cdcc8cf6016ed10620edf3a1d3c5ef2b\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents\"" + x-wso2-request: "{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\",\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" + summary: Add a new document + description: | + Add a new document to an API + parameters: + - $ref: '#/parameters/apiId' + - in: body + name: body + description: | + Document object that needs to be added + required: true + schema: + $ref: '#/definitions/Document' + - $ref: '#/parameters/Content-Type' + tags: + - API Document + responses: + 201: + description: | + Created. + Successful response with the newly created Document object as entity in the body. + Location header contains URL of newly added document. + schema: + $ref: '#/definitions/Document' + headers: + Location: + description: | + Location to the newly created Document. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 415: + description: | + Unsupported media type. + The entity of the request was in a not supported format. + +###################################################### +# The "Individual Document" resource APIs +###################################################### + '/apis/{apiId}/documents/{documentId}': + +#----------------------------------------------------- +# Retrieve a particular document of a certain API +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" + summary: Get an API Document + description: | + Get a particular document associated with an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - API Document + responses: + 200: + description: | + OK. + Document returned. + schema: + $ref: '#/definitions/Document' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update a particular document of a certain API +#----------------------------------------------------- + put: + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" + x-wso2-request: "{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" + summary: Update an API Document + description: | + Update document details. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - in: body + name: body + description: | + Document object that needs to be added + required: true + schema: + $ref: '#/definitions/Document' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - API Document + responses: + 200: + description: | + OK. + Document updated + schema: + $ref: '#/definitions/Document' + headers: + Location: + description: | + The URL of the updated document. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete a particular document of a certain API +#----------------------------------------------------- + delete: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X DELETE http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Delete an API Document + description: | + Delete a document of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - API Document + responses: + 200: + description: | + OK. + Resource successfully deleted. + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +################################################################ +# The content resource of "Individual Document" resource APIs +################################################################ + + '/apis/{apiId}/documents/{documentId}/content': + + #------------------------------------------------------------------------------------------------- + # Downloads a FILE type document/get the inline content or source url of a certain document + #------------------------------------------------------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\" > sample.pdf" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Disposition: attachment; filename=\"sample.pdf\"\nContent-Type: application/octet-stream\nContent-Length: 7802\n\n%PDF-1.4\n%äüöß\n2 0 obj\n<>\nstream\n..\n>>\nstartxref\n7279\n%%EOF" + summary: Get document content + description: | + Downloads a FILE type document/get the inline content or source url of a certain document. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - API Document + responses: + 200: + description: | + OK. + File or inline content returned. + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 303: + description: | + See Other. + Source can be retrived from the URL specified at the Location header. + headers: + Location: + description: | + The Source URL of the document. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + + #---------------------------------------------------------------------------- + # Upload a file or add inline content to a document of a certain API + #---------------------------------------------------------------------------- + post: + consumes: + - multipart/form-data + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -F file=@\"sample.pdf\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\"" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\nContent-Type: application/json\n\n{\n \"visibility\":\"API_LEVEL\",\n \"sourceType\":\"FILE\",\n \"sourceUrl\":null,\n \"otherTypeName\":null,\n \"documentId\":\"daf732d3-bda2-46da-b381-2c39d901ea61\",\n \"summary\":\"This is a sample documentation pdf\",\n \"name\":\"Introduction to PhoneVerification API PDF\",\n \"type\":\"HOWTO\"\n}" + summary: Update API document content. + description: | + Upload a file to a document or add inline content to the document. + + Document's source type should be **FILE** in order to upload a file to the document using **file** parameter. + Document's source type should be **INLINE** in order to add inline content to the document using **inlineContent** parameter. + + Only one of **file** or **inlineContent** can be specified at one time. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - in: formData + name: file + description: Document to upload + type: file + required: false + - in: formData + name: inlineContent + description: Inline content of the document + type: string + required: false + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - API Document + responses: + 200: + description: | + OK. + Document updated + schema: + $ref: '#/definitions/Document' + headers: + Location: + description: | + The URL of the updated content of the document. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual Application" resource APIs +###################################################### + '/applications/{applicationId}': + +#----------------------------------------------------- +# Retrieve the details about a certain application +#----------------------------------------------------- + get: + x-scope: apim:api_create + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/applications/896658a0-b4ee-4535-bbfa-806c894a4015" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"name\": \"DefaultApplication\"\n}" + summary: Get Application + description: | + Get application details + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Applications + responses: + 200: + description: | + OK. + Application returned. + schema: + $ref: '#/definitions/Application' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested application does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Subscription Collection" resource APIs +###################################################### + /subscriptions: + +#----------------------------------------------------- +# Retrieve all subscriptions of a certain API +#----------------------------------------------------- + get: + x-scope: apim:subscription_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n \n{\n \"previous\": \"\",\n \"list\": [\n {\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n },\n {\n \"subscriptionId\": \"7ac22c34-8745-4cfe-91e0-262c50b2f2e3\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"367a2361-8db5-4140-8133-c6c8dc7fa0c4\",\n \"status\": \"UNBLOCKED\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" + summary: Get All Subscriptions + description: | + Get subscription list. + The API Identifier and corresponding Application Identifier + the subscriptions of which are to be returned are passed as parameters. + parameters: + - $ref: '#/parameters/apiId-Q' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Subscriptions + responses: + 200: + description: | + OK. + Subscription list returned. + schema: + $ref: '#/definitions/SubscriptionList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual Subscription" resource APIs +###################################################### + '/subscriptions/{subscriptionId}': + +#----------------------------------------------------- +# Retrieve a certain subscription +#----------------------------------------------------- + get: + x-scope: apim:subscription_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/64eca60b-2e55-4c38-8603-e9e6bad7d809" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n}" + summary: Get a Subscription + description: | + Get subscription details + parameters: + - $ref: '#/parameters/subscriptionId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Subscriptions + responses: + 200: + description: | + OK. + Subscription returned + schema: + $ref: '#/definitions/Subscription' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: 'Entity Tag of the response resource. Used by caches, or in conditional requests.' + type: string + Last-Modified: + description: 'Date and time the resource has been modifed the last time. Used by caches, or in conditional reuquests.' + type: string + '304': + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + '404': + description: | + Not Found. + Requested Subscription does not exist. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Block Subscription" Processing Function resource API +###################################################### + /subscriptions/block-subscription: + +#----------------------------------------------------- +# Block a certain subscription +#----------------------------------------------------- + post: + x-scope: apim:subscription_block + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/block-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809&blockState=PROD_ONLY_BLOCKED\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n \n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"PROD_ONLY_BLOCKED\"\n}" + summary: Block a subscription + parameters: + - $ref: '#/parameters/subscriptionId-Q' + - name: blockState + in: query + description: | + Subscription block state. + type: string + required: true + enum: + - BLOCKED + - PROD_ONLY_BLOCKED + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + description: | + Block a subscription. + tags: + - Subscriptions + responses: + 200: + description: | + OK. + Subscription was blocked successfully. + headers: + ETag: + description: | + Entity Tag of the blocked subscription. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the subscription has been blocked. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Requested subscription does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Unblock Subscription" Processing Function resource API +###################################################### + /subscriptions/unblock-subscription: + +#----------------------------------------------------- +# Unblock a certain subscription +#----------------------------------------------------- + post: + x-scope: apim:subscription_block + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/unblock-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n} " + summary: Unblock a Subscription + parameters: + - $ref: '#/parameters/subscriptionId-Q' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + description: | + Unblock a subscription. + tags: + - Subscriptions + responses: + 200: + description: | + OK. + Subscription was unblocked successfully. + headers: + ETag: + description: | + Entity Tag of the unblocked subscription. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the subscription has been unblocked. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Requested subscription does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Tier Collection" resource APIs +###################################################### + '/tiers/{tierLevel}': + +#----------------------------------------------------- +# Retrieve the list of all available tiers +#----------------------------------------------------- + get: + x-scope: apim:tier_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 20,\n \"description\": \"Allows 20 request(s) per minute.\",\n \"name\": \"Gold\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Silver\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 0,\n \"tierPlan\": null,\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 0,\n \"description\": \"Allows unlimited requests\",\n \"name\": \"Unlimited\",\n \"attributes\": {}\n }\n ],\n \"next\": \"\",\n \"count\": 4\n}" + summary: List Tiers + description: | + Get available tiers + parameters: + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Tiers + responses: + 200: + description: | + OK. + List of tiers returned. + schema: + $ref: '#/definitions/TierList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Create a new tier +#----------------------------------------------------- + post: + x-scope: apim:tier_manage + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api\"" + x-wso2-request: "{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\":10,\n \"b\":30\n }\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/tiers/Low\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"b\": \"30\",\n \"a\": \"10\"\n }\n}" + summary: Add a new Tier + description: | + Add a new tier + parameters: + - in: body + name: body + description: | + Tier object that should to be added + required: true + schema: + $ref: '#/definitions/Tier' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/Content-Type' + tags: + - Tiers + responses: + 201: + description: | + Created. + Successful response with the newly created object as entity in the body. + Location header contains URL of newly created entity. + schema: + $ref: '#/definitions/Tier' + headers: + Location: + description: | + Location of the newly created tier. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request' + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 415: + description: | + Unsupported media type. + The entity of the request was in a not supported format. + +###################################################### +# The "Individual Tier" resource APIs +###################################################### + '/tiers/{tierLevel}/{tierName}': + +#----------------------------------------------------- +# Retrieve a certain tier +#----------------------------------------------------- + get: + x-scope: apim:tier_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Bronze" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n}" + summary: Get a Tier + description: | + Get tier details + parameters: + - $ref: '#/parameters/tierName' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Tiers + responses: + 200: + description: | + OK. + Tier returned + schema: + $ref: '#/definitions/Tier' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Tier does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update a certain tier +#----------------------------------------------------- + put: + x-scope: apim:tier_manage + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Low\"" + x-wso2-request: "{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 10,\n \"description\": \"Allows 10 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\": \"30\",\n \"b\": \"10\",\n \"c\": \"20\"\n }\n}\n" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 10,\n \"description\": \"Allows 10 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"b\": \"10\",\n \"c\": \"20\",\n \"a\": \"30\"\n }\n}" + summary: Update a Tier + description: | + Update tier details + parameters: + - $ref: '#/parameters/tierName' + - in: body + name: body + description: | + Tier object that needs to be modified + required: true + schema: + $ref: '#/definitions/Tier' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Tiers + responses: + 200: + description: | + OK. + Subscription updated. + schema: + $ref: '#/definitions/Tier' + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete a certain tier +#----------------------------------------------------- + delete: + x-scope: apim:tier_manage + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Low\"" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Delete a Tier + description: | + Remove a tier + parameters: + - $ref: '#/parameters/tierName' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Tiers + responses: + 200: + description: | + OK. + Resource successfully deleted. + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Update Permission" Processing Function resource API +###################################################### + '/tiers/update-permission': + +#----------------------------------------------------- +# Update the permission of a certain tier +#----------------------------------------------------- + post: + x-scope: apim:tier_manage + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/update-permission?tierName=Bronze&tierLevel=api\"" + x-wso2-request: "{\n \"permissionType\":\"deny\",\n \"roles\": [\"Internal/everyone\",\"admin\"]\n}" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Update Tier Permission + description: | + Update tier permission + parameters: + - $ref: '#/parameters/tierName-Q' + - $ref: '#/parameters/tierLevel-Q' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + - in: body + name: permissions + schema: + $ref: '#/definitions/TierPermission' + tags: + - Tiers + responses: + 200: + description: | + OK. + Successfully updated tier permissions + schema: + type: array + items: + $ref: '#/definitions/Tier' + headers: + ETag: + description: | + Entity Tag of the modified tier. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the tier has been modified. + Used by caches, or in conditional requests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Requested tier does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + + +###################################################### +# The "Environment Collection" resource API +###################################################### + /environments: + +#----------------------------------------------------- +# Retrieve the list of environments configured for a certain API +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/environments\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"list\": [ {\n \"showInApiConsole\": true,\n \"serverUrl\": \"https://192.168.56.1:9444//services/\",\n \"endpoints\": {\n \"http\": \"http://192.168.56.1:8281\",\n \"https\": \"https://192.168.56.1:8244\"\n },\n \"name\": \"Production and Sandbox\",\n \"type\": \"hybrid\"\n }],\n \"count\": 1\n}" + summary: Get gateway environments + description: | + Get a list of gateway environments configured previously. + parameters: + - in: query + name: apiId + description: | + Will return environment list for the provided API. + type: string + tags: + - Environments + responses: + 200: + description: | + OK. + Environment list is returned. + schema: + $ref: '#/definitions/EnvironmentList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' +###################################################### +# Parameters - required by some of the APIs above +###################################################### +parameters: + +# API Identifier +# Specified as part of the path expression + apiId: + name: apiId + in: path + description: | + **API ID** consisting of the **UUID** of the API. + The combination of the provider of the API, name of the API and the version is also accepted as a valid API ID. + Should be formatted as **provider-name-version**. + required: true + type: string + +# API Identifier +# Specified as part of the query string + apiId-Q: + name: apiId + in: query + description: | + **API ID** consisting of the **UUID** of the API. + The combination of the provider of the API, name of the API and the version is also accepted as a valid API I. + Should be formatted as **provider-name-version**. + required: true + type: string + + +# Document Identifier +# Specified as part of the path expression + documentId: + name: documentId + in: path + description: | + **Document Identifier** + required: true + type: string + +# Application Identifier +# Specified as part of the path expression + applicationId: + name: applicationId + in: path + description: | + **Application Identifier** consisting of the UUID of the Application. + required: true + type: string + +# Subscription Identifier +# Specified as part of the path expression + subscriptionId: + name: subscriptionId + in: path + description: | + Subscription Id + required: true + type: string + +# Subscription Identifier +# Specified as part of the query string + subscriptionId-Q: + name: subscriptionId + in: query + description: | + Subscription Id + required: true + type: string + +# Tier Name +# Specified as part of the path expression + tierName: + name: tierName + in: path + description: | + Tier name + required: true + type: string + +# Tier Name +# Specified as part of the query string + tierName-Q: + name: tierName + in: query + description: | + Name of the tier + required: true + type: string + +# Tier Type +# Specified as part of the path expression + tierLevel: + name: tierLevel + in: path + description: | + List API or Application or Resource type tiers. + type: string + enum: + - api + - application + - resource + required: true + +# Tier Type +# Specified as part of the query string + tierLevel-Q: + name: tierLevel + in: query + description: | + List API or Application or Resource type tiers. + type: string + enum: + - api + - application + - resource + required: true + +# Used for pagination: +# The maximum number of resoures to be returned by a GET + limit: + name: limit + in: query + description: | + Maximum size of resource array to return. + default: 25 + type: integer + +# Used for pagination: +# The order number of an instance in a qualified set of resoures +# at which to start to return the next batch of qualified resources + offset: + name: offset + in: query + description: | + Starting point within the complete list of items qualified. + default: 0 + type: integer + +# The HTTP Accept header + Accept: + name: Accept + in: header + description: | + Media types acceptable for the response. Default is JSON. + default: JSON + type: string + +# The HTTP Content-Type header + Content-Type: + name: Content-Type + in: header + description: | + Media type of the entity in the body. Default is JSON. + default: JSON + required: true + type : string + +# The HTTP If-None-Match header +# Used to avoid retrieving data that are already cached + If-None-Match: + name: If-None-Match + in: header + description: | + Validator for conditional requests; based on the ETag of the formerly retrieved + variant of the resourec. + type : string + +# The HTTP If-Modified-Since header +# Used to avoid retrieving data that are already cached + If-Modified-Since: + name: If-Modified-Since + in: header + description: | + Validator for conditional requests; based on Last Modified header of the + formerly retrieved variant of the resource. + type: string + +# The HTTP If-Match header +# Used to avoid concurrent updates + If-Match: + name: If-Match + in: header + description: | + Validator for conditional requests; based on ETag. + type: string + +# The HTTP If-Unmodified-Since header +# Used to avoid concurrent updates + If-Unmodified-Since: + name: If-Unmodified-Since + in: header + description: | + Validator for conditional requests; based on Last Modified header. + type: string + +###################################################### +# The resources used by some of the APIs above within the message body +###################################################### +definitions: + +#----------------------------------------------------- +# The API List resource +#----------------------------------------------------- + APIList: + title: API List + properties: + count: + type: integer + description: | + Number of APIs returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/apis?limit=1&offset=2&query=" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/apis?limit=1&offset=0&query=" + list: + type: array + items: + $ref: '#/definitions/APIInfo' + +#----------------------------------------------------- +# The API Info resource +#----------------------------------------------------- + APIInfo: + title: API Info object with basic API details. + properties: + id: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorAPI + description: + type: string + example: A calculator API that supports basic operations + context: + type: string + example: CalculatorAPI + version: + type: string + example: 1.0.0 + provider: + description: | + If the provider value is not given, the user invoking the API will be used as the provider. + type: string + example: admin + status: + type: string + example: CREATED + +#----------------------------------------------------- +# The API resource +#----------------------------------------------------- + API: + title: API object + required: + - name + - context + - version + - apiDefinition + - tiers + - isDefaultVersion + - transport + - endpointConfig + - visibility + properties: + id: + type: string + description: | + UUID of the api registry artifact + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorAPI + description: + type: string + example: A calculator API that supports basic operations + context: + type: string + example: CalculatorAPI + version: + type: string + example: 1.0.0 + provider: + description: | + If the provider value is not given user invoking the api will be used as the provider. + type: string + example: admin + apiDefinition: + description: | + Swagger definition of the API which contains details about URI templates and scopes + type: string + wsdlUri: + description: | + WSDL URL if the API is based on a WSDL endpoint + type: string + example: "http://www.webservicex.com/globalweather.asmx?wsdl" + status: + type: string + example: CREATED + responseCaching: + type: string + example: Disabled + cacheTimeout: + type: integer + example: 300 + destinationStatsEnabled: + type: string + example: Disabled + isDefaultVersion: + type: boolean + example: false + transport: + description: | + Supported transports for the API (http and/or https). + type: array + items: + type: string + example: ["http","https"] + tags: + type: array + items: + type: string + example: ["substract","add"] + tiers: + type: array + items: + type: string + example: ["Unlimited"] + maxTps: + properties: + production: + type: integer + format: int64 + example: 1000 + sandbox: + type: integer + format: int64 + example: 1000 + thumbnailUri: + type: string + example: "/apis/01234567-0123-0123-0123-012345678901/thumbnail" + visibility: + type: string + enum: + - PUBLIC + - PRIVATE + - RESTRICTED + - CONTROLLED + example: PUBLIC + visibleRoles: + type: array + items: + type: string + example: [] + visibleTenants: + type: array + items: + type: string + example: [] + endpointConfig: + type: string + example: "{\"production_endpoints\":{\"url\":\"http://localhost:9763/am/sample/calculator/v1/api\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}" + endpointSecurity: + properties: + type: + type: string + example: basic + enum: + - basic + - digest + username: + type: string + example: admin + password: + type: string + example: password + gatewayEnvironments: + description: | + Comma separated list of gateway environments. + type: string + example: Production and Sandbox + sequences: + type: array + items: + $ref: '#/definitions/Sequence' + example: [] + subscriptionAvailability: + type: string + enum: + - current_tenant + - all_tenants + - specific_tenants + example: current_tenant + subscriptionAvailableTenants: + type: array + items: + type: string + example: [] + businessInformation: + properties: + businessOwner: + type: string + example: businessowner + businessOwnerEmail: + type: string + example: businessowner@wso2.com + technicalOwner: + type: string + example: technicalowner + technicalOwnerEmail: + type: string + example: technicalowner@wso2.com + corsConfiguration: + description: | + CORS configuration for the API + properties: + corsConfigurationEnabled: + type: boolean + default: false + accessControlAllowOrigins: + type: array + items: + type: string + accessControlAllowCredentials: + type: boolean + default: false + accessControlAllowHeaders: + type: array + items: + type: string + accessControlAllowMethods: + type: array + items: + type: string + +#----------------------------------------------------- +# The Application resource +#----------------------------------------------------- + Application: + title: Application + required: + - name + - throttlingTier + properties: + applicationId: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorApp + subscriber: + type: string + example: admin + throttlingTier: + type: string + example: Unlimited + description: + type: string + example: Sample calculator application + groupId: + type: string + example: "" + +#----------------------------------------------------- +# The Document List resource +#----------------------------------------------------- + DocumentList: + title: Document List + properties: + count: + type: integer + description: | + Number of Documents returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/apis/01234567-0123-0123-0123-012345678901/documents?limit=1&offset=2" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/apis/01234567-0123-0123-0123-012345678901/documents?limit=1&offset=0" + list: + type: array + items: + $ref: '#/definitions/Document' + +#----------------------------------------------------- +# The Document resource +#----------------------------------------------------- + Document: + title: Document + required: + - name + - type + - sourceType + - visibility + properties: + documentId: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorDoc + type: + type: string + enum: + - HOWTO + - SAMPLES + - PUBLIC_FORUM + - SUPPORT_FORUM + - API_MESSAGE_FORMAT + - SWAGGER_DOC + - OTHER + example: HOWTO + summary: + type: string + example: "Summary of Calculator Documentation" + sourceType: + type: string + enum: + - INLINE + - URL + - FILE + example: INLINE + sourceUrl: + type: string + example: "" + otherTypeName: + type: string + example: "" + visibility: + type: string + enum: + - OWNER_ONLY + - PRIVATE + - API_LEVEL + example: API_LEVEL + +#----------------------------------------------------- +# The Tier List resource +#----------------------------------------------------- + TierList: + title: Tier List + properties: + count: + type: integer + description: | + Number of Tiers returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/tiers/api?limit=1&offset=2" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/tiers/api?limit=1&offset=0" + list: + type: array + items: + $ref: '#/definitions/Tier' + +#----------------------------------------------------- +# The Tier resource +#----------------------------------------------------- + Tier: + title: Tier + required: + - name + - tierPlan + - requestCount + - unitTime + - stopOnQuotaReach + properties: + name: + type: string + example: Platinum + description: + type: string + example: "Allows 50 request(s) per minute." + tierLevel: + type: string + enum: + - api + - application + - resource + example: api + attributes: + description: | + Custom attributes added to the tier policy + type: object + additionalProperties: + type: string + example: {} + requestCount: + description: | + Maximum number of requests which can be sent within a provided unit time + type: integer + format: int64 + example: 50 + unitTime: + type: integer + format: int64 + example: 60000 + timeUnit: + type: string + example: "min" + tierPlan: + description: | + This attribute declares whether this tier is available under commercial or free + type: string + enum: + - FREE + - COMMERCIAL + example: FREE + stopOnQuotaReach: + description: | + By making this attribute to false, you are capabale of sending requests + even if the request count exceeded within a unit time + type: boolean + example: true + +#----------------------------------------------------- +# The Tier Permission resource +#----------------------------------------------------- + TierPermission: + title: tierPermission + required: + - permissionType + - roles + properties: + permissionType: + type: string + enum: + - allow + - deny + example: deny + roles: + type: array + items: + type: string + example: ["Internal/everyone"] + +#----------------------------------------------------- +# The Subscription List resource +#----------------------------------------------------- + SubscriptionList: + title: Subscription List + properties: + count: + type: integer + description: | + Number of Subscriptions returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/subscriptions?limit=1&offset=2&apiId=01234567-0123-0123-0123-012345678901&groupId=" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/subscriptions?limit=1&offset=0&apiId=01234567-0123-0123-0123-012345678901&groupId=" + list: + type: array + items: + $ref: '#/definitions/Subscription' + +#----------------------------------------------------- +# The Subscription resource +#----------------------------------------------------- + Subscription: + title: Subscription + required: + - applicationId + - apiIdentifier + - tier + properties: + subscriptionId: + type: string + example: 01234567-0123-0123-0123-012345678901 + applicationId: + type: string + example: 01234567-0123-0123-0123-012345678901 + apiIdentifier: + type: string + example: 01234567-0123-0123-0123-012345678901 + tier: + type: string + example: Unlimited + status: + type: string + enum: + - BLOCKED + - PROD_ONLY_BLOCKED + - UNBLOCKED + - ON_HOLD + - REJECTED + example: UNBLOCKED + +#----------------------------------------------------- +# The Sequence resource +#----------------------------------------------------- + Sequence: + title: Sequence + required: + - name + properties: + name: + type: string + example: log_in_message + config: + type: string + example: "" + type: + type: string + example: in + +#----------------------------------------------------- +# The Error resource +#----------------------------------------------------- + Error: + title: Error object returned with 4XX HTTP status + required: + - code + - message + properties: + code: + type: integer + format: int64 + message: + type: string + description: Error message. + description: + type: string + description: | + A detail description about the error message. + moreInfo: + type: string + description: | + Preferably an url with more details about the error. + error: + type: array + description: | + If there are more than one error list them out. + For example, list out validation errors by each field. + items: + $ref: '#/definitions/ErrorListItem' + +#----------------------------------------------------- +# The Error List Item resource +#----------------------------------------------------- + ErrorListItem: + title: Description of individual errors that may have occurred during a request. + required: + - code + - message + properties: + code: + type: string + message: + type: string + description: | + Description about individual errors occurred + +#----------------------------------------------------- +# The Environment resource +#----------------------------------------------------- + Environment: + title: Environment + required: + - name + - type + - serverUrl + - endpoints + - showInApiConsole + properties: + name: + type: string + example: Production and Sandbox + type: + type: string + example: hybrid + serverUrl: + type: string + example: "https://localhost:9443//services/" + showInApiConsole: + type: boolean + example: true + endpoints: + $ref: '#/definitions/EnvironmentEndpoints' + +#----------------------------------------------------- +# The Environment List resource +#----------------------------------------------------- + EnvironmentList: + title: Environment List + properties: + count: + type: integer + description: | + Number of Environments returned. + example: 1 + list: + type: array + items: + $ref: '#/definitions/Environment' + + +#----------------------------------------------------- +# The Environment Endpoint resource +#----------------------------------------------------- + EnvironmentEndpoints : + title: Environment Endpoints + properties: + http: + type: string + description: HTTP environment URL + example: "http://localhost:8280" + https: + type: string + description: HTTPS environment URL + example: "https://localhost:8244" + +#----------------------------------------------------- +# The File Information resource +#----------------------------------------------------- + FileInfo : + title: File Information including meta data + properties: + relativePath: + type: string + description: relative location of the file (excluding the base context and host of the Publisher API) + example: "apis/01234567-0123-0123-0123-012345678901/thumbnail" + mediaType: + type: string + description: media-type of the file + example: "image/jpeg" diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/pom.xml new file mode 100644 index 0000000000..4751427221 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/pom.xml @@ -0,0 +1,176 @@ + + + + + + apimgt-extensions + org.wso2.carbon.devicemgt + 2.0.8-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.apimgt.store.client + bundle + org.wso2.carbon.apimgt.store.client + + + + + io.swagger + swagger-codegen-maven-plugin + 2.2.1 + + + + generate + + + ${project.basedir}/src/main/resources/store-api.yaml + java + + ${project.artifactId}.api + ${project.artifactId}.model + ${project.artifactId}.invoker + + feign + + + + + + maven-antrun-plugin + 1.4 + + + copy + process-resources + + + + + + + + + + + + + + run + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + ${project.version} + APIM Integration + + org.wso2.carbon.apimgt.store.client.model, + org.wso2.carbon.apimgt.store.client.api, + org.wso2.carbon.apimgt.store.client.invoker + + + org.osgi.framework, + org.osgi.service.component, + org.wso2.carbon.logging, + io.swagger, + junit, + javax.ws.rs, + feign, + feign.jackson, + feign.codec, + feign.auth, + feign.gson, + feign.slf4j, + feign.jaxrs, + com.google.gson, + com.fasterxml.jackson.core, + com.fasterxml.jackson.annotation, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.datatype.joda, i + o.swagger.annotations, + javax.net.ssl, + org.apache.oltu.oauth2.client.*, + org.apache.oltu.oauth2.common.*, + org.junit;resolution:=optional + + + + + + + + + + + + + + io.swagger + swagger-annotations + + + junit + junit + + + io.github.openfeign + feign-core + + + io.github.openfeign + feign-jaxrs + + + io.github.openfeign + feign-gson + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-annotations + + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + + + org.wso2.orbit.joda-time + joda-time + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + + + io.github.openfeign + feign-jackson + + + io.github.openfeign + feign-slf4j + + + + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/src/main/resources/store-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/src/main/resources/store-api.yaml new file mode 100644 index 0000000000..b591fc3597 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.store.client/src/main/resources/store-api.yaml @@ -0,0 +1,2098 @@ +swagger: '2.0' +###################################################### +# Prolog +###################################################### +info: + version: "0.10.0" + title: "WSO2 API Manager - Store" + description: | + This document specifies a **RESTful API** for WSO2 **API Manager** - Store. + + It is written with [swagger 2](http://swagger.io/). + + contact: + name: "WSO2" + url: "http://wso2.com/products/api-manager/" + email: "architecture@wso2.com" + license: + name: "Apache 2.0" + url: "http://www.apache.org/licenses/LICENSE-2.0.html" + +###################################################### +# The fixed parts of the URLs of the API +###################################################### + +# The schemes supported by the API +schemes: + - https + +# The domain of the API. +# This is configured by the customer during deployment. +# The given host is just an example. +host: apis.wso2.com + +# The base path of the API. +# Will be prefixed to all paths. +basePath: /api/am/store/v0.10 + +# The following media types can be passed as input in message bodies of the API. +# The actual media type must be specified in the Content-Type header field of the request. +# The default is json, i.e. the Content-Type header is not needed to +# be set, but supporting it serves extensibility. +consumes: + - application/json + +# The following media types may be passed as output in message bodies of the API. +# The media type(s) consumable by the requestor is specified in the Accept header field +# of the corresponding request. +# The actual media type returned will be specfied in the Content-Type header field +# of the of the response. +# The default of the Accept header is json, i.e. there is not needed to +# set the value, but supporting it serves extensibility. +produces: + - application/json + +x-wso2-security: + apim: + x-wso2-scopes: + - description: "" + roles: Internal/subscriber + name: apim:subscribe + key: apim:subscribe + +###################################################### +# The "API Collection" resource APIs +###################################################### +paths: + /apis: + +#----------------------------------------------------- +# Retrieving the list of all APIs qualifying under a given search condition +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" http://127.0.0.1:9763/api/am/store/v0.10/apis" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"This API provide Account Status Validation.\",\n \"status\": \"PUBLISHED\",\n \"name\": \"AccountVal\",\n \"context\": \"/account/1.0.0\",\n \"id\": \"2e81f147-c8a8-4f68-b4f0-69e0e7510b01\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": null,\n \"status\": \"PUBLISHED\",\n \"name\": \"api1\",\n \"context\": \"/api1/1.0.0\",\n \"id\": \"3e22d2fb-277a-4e9e-8c7e-1c0f7f73960e\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Verify a phone number\",\n \"status\": \"PUBLISHED\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify/2.0.0\",\n \"id\": \"c43a325c-260b-4302-81cb-768eafaa3aed\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" + summary: | + Retrieving APIs + description: | + Get a list of available APIs qualifying under a given search condition. + parameters: + - $ref : '#/parameters/limit' + - $ref : '#/parameters/offset' + - $ref : '#/parameters/requestedTenant' + - name : query + in: query + description: | + **Search condition**. + + You can search in attributes by using an **"attribute:"** modifier. + + Eg. + "provider:wso2" will match an API if the provider of the API is exactly "wso2". + + Additionally you can use wildcards. + + Eg. + "provider:wso2\*" will match an API if the provider of the API starts with "wso2". + + Supported attribute modifiers are [**version, context, status, + description, subcontext, doc, provider, tag**] + + If no advanced attribute modifier has been specified, search will match the + given query string against API Name. + type: string + - $ref : "#/parameters/Accept" + - $ref : "#/parameters/If-None-Match" + tags: + - apisAPI + responses: + 200: + description: | + OK. + List of qualifying APIs is returned. + schema: + $ref: '#/definitions/APIList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual API" resource APIs +###################################################### + /apis/{apiId}: + +#----------------------------------------------------- +# Retrieve the details of an API definition +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" http://127.0.0.1:9763/api/am/store/v0.10/apis/c43a325c-260b-4302-81cb-768eafaa3aed" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"isDefaultVersion\": false,\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Verify a phone number\",\n \"status\": \"PUBLISHED\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify/2.0.0\",\n \"id\": \"c43a325c-260b-4302-81cb-768eafaa3aed\"\n}" + summary: | + Get Details of API + description: | + Get details of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + - $ref: '#/parameters/requestedTenant' + tags: + - API (individual) + responses: + 200: + description: | + OK. + Requested API is returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + schema: + $ref: '#/definitions/API' + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + + + /apis/{apiId}/swagger: +#----------------------------------------------------- +# Retrieve the API swagger definition +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" http://127.0.0.1:9763/api/am/store/v0.10/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"2.0.0\"\n }\n}\n" + summary: | + Get the swagger of an API + description: | + Get the swagger of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + - $ref: '#/parameters/requestedTenant' + tags: + - API (individual) + responses: + 200: + description: | + OK. + Requested swagger document of the API is returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Document Collection" resource APIs +###################################################### + /apis/{apiId}/documents: + +#----------------------------------------------------- +# Retrieve the documents associated with an API that qualify under a search condition +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" http://127.0.0.1:9763/api/am/store/v0.10/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"850a4f34-db2c-4d23-9d85-3f95fbfb082c\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n },\n {\n \"sourceType\": \"URL\",\n \"sourceUrl\": \"http://wiki.cdyne.com/index.php/Phone_Verification\",\n \"otherTypeName\": null,\n \"documentId\": \"98e18be8-5861-43c7-ba26-8cbbccd3a76f\",\n \"summary\": \"This is the URL for online documentation\",\n \"name\": \"Online Documentation\",\n \"type\": \"SAMPLES\"\n },\n {\n \"sourceType\": \"FILE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"b66451ff-c6c2-4f6a-b91d-3821dc119b04\",\n \"summary\": \"This is a sample documentation pdf\",\n \"name\": \"Introduction to PhoneVerification API PDF\",\n \"type\": \"HOWTO\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" + summary: | + Get a list of documents belonging to an API. + description: | + Get a list of documents belonging to an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - API (individual) + responses: + 200: + description: | + OK. + Document list is returned. + schema: + $ref: '#/definitions/DocumentList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual Document" resource APIs +###################################################### + '/apis/{apiId}/documents/{documentId}': + +#----------------------------------------------------- +# Retrieve a particular document of a certain API +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"850a4f34-db2c-4d23-9d85-3f95fbfb082c\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" + summary: | + Get a particular document associated with an API. + description: | + Get a particular document associated with an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - API (individual) + responses: + 200: + description: | + OK. + Document returned. + schema: + $ref: '#/definitions/Document' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + + +################################################################ +# The content resource of "Individual Document" resource APIs +################################################################ + + '/apis/{apiId}/documents/{documentId}/content': + + #------------------------------------------------------------------------------------------------- + # Downloads a FILE type document/get the inline content or source url of a certain document + #------------------------------------------------------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content\" > sample.pdf" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Disposition: attachment; filename=\"sample.pdf\"\nContent-Type: application/octet-stream\nContent-Length: 7802\n\n%PDF-1.4\n%äüöß\n2 0 obj\n<>\nstream\n..\n>>\nstartxref\n7279\n%%EOF" + summary: | + Downloads a FILE type document/get the inline content or source url of a certain document. + description: | + Downloads a FILE type document/get the inline content or source url of a certain document. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/documentId' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - API (individual) + responses: + 200: + description: | + OK. + File or inline content returned. + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 303: + description: | + See Other. + Source can be retrived from the URL specified at the Location header. + headers: + Location: + description: | + The Source URL of the document. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +################################################################ +# The thumbnail resource of "Individual API" resource APIs +################################################################ + + /apis/{apiId}/thumbnail: +#------------------------------------------------------------------------------------------------- +# Downloads a thumbnail image of an API +#------------------------------------------------------------------------------------------------- + get: + x-wso2-curl: "curl http://127.0.0.1:9763/api/am/store/v0.10/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail > image.jpg" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\n\r\n[image content]" + summary: Get the thumbnail image + description: | + Downloads a thumbnail image of an API + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - API (individual) + responses: + 200: + description: | + OK. + Thumbnail image returned + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Application Collection" resource APIs +###################################################### + /applications: + +#----------------------------------------------------- +# Retrieve a list of all applications of a certain subscriber +#----------------------------------------------------- + get: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/applications\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"367a2361-8db5-4140-8133-c6c8dc7fa0c4\",\n \"description\": \"\",\n \"status\": \"APPROVED\",\n \"name\": \"app1\"\n },\n {\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"status\": \"APPROVED\",\n \"name\": \"DefaultApplication\"\n }\n ],\n \"count\": 2,\n \"next\": \"\"\n}" + summary: | + Get a list of applications + description: | + Get a list of applications + parameters: + - $ref: '#/parameters/groupId' + - name : query + in: query + description: | + **Search condition**. + + You can search for an application by specifying the name as "query" attribute. + + Eg. + "app1" will match an application if the name is exactly "app1". + + Currently this does not support wildcards. Given name must exactly match the application name. + type: string + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Application Collection + responses: + 200: + description: | + OK. + Application list returned. + schema: + $ref: '#/definitions/ApplicationList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Create a new application +#----------------------------------------------------- + post: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/store/v0.10/applications\"" + x-wso2-request: "{\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"description\": \"sample app description\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/store/v0.10/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\nContent-Type: application/json\n\n{\n \"groupId\": null,\n \"callbackUrl\": null,\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\",\n \"keys\": []\n}" + summary: | + Create a new application. + description: | + Create a new application. + parameters: + - in: body + name: body + description: | + Application object that is to be created. + required: true + schema: + $ref: '#/definitions/Application' + - $ref: '#/parameters/Content-Type' + tags: + - Application (individual) + responses: + 201: + description: | + Created. + Successful response with the newly created object as entity in the body. + Location header contains URL of newly created entity. + schema: + $ref: '#/definitions/Application' + headers: + Location: + description: | + Location of the newly created Application. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 409: + description: | + Conflict. + Application already exists. + schema: + $ref: '#/definitions/Error' + 415: + description: | + Unsupported media type. + The entity of the request was in a not supported format. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual Application" resource APIs +###################################################### + '/applications/{applicationId}': + +#----------------------------------------------------- +# Retrieve the details about a certain application +#----------------------------------------------------- + get: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/applications/896658a0-b4ee-4535-bbfa-806c894a4015\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": \"\",\n \"callbackUrl\": null,\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"status\": \"APPROVED\",\n \"name\": \"DefaultApplication\",\n \"keys\": [ {\n \"consumerKey\": \"AVoREWiB16kY_GTIzscl40GYYZQa\",\n \"consumerSecret\": \"KXQxmS8W3xDvvJH4AfR6xrhKIeIa\",\n \"keyState\": \"COMPLETED\",\n \"keyType\": \"PRODUCTION\",\n \"supportedGrantTypes\": null,\n \"token\": {\n \"validityTime\": 3600,\n \"accessToken\": \"3887da6d111f0429c6dff47a46e87209\",\n \"tokenScopes\": [\n \"am_application_scope\",\n \"default\"\n ]\n }\n }]\n}" + summary: | + Get application details + description: | + Get application details + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Application (individual) + responses: + 200: + description: | + OK. + Application returned. + schema: + $ref: '#/definitions/Application' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested application does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update a certain application +#----------------------------------------------------- + put: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"http://127.0.0.1:9763/api/am/store/v0.10/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" + x-wso2-request: "{\n \"groupId\": null,\n \"callbackUrl\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Bronze\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description updated\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\"\n}" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": null,\n \"callbackUrl\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Bronze\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description updated\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\",\n \"keys\": []\n}" + summary: | + Update application details + description: | + Update application details + parameters: + - $ref: '#/parameters/applicationId' + - in: body + name: body + description: | + Application object that needs to be updated + required: true + schema: + $ref: '#/definitions/Application' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Application (individual) + responses: + 200: + description: | + OK. + Application updated. + schema: + $ref: '#/definitions/Application' + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete a certain application +#----------------------------------------------------- + delete: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -X DELETE \"http://127.0.0.1:9763/api/am/store/v0.10/applications/367a2361-8db5-4140-8133-c6c8dc7fa0c4\"" + x-wso2-response: "HTTP/1.1 200 OK" + summary: | + Remove an application + description: | + Remove an application + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Application (individual) + responses: + 200: + description: | + OK. + Resource successfully deleted. + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Generate Keys" Processing Function resource API +###################################################### + '/applications/generate-keys': + +#----------------------------------------------------- +# Generate keys for an application +#----------------------------------------------------- + post: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/store/v0.10/applications/generate-keys?applicationId=c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" + x-wso2-request: "{\n \"validityTime\": \"3600\",\n \"keyType\": \"PRODUCTION\",\n \"accessAllowDomains\": [\"ALL\"\n ]\n}" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"consumerSecret\": \"8V7DDKtKGtuG_9GDjaOJ5sijdX0a\",\n \"consumerKey\": \"LOFL8He72MSGVil4SS_bsh9O8MQa\",\n \"keyState\": \"APPROVED\",\n \"keyType\": \"PRODUCTION\",\n \"supportedGrantTypes\": [\n \"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n \"iwa:ntlm\",\n \"refresh_token\",\n \"client_credentials\",\n \"password\"\n ],\n \"token\": {\n \"validityTime\": 3600,\n \"accessToken\": \"fd2cdc4906fbc162e033d57f85a71c21\",\n \"tokenScopes\": [\n \"am_application_scope\",\n \"default\"\n ]\n }\n}" + description: | + Generate keys for application + summary: | + Generate keys for application + parameters: + - $ref: '#/parameters/applicationId-Q' + - in: body + name: body + description: | + Application object the keys of which are to be generated + required: true + schema: + $ref: '#/definitions/ApplicationKeyGenerateRequest' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Application (individual) + responses: + 200: + description: | + OK. + Keys are generated. + schema: + $ref: '#/definitions/ApplicationKey' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional request. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests.‚ + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Subscription Collection" resource APIs +###################################################### + /subscriptions: + +#----------------------------------------------------- +# Retrieve all subscriptions of a certain API and application +#----------------------------------------------------- + get: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"tier\": \"Bronze\",\n \"subscriptionId\": \"03b8ef2b-5ae5-41f5-968e-52fa7fbd5d33\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n },\n {\n \"tier\": \"Bronze\",\n \"subscriptionId\": \"5ed42650-9f5e-4dd4-94f3-3f09f1b17354\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"846118a5-3b25-4c22-a983-2d0278936f09\",\n \"status\": \"UNBLOCKED\"\n }\n ],\n \"count\": 2,\n \"next\": \"\"\n}" + summary: | + Get subscription list. + description: | + Get subscription list. + The API Identifier or Application Identifier + the subscriptions of which are to be returned are passed as parameters. + parameters: + - $ref: '#/parameters/apiId-Q' + - $ref: '#/parameters/applicationId-Q' + - $ref: '#/parameters/groupId' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/limit' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Subscription Collection + responses: + 200: + description: | + OK. + Subscription list returned. + schema: + $ref: '#/definitions/SubscriptionList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Create a new subscription +#----------------------------------------------------- + post: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/store/v0.10/subscriptions\"" + x-wso2-request: "{\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"c43a325c-260b-4302-81cb-768eafaa3aed\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/store/v0.10/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" + summary: | + Add a new subscription + description: | + Add a new subscription + parameters: + - in: body + name: body + description: | + Subscription object that should to be added + required: true + schema: + $ref: '#/definitions/Subscription' + - $ref: '#/parameters/Content-Type' + tags: + - Subscription (individual) + responses: + 201: + description: | + Created. + Successful response with the newly created object as entity in the body. + Location header contains URL of newly created entity. + schema: + $ref: '#/definitions/Subscription' + headers: + Location: + description: | + Location to the newly created subscription. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional request. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 415: + description: | + Unsupported media type. + The entity of the request was in a not supported format. + +###################################################### +# The "Individual Subscription" resource APIs +###################################################### + '/subscriptions/{subscriptionId}': + +#----------------------------------------------------- +# Retrieve a certain subscription +#----------------------------------------------------- + get: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" + description: | + Get subscription details + summary: | + Get subscription details + parameters: + - $ref: '#/parameters/subscriptionId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Subscription (individual) + responses: + 200: + description: | + OK. + Subscription returned + schema: + $ref: '#/definitions/Subscription' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: 'Entity Tag of the response resource. Used by caches, or in conditional requests.' + type: string + Last-Modified: + description: 'Date and time the resource has been modifed the last time. Used by caches, or in conditional reuquests.' + type: string + '304': + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + '404': + description: | + Not Found. + Requested Subscription does not exist. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete a certain subscription +#----------------------------------------------------- + delete: + x-scope: apim:subscribe + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" -X DELETE \"http://127.0.0.1:9763/api/am/store/v0.10/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" + x-wso2-response: "HTTP/1.1 200 OK" + summary: | + Remove subscription + description: | + Remove subscription + parameters: + - $ref: '#/parameters/subscriptionId' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Subscription (individual) + responses: + 200: + description: | + OK. + Resource successfully deleted. + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Tier Collection" resource APIs +###################################################### + /tiers/{tierLevel}: + +#----------------------------------------------------- +# Retrieve the list of all available tiers +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/tiers/api\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 20,\n \"description\": \"Allows 20 request(s) per minute.\",\n \"name\": \"Gold\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Silver\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 0,\n \"tierPlan\": null,\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 0,\n \"description\": \"Allows unlimited requests\",\n \"name\": \"Unlimited\",\n \"attributes\": {}\n }\n ],\n \"count\": 4,\n \"next\": \"\"\n}" + description: | + Get available tiers + summary: | + Get available tiers + parameters: + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Tier Collection + responses: + 200: + description: | + OK. + List of tiers returned. + schema: + type: array + items: + $ref: '#/definitions/TierList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Individual Tier" resource APIs +###################################################### + '/tiers/{tierLevel}/{tierName}': + +#----------------------------------------------------- +# Retrieve a certain tier +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/tiers/api/Bronze\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n}" + description: | + Get tier details + summary: | + Get tier details + parameters: + - $ref: '#/parameters/tierName' + - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Tier (individual) + responses: + 200: + description: | + OK. + Tier returned + schema: + $ref: '#/definitions/Tier' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. + Requested Tier does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Tag Collection" resource API +###################################################### + /tags: + +#----------------------------------------------------- +# Retrieve the list of tags qualifying under a search condition +#----------------------------------------------------- + get: + x-wso2-curl: "curl -H \"Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d\" \"http://127.0.0.1:9763/api/am/store/v0.10/tags\"" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"weight\": 1,\n \"name\": \"mobile\"\n },\n {\n \"weight\": 1,\n \"name\": \"multimedia\"\n },\n {\n \"weight\": 1,\n \"name\": \"phone\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" + description: | + Get a list of tags that are already added to APIs + summary: | + Get a list of tags that are already added to APIs + parameters: + - $ref: '#/parameters/limit' + - $ref: '#/parameters/offset' + - $ref: '#/parameters/requestedTenant' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + tags: + - Tag Collection + responses: + 200: + description: | + OK. + Tag list is returned. + schema: + $ref: '#/definitions/TagList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests. + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + 404: + description: | + Not Found. Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +###################################################### +# Parameters - required by some of the APIs above +###################################################### +parameters: + +# Requested Tenant domain +# Specified as a header parameter + requestedTenant: + name: X-WSO2-Tenant + in: header + description: | + For cross-tenant invocations, this is used to specify the tenant domain, where the resource need to be + retirieved from. + required: false + type: string + +# API Identifier +# Specified as part of the path expression + apiId: + name: apiId + in: path + description: | + **API ID** consisting of the **UUID** of the API. + The combination of the provider of the API, name of the API and the version is also accepted as a valid API ID. + Should be formatted as **provider-name-version**. + required: true + type: string + +# API Identifier +# Specified as part of the query string + apiId-Q: + name: apiId + in: query + description: | + **API ID** consisting of the **UUID** of the API. + The combination of the provider of the API, name of the API and the version is also accepted as a valid API I. + Should be formatted as **provider-name-version**. + required: true + type: string + + +# Document Identifier +# Specified as part of the path expression + documentId: + name: documentId + in: path + description: | + **Document Identifier** + required: true + type: string + +# Application Identifier +# Specified as part of the path expression + applicationId: + name: applicationId + in: path + description: | + **Application Identifier** consisting of the UUID of the Application. + required: true + type: string + +# Application Identifier +# Specified as part of the query string + applicationId-Q: + name: applicationId + in: query + description: | + **Application Identifier** consisting of the UUID of the Application. + required: true + type: string + +# Group Identifier of the application + groupId: + name: groupId + in: query + description: | + Application Group Id + required: false + type: string + +# Subscription Identifier +# Specified as part of the path expression + subscriptionId: + name: subscriptionId + in: path + description: | + Subscription Id + required: true + type: string + +# Tier Name +# Specified as part of the path expression + tierName: + name: tierName + in: path + description: | + Tier name + required: true + type: string + +# Tier Type +# Specified as part of the path expression + tierLevel: + name: tierLevel + in: path + description: | + List API or Application type tiers. + type: string + enum: + - api + - application + required: true + +# Used for pagination: +# The maximum number of resoures to be returned by a GET + limit: + name: limit + in: query + description: | + Maximum size of resource array to return. + default: 25 + type: integer + +# Used for pagination: +# The order number of an instance in a qualified set of resoures +# at which to start to return the next batch of qualified resources + offset: + name: offset + in: query + description: | + Starting point within the complete list of items qualified. + default: 0 + type: integer + +# The HTTP Accept header + Accept: + name: Accept + in: header + description: | + Media types acceptable for the response. Default is JSON. + default: JSON + type: string + +# The HTTP Content-Type header + Content-Type: + name: Content-Type + in: header + description: | + Media type of the entity in the body. Default is JSON. + default: JSON + required: true + type : string + +# The HTTP If-None-Match header +# Used to avoid retrieving data that are already cached + If-None-Match: + name: If-None-Match + in: header + description: | + Validator for conditional requests; based on the ETag of the formerly retrieved + variant of the resourec. + type : string + +# The HTTP If-Modified-Since header +# Used to avoid retrieving data that are already cached + If-Modified-Since: + name: If-Modified-Since + in: header + description: | + Validator for conditional requests; based on Last Modified header of the + formerly retrieved variant of the resource. + type: string + +# The HTTP If-Match header +# Used to avoid concurrent updates + If-Match: + name: If-Match + in: header + description: | + Validator for conditional requests; based on ETag. + type: string + +# The HTTP If-Unmodified-Since header +# Used to avoid concurrent updates + If-Unmodified-Since: + name: If-Unmodified-Since + in: header + description: | + Validator for conditional requests; based on Last Modified header. + type: string + +###################################################### +# The resources used by some of the APIs above within the message body +###################################################### +definitions: + +#----------------------------------------------------- +# The API List resource +#----------------------------------------------------- + APIList: + title: API List + properties: + count: + type: integer + description: | + Number of APIs returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/apis?limit=1&offset=2&query=" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/apis?limit=1&offset=0&query=" + list: + type: array + items: + $ref: '#/definitions/APIInfo' + +#----------------------------------------------------- +# The API Info resource +#----------------------------------------------------- + APIInfo: + title: API Info object with basic API details. + properties: + id: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorAPI + description: + type: string + example: A calculator API that supports basic operations + context: + type: string + example: CalculatorAPI + version: + type: string + example: 1.0.0 + provider: + description: | + If the provider value is not given, the user invoking the API will be used as the provider. + type: string + example: admin + status: + type: string + example: PUBLISHED + +#----------------------------------------------------- +# The API resource +#----------------------------------------------------- + API: + title: API object + required: + - name + - context + - version + - provider + - status + - apiDefinition + properties: + id: + type: string + description: | + UUID of the api registry artifact + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorAPI + description: + type: string + example: A calculator API that supports basic operations + context: + type: string + example: CalculatorAPI + version: + type: string + example: 1.0.0 + provider: + description: | + If the provider value is not given user invoking the api will be used as the provider. + type: string + example: admin + apiDefinition: + description: | + Swagger definition of the API which contains details about URI templates and scopes + type: string + example: "" + wsdlUri: + description: | + WSDL URL if the API is based on a WSDL endpoint + type: string + example: "http://www.webservicex.com/globalweather.asmx?wsdl" + status: + type: string + example: PUBLISHED + isDefaultVersion: + type: boolean + example: false + transport: + type: array + items: + description: | + Supported transports for the API (http and/or https). + type: string + example: ["http","https"] + tags: + type: array + items: + type: string + example: ["substract","add"] + tiers: + type: array + items: + type: string + example: ["Unlimited"] + thumbnailUrl: + type: string + example: "" + endpointURLs: + type: array + items: + properties: + environmentName: + type: string + example: Production and Sandbox + environmentType: + type: string + example: hybrid + environmentURLs: + properties: + http: + type: string + description: HTTP environment URL + example: "http://192.168.56.1:8280/phoneverify/1.0.0" + https: + type: string + description: HTTPS environment URL + example: "https://192.168.56.1:8243/phoneverify/1.0.0" + businessInformation: + properties: + businessOwner: + type: string + example: businessowner + businessOwnerEmail: + type: string + example: businessowner@wso2.com + technicalOwner: + type: string + example: technicalowner + technicalOwnerEmail: + type: string + example: technicalowner@wso2.com + +#----------------------------------------------------- +# The Application List resource +#----------------------------------------------------- + ApplicationList: + title: Application List + properties: + count: + type: integer + description: | + Number of applications returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/applications?limit=1&offset=2&groupId=" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/applications?limit=1&offset=0&groupId=" + list: + type: array + items: + $ref: '#/definitions/ApplicationInfo' + +#----------------------------------------------------- +# The Application resource +#----------------------------------------------------- + Application: + title: Application + required: + - name + - throttlingTier + properties: + applicationId: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorApp + subscriber: + description: | + If subscriber is not given user invoking the API will be taken as the subscriber. + type: string + example: admin + throttlingTier: + type: string + example: Unlimited + callbackUrl: + type: string + example: "" + description: + type: string + example: Sample calculator application + status: + type: string + example: APPROVED + default: "" + groupId: + type: string + example: "" + keys: + type: array + items: + $ref: '#/definitions/ApplicationKey' + example: [] + +#----------------------------------------------------- +# The Application Info resource +#----------------------------------------------------- + ApplicationInfo: + title: Application info object with basic application details + properties: + applicationId: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorApp + subscriber: + type: string + example: admin + throttlingTier: + type: string + example: Unlimited + description: + type: string + example: Sample calculator application + status: + type: string + example: APPROVED + groupId: + type: string + example: "" + +#----------------------------------------------------- +# The Document List resource +#----------------------------------------------------- + DocumentList: + title: Document List + properties: + count: + type: integer + description: | + Number of Documents returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/apis/01234567-0123-0123-0123-012345678901/documents?limit=1&offset=2" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/apis/01234567-0123-0123-0123-012345678901/documents?limit=1&offset=0" + list: + type: array + items: + $ref: '#/definitions/Document' + +#----------------------------------------------------- +# The Document resource +#----------------------------------------------------- + Document: + title: Document + required: + - name + - type + - sourceType + properties: + documentId: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: CalculatorDoc + type: + type: string + enum: + - HOWTO + - SAMPLES + - PUBLIC_FORUM + - SUPPORT_FORUM + - API_MESSAGE_FORMAT + - SWAGGER_DOC + - OTHER + example: HOWTO + summary: + type: string + example: "Summary of Calculator Documentation" + sourceType: + type: string + enum: + - INLINE + - URL + - FILE + example: INLINE + sourceUrl: + type: string + example: "" + otherTypeName: + type: string + example: "" + +#----------------------------------------------------- +# The Tier List resource +#----------------------------------------------------- + TierList: + title: Tier List + properties: + count: + type: integer + description: | + Number of Tiers returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/tiers/api?limit=1&offset=2" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/tiers/api?limit=1&offset=0" + list: + type: array + items: + $ref: '#/definitions/Tier' + +#----------------------------------------------------- +# The Tier resource +#----------------------------------------------------- + Tier: + title: Tier + required: + - name + - tierPlan + - requestCount + - unitTime + - stopOnQuotaReach + properties: + name: + type: string + example: Platinum + description: + type: string + example: "Allows 50 request(s) per minute." + tierLevel: + type: string + enum: + - api + - application + example: api + attributes: + description: | + Custom attributes added to the tier policy + type: object + additionalProperties: + type: string + example: {} + requestCount: + description: | + Maximum number of requests which can be sent within a provided unit time + type: integer + format: int64 + example: 50 + unitTime: + type: integer + format: int64 + example: 60000 + tierPlan: + description: | + This attribute declares whether this tier is available under commercial or free + type: string + enum: + - FREE + - COMMERCIAL + example: FREE + stopOnQuotaReach: + description: | + If this attribute is set to false, you are capabale of sending requests + even if the request count exceeded within a unit time + type: boolean + example: true + +#----------------------------------------------------- +# The Subscription List resource +#----------------------------------------------------- + SubscriptionList: + title: Subscription List + properties: + count: + type: integer + description: | + Number of Subscriptions returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/subscriptions?limit=1&offset=2&apiId=01234567-0123-0123-0123-012345678901&groupId=" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/subscriptions?limit=1&offset=0&apiId=01234567-0123-0123-0123-012345678901&groupId=" + list: + type: array + items: + $ref: '#/definitions/Subscription' + +#----------------------------------------------------- +# The Subscription resource +#----------------------------------------------------- + Subscription: + title: Subscription + required: + - applicationId + - apiIdentifier + - tier + properties: + subscriptionId: + type: string + example: 01234567-0123-0123-0123-012345678901 + applicationId: + type: string + example: 01234567-0123-0123-0123-012345678901 + apiIdentifier: + type: string + example: 01234567-0123-0123-0123-012345678901 + tier: + type: string + example: Unlimited + status: + type: string + enum: + - BLOCKED + - PROD_ONLY_BLOCKED + - UNBLOCKED + - ON_HOLD + - REJECTED + example: UNBLOCKED + +#----------------------------------------------------- +# The Tag resource +#----------------------------------------------------- + Tag: + title: Tag + required: + - name + - weight + properties: + name: + type: string + example: tag1 + weight: + type: integer + example: 5 + +#----------------------------------------------------- +# The Tag List resource +#----------------------------------------------------- + TagList: + title: Tag List + properties: + count: + type: integer + description: | + Number of Tags returned. + example: 1 + next: + type: string + description: | + Link to the next subset of resources qualified. + Empty if no more resources are to be returned. + example: "/tags?limit=1&offset=2" + previous: + type: string + description: | + Link to the previous subset of resources qualified. + Empty if current subset is the first subset returned. + example: "/tags?limit=1&offset=0" + list: + type: array + items: + $ref: '#/definitions/Tag' + +#----------------------------------------------------- +# The Error resource +#----------------------------------------------------- + Error: + title: Error object returned with 4XX HTTP status + required: + - code + - message + properties: + code: + type: integer + format: int64 + message: + type: string + description: Error message. + description: + type: string + description: | + A detail description about the error message. + moreInfo: + type: string + description: | + Preferably an url with more details about the error. + error: + type: array + description: | + If there are more than one error list them out. + For example, list out validation errors by each field. + items: + $ref: '#/definitions/ErrorListItem' + +#----------------------------------------------------- +# The Error List Item resource +#----------------------------------------------------- + ErrorListItem: + title: Description of individual errors that may have occurred during a request. + required: + - code + - message + properties: + code: + type: string + message: + type: string + description: | + Description about individual errors occurred + +#----------------------------------------------------- +# The Token resource +#----------------------------------------------------- + Token : + title: Token details for invoking APIs + properties: + accessToken: + type: string + description: Access token + example: 01234567890123456789012345678901 + tokenScopes: + type: array + items: + type: string + description: Valid scopes for the access token + example: ["default"] + validityTime: + type: integer + format: int64 + description: Maximum validity time for the access token + example: 3600 + +#----------------------------------------------------- +# The Application Key resource +#----------------------------------------------------- + ApplicationKey : + title: Application key details + properties: + consumerKey: + type: string + description: Consumer key of the application + example: vYDoc9s7IgAFdkSyNDaswBX7ejoa + consumerSecret: + type: string + description: Consumer secret of the application + example: TIDlOFkpzB7WjufO3OJUhy1fsvAa + supportedGrantTypes: + type: array + items: + type: string + description: Supported grant types for the application + example: ["client_credentials","password"] + keyState: + type: string + description: State of the key generation of the application + example: APPROVED + keyType: + description: Key type + type: string + enum: + - PRODUCTION + - SANDBOX + example: PRODUCTION + token: + $ref: '#/definitions/Token' + +#----------------------------------------------------- +# The Application Key Generation Request schema +#----------------------------------------------------- + ApplicationKeyGenerateRequest : + title: Application key generation request object + required: + - keyType + - validityTime + - accessAllowDomains + properties: + keyType: + type: string + enum: + - PRODUCTION + - SANDBOX + example: PRODUCTION + validityTime: + type: string + example: 3600 + callbackUrl: + type: string + description: Callback URL + example: "" + accessAllowDomains: + type: array + items: + type: string + description: Allowed domains for the access token + example: ["ALL"] + scopes: + type: array + items: + type: string + description: Allowed scopes for the access token + example: ["am_application_scope","default"] + +#----------------------------------------------------- +# END-OF-FILE +#----------------------------------------------------- diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherService.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherService.java index c41a684968..de3cc18668 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherService.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherService.java @@ -41,19 +41,4 @@ public interface APIPublisherService { */ void publishAPI(API api) throws APIManagementException, FaultGatewaysException; - /** - * This method removes an API that's already published within the underlying API-Management infrastructure. - * - * @param id An instance of the bean that carries API identification related metadata - * @throws APIManagementException Is thrown if some unexpected event occurs while removing the API - */ - void removeAPI(APIIdentifier id) throws APIManagementException; - - /** - * This method registers a collection of APIs within the underlying API-Management infrastructure. - * - * @param apis A list of the beans that passes metadata related to the APIs being published - * @throws APIManagementException Is thrown if some unexpected event occurs while publishing the APIs - */ - void publishAPIs(List apis) throws APIManagementException, FaultGatewaysException; } diff --git a/components/apimgt-extensions/pom.xml b/components/apimgt-extensions/pom.xml index 8720c345cb..218bf0883a 100644 --- a/components/apimgt-extensions/pom.xml +++ b/components/apimgt-extensions/pom.xml @@ -34,6 +34,9 @@ http://wso2.org + org.wso2.carbon.apimgt.publisher.client + org.wso2.carbon.apimgt.store.client + org.wso2.carbon.apimgt.integration.client org.wso2.carbon.apimgt.webapp.publisher org.wso2.carbon.apimgt.application.extension org.wso2.carbon.apimgt.application.extension.api diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml new file mode 100644 index 0000000000..7d22f7be65 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/pom.xml @@ -0,0 +1,145 @@ + + + + + + org.wso2.carbon.devicemgt + apimgt-extensions-feature + 2.0.8-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.apimgt.integration.client.feature + pom + WSO2 Carbon - APIM Integration Client Feature + http://wso2.org + This feature contains a http client implementation to communicate with WSO2-APIM server + + + + org.wso2.carbon + org.wso2.carbon.apimgt.integration.client + + + + + + + maven-resources-plugin + 2.6 + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.apimgt.client + ../../../features/etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + org.eclipse.equinox.p2.type.group:false + + + + + javax.ws.rs:jsr311-api:${jsr311.version} + + + io.swagger:swagger-annotations:${swagger.annotations.version} + + + io.github.openfeign:feign-slf4j:${io.github.openfeign.version} + + + io.github.openfeign:feign-jaxrs:${io.github.openfeign.version} + + + io.github.openfeign:feign-jackson:${io.github.openfeign.version} + + + io.github.openfeign:feign-core:${io.github.openfeign.version} + + + io.github.openfeign:feign-gson:${io.github.openfeign.version} + + + org.wso2.carbon:org.wso2.carbon.apimgt.integration.client:${project.version} + + + org.wso2.carbon:org.wso2.carbon.apimgt.publisher.client:${project.version} + + + org.wso2.carbon:org.wso2.carbon.apimgt.store.client:${project.version} + + + org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:${oltu.client.version} + + + com.fasterxml.jackson.datatype:jackson-datatype-joda:${jackson.datatype.joda.version} + + + + org.wso2.carbon.core.server:${carbon.kernel.version} + + + + + + + + + + + 1.5.4 + 4.4.10 + 9.3.1 + + + diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/build.properties b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/build.properties new file mode 100644 index 0000000000..9c86577d76 --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/build.properties @@ -0,0 +1 @@ +custom = true diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/conf/apim-integration.xml b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/conf/apim-integration.xml new file mode 100644 index 0000000000..c809feecdd --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/conf/apim-integration.xml @@ -0,0 +1,28 @@ + + + + http://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.10/register + https://${iot.gateway.host}:${iot.gateway.https.port}/token + https://localhost:9443/api/am/publisher/v0.10 + https://localhost:9443/api/am/store/v0.10 + admin + admin + \ No newline at end of file diff --git a/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/p2.inf b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/p2.inf new file mode 100644 index 0000000000..461f6ec80f --- /dev/null +++ b/features/apimgt-extensions/org.wso2.carbon.apimgt.integration.client.feature/src/main/resources/p2.inf @@ -0,0 +1,2 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.apimgt.apim.integration_${feature.version}/conf/apim-integration.xml,target:${installFolder}/../../conf/apim-integration.xml,overwrite:true);\ diff --git a/features/apimgt-extensions/pom.xml b/features/apimgt-extensions/pom.xml index 5575d0e811..20391e8144 100644 --- a/features/apimgt-extensions/pom.xml +++ b/features/apimgt-extensions/pom.xml @@ -35,6 +35,7 @@ http://wso2.org + org.wso2.carbon.apimgt.integration.client.feature org.wso2.carbon.apimgt.webapp.publisher.feature org.wso2.carbon.apimgt.application.extension.feature org.wso2.carbon.apimgt.handler.server.feature diff --git a/pom.xml b/pom.xml index e9b56eb1de..241eb082a0 100644 --- a/pom.xml +++ b/pom.xml @@ -37,11 +37,11 @@ components/device-mgt components/device-mgt-extensions + components/identity-extensions components/apimgt-extensions components/policy-mgt components/certificate-mgt components/webapp-authenticator-framework - components/identity-extensions components/email-sender features/device-mgt features/apimgt-extensions @@ -208,6 +208,21 @@ org.wso2.carbon.apimgt.webapp.publisher ${carbon.device.mgt.version} + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.publisher.client + ${carbon.device.mgt.version} + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.store.client + ${carbon.device.mgt.version} + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.integration.client + ${carbon.device.mgt.version} + org.wso2.carbon.devicemgt org.wso2.carbon.apimgt.annotations @@ -1364,6 +1379,7 @@ ${jackson.version} + org.wso2.carbon.commons org.wso2.carbon.ntask.core @@ -1628,6 +1644,17 @@ jackson-annotations ${jackson-annotations.version} + + org.wso2.orbit.com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + + org.wso2.orbit.joda-time + joda-time + ${joda-time.version} + org.wso2.orbit.org.owasp.encoder encoder @@ -1669,6 +1696,41 @@ org.wso2.store.sso.common ${carbon.store.sso.common.version} + + io.github.openfeign + feign-core + ${io.github.openfeign.version} + + + io.github.openfeign + feign-jaxrs + ${io.github.openfeign.version} + + + io.github.openfeign + feign-gson + ${io.github.openfeign.version} + + + io.github.openfeign + feign-jackson + ${io.github.openfeign.version} + + + io.github.openfeign + feign-slf4j + ${io.github.openfeign.version} + + + org.apache.oltu.oauth2 + org.apache.oltu.oauth2.client + ${oltu.client.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + ${jackson.datatype.joda.version} + @@ -2047,6 +2109,8 @@ 1.0.2 2.6.1.wso2v1 + 2.6.1.wso2v3 + 2.8.2.wso2v1 1.2.0.wso2v1 5.0.2.Final @@ -2067,6 +2131,12 @@ 1.4.4 + + + 9.3.1 + + 1.0.1 + 2.1.5